-/*
+/*
Copyright (c) 1995-1998 by Cisco systems, Inc.
Permission to use, copy, modify, and distribute this software for
FITNESS FOR A PARTICULAR PURPOSE.
*/
+
#include "tac_plus.h"
-#include "expire.h"
-#include "time_limit.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <pwd.h>
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
#ifdef SHADOW_PASSWORDS
+#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif
+#endif
-#ifdef USE_PAM
-int
-tac_pam_auth(char *UserName,char *Password,struct authen_data *data,char *Service);
-#endif /* USE_PAM */
+#include "pwlib.h"
+#include "expire.h"
+#include "time_limit.h"
+#include "report.h"
+#include "utils.h"
+#include "cfgfile.h"
+#include "pw.h"
+#include "choose_authen.h" /* for "struct authen_data" */
+#include "packet.h"
+#include "main.h"
+#include "parse.h"
-/* For database verification */
+#ifdef USE_PAM
+#include "tac_pam.h"
+#endif
#ifdef DB
-int db_verify();
-#endif /* DB */
-
-/* For LDAP verification */
+#include "db.h" /* For database verification */
+#endif
#ifdef USE_LDAP
-#include "ldap.h"
-#endif /* LDAP */
+#include "ldap_author.h" /* For LDAP verification */
+#endif
+
+
+static int passwd_file_verify TAC_ARGS((const char *user, const char *supplied_passwd, struct authen_data *data, const char *filename));
+
/* Generic password verification routines for des, file and cleartext
passwords */
-static int passwd_file_verify();
-
/* Adjust data->status depending on whether a user has expired or not */
+void set_expiration_status TAC_ARGS((const char *exp_date, struct authen_data *data));
+
void
set_expiration_status(exp_date, data)
-char *exp_date;
+const char *exp_date;
struct authen_data *data;
{
int expired;
switch (expired) {
case PW_OK:
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Password has not expired %s",
+ report(LOG_DEBUG, "Password has not expired %s",
exp_date ? exp_date : "<no expiry date set>");
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
case PW_EXPIRING:
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Password will expire soon %s",
+ report(LOG_DEBUG, "Password will expire soon %s",
exp_date ? exp_date : "<no expiry date set>");
if (data->server_msg)
free(data->server_msg);
case PW_EXPIRED:
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Password has expired %s",
+ report(LOG_DEBUG, "Password has expired %s",
exp_date ? exp_date : "<no expiry date set>");
if (data->server_msg)
free(data->server_msg);
return;
default:
- report(LOG_ERR, "%s: Bogus return value %d from check_expiration",
+ report(LOG_ERR, "%s: Bogus return value %d from check_expiration",
session.peer, expired);
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
return;
/* Verify that this user/password is valid. Works only for cleartext,
file and des passwords.
-
+
Return 1 if password is valid */
+int verify TAC_ARGS((const char *name, const char *passwd, struct authen_data *data, int recurse));
+
int
verify(name, passwd, data, recurse)
-char *name, *passwd;
+const char *name;
+const char *passwd;
struct authen_data *data;
int recurse;
{
- char *exp_date;
- char *timestamp;
- char *cfg_passwd;
- char *p;
-
- timestamp = (char *)cfg_get_timestamp(name, recurse);
- if ( timestamp != NULL ) {
+ const char *exp_date, *cfg_passwd, *p, *timestamp;
+
+ timestamp = cfg_get_timestamp(name, recurse);
+ if ( timestamp != NULL ) {
if( time_limit_process(timestamp) == 0 ) {
- if ( debug & DEBUG_AUTHEN_FLAG )
- report(LOG_DEBUG,"Timestamp check failed");
+ if ( debug & DEBUG_AUTHEN_FLAG )
+ report(LOG_DEBUG,"Timestamp check failed");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return (0);
- }
+ }
}
if (data->type == TAC_PLUS_AUTHEN_TYPE_PAP) {
cfg_passwd = cfg_get_login_secret(name, recurse);
}
- /* If there is no login or pap password for this user, see if there is
+ /* If there is no login or pap password for this user, see if there is
a global password for her that we can use */
if (!cfg_passwd) {
has been issued, attempt to use this password file */
if (!cfg_passwd) {
- char *file = cfg_get_authen_default();
+ const char *file = cfg_get_authen_default();
switch (cfg_get_authen_default_method()) {
+
case (S_file):
+ if (file)
+ return (passwd_file_verify(name, passwd, data, file));
+ break;
- if (file) {
- return (passwd_file_verify(name, passwd, data, file));
- }
- break;
#ifdef DB
case (S_db):
- /* ugly check for database connect string */
- if( strstr(file, "://") ){
- if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG,"%s %s: DB access to %s for user %s",session.peer, session.port, file, name);
- if (!db_verify(name, passwd, file)) {
- data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
- return (0);
- } else {
- data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
- }
- exp_date = NULL;
- set_expiration_status(exp_date, data);
- return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
- }
+ /* ugly check for database connect string */
+ if( strstr(file, "://") ) {
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG,"%s %s: DB access to %s for user %s",session.peer, session.port, file, name);
+ if (!db_verify(name, passwd, file)) {
+ data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
+ return (0);
+ } else {
+ data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
+ }
+ exp_date = NULL;
+ set_expiration_status(exp_date, data);
+ return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
+ }
break;
#endif
#ifdef USE_PAM
case (S_pam):
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "PAM verify daemon %s == NAS %s", p,passwd);
- if (tac_pam_auth(name, passwd, data,file)) {
+ report(LOG_DEBUG, "PAM verify daemon [PAM] == NAS %s", passwd);
+ if (tac_pam_auth(name, passwd, data, file)) {
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "PAM default authentication fail");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
set_expiration_status(exp_date, data);
return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
break;
-#endif
+#endif
default:
/* otherwise, we fail */
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return (0);
-
+ }
}
-}
/* We have a configured password. Deal with it depending on its
type */
if (strcmp(passwd, p)) {
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Password is incorrect");
+ report(LOG_DEBUG, "Password is incorrect");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return(0);
} else {
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Password is correct");
+ report(LOG_DEBUG, "Password is correct");
}
exp_date = cfg_get_expires(name, recurse);
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "DB Password is incorrect");
-
+
return (0);
} else {
if (p) {
return (passwd_file_verify(name, passwd, data, p));
}
-
+
/* Oops. No idea what kind of password this is. This should never
happen as the parser should never create such passwords. */
report(LOG_ERR, "%s: Error cannot identify password type %s for %s",
- session.peer,
- cfg_passwd && cfg_passwd[0] ? cfg_passwd : "<NULL>",
+ session.peer,
+ cfg_passwd && cfg_passwd[0] ? cfg_passwd : "<NULL>",
name ? name : "<unknown>");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return (0);
}
+static int etc_passwd_file_verify TAC_ARGS((const char *user, const char *supplied_passwd, struct authen_data *data));
+
/* verify that this user/password is valid per /etc/passwd.
- Return 0 if invalid. */
+ * Return 0 if invalid.
+ */
static int
etc_passwd_file_verify(user, supplied_passwd, data)
-char *user, *supplied_passwd;
+const char *user;
+const char *supplied_passwd;
struct authen_data *data;
{
struct passwd *pw;
}
cfg_passwd = spwd->sp_pwdp;
- /*
+ /*
* Sigh. The Solaris shadow password file contains its own
* expiry date as the number of days after the epoch
* (January 1, 1970) when the password expires.
* Convert this to ascii so that the traditional tacacs
- * password expiration routines work correctly.
+ * password expiration routines work correctly.
*/
if (spwd->sp_expire > 0) {
/* verify that this user/password is valid per a passwd(5) style
database. Return 0 if invalid. */
+static int passwd_file_verify TAC_ARGS((const char *user, const char *supplied_passwd, struct authen_data *data, const char *filename));
+
static int
passwd_file_verify(user, supplied_passwd, data, filename)
-char *user, *supplied_passwd;
+const char *user;
+const char *supplied_passwd;
struct authen_data *data;
-char *filename;
+const char *filename;
{
struct passwd *pw;
char *exp_date;
if (filename && (STREQ(filename, "/etc/passwd")|| STREQ(filename,"/etc/shadow") )) {
return(etc_passwd_file_verify(user, supplied_passwd, data));
}
-
+
/* an alternate filename */
* return 1 if verified, 0 otherwise.
*/
+int des_verify TAC_ARGS((const char *users_passwd, const char *encrypted_passwd));
+
int
des_verify(users_passwd, encrypted_passwd)
-char *users_passwd, *encrypted_passwd;
+const char *users_passwd;
+const char *encrypted_passwd;
{
char *ep;