summaryrefslogtreecommitdiff
path: root/contrib/libpam/modules/pam_pwdb/support.-c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpam/modules/pam_pwdb/support.-c')
-rw-r--r--contrib/libpam/modules/pam_pwdb/support.-c132
1 files changed, 82 insertions, 50 deletions
diff --git a/contrib/libpam/modules/pam_pwdb/support.-c b/contrib/libpam/modules/pam_pwdb/support.-c
index 71e212d641950..2b80f960cde7a 100644
--- a/contrib/libpam/modules/pam_pwdb/support.-c
+++ b/contrib/libpam/modules/pam_pwdb/support.-c
@@ -1,18 +1,5 @@
/*
- * $Id: support.-c,v 1.7 1997/04/05 06:32:06 morgan Exp morgan $
- *
- * $Log: support.-c,v $
- * Revision 1.7 1997/04/05 06:32:06 morgan
- * new option and also deleted _readto
- *
- * Revision 1.6 1997/02/15 17:27:20 morgan
- * added helper binary to password checking
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:06:07 morgan
- * pwdb conversion
+ * $Id: support.-c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
*
* Copyright information at end of file.
*/
@@ -91,8 +78,9 @@ typedef struct {
#define UNIX_NODELAY 18 /* admin does not want a fail-delay */
#define UNIX_UNIX 19 /* wish to use /etc/passwd for pwd */
#define UNIX_BIGCRYPT 20 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 21 /* need to auth for setcred to work */
/* -------------- */
-#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 22 /* number of ctrl arguments defined */
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
@@ -118,8 +106,9 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
/* UNIX__SET_DB */ { NULL, _ALL_ON_, 0100000 },
/* UNIX_DEBUG */ { "debug", _ALL_ON_, 0200000 },
/* UNIX_NODELAY */ { "nodelay", _ALL_ON_, 0400000 },
-/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
+/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
/* UNIX_BIGCRYPT */ { "bigcrypt", _ALL_ON_^(020000), 02000000 },
+/* UNIX_LIKE_AUTH */ { "likeauth", _ALL_ON_, 04000000 },
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@@ -161,7 +150,7 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
, pam_strerror(pamh, retval));
}
- } else {
+ } else if (retval != PAM_CONV_AGAIN) {
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
}
@@ -322,13 +311,13 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
if ( !quiet && !err ) { /* under advisement from Sun,may go away */
/* log the number of authentication failures */
- if ( failure->count != 0 ) {
+ if ( failure->count > 1 ) {
(void) pam_get_item(pamh, PAM_SERVICE
, (const void **)&service);
_log_err(LOG_NOTICE
- , "%d authentication failure%s; %s(uid=%d) -> "
+ , "%d more authentication failure%s; %s(uid=%d) -> "
"%s for %s service"
- , failure->count, failure->count==1 ? "":"s"
+ , failure->count-1, failure->count==2 ? "":"s"
, failure->name
, failure->id
, failure->user
@@ -356,7 +345,8 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
#include <sys/types.h>
#include <sys/wait.h>
-static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
+static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ const char *user)
{
int retval, child, fds[2];
@@ -370,7 +360,7 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* fork */
child = fork();
if (child == 0) {
- static char *args[] = { NULL, NULL };
+ static char *args[] = { NULL, NULL, NULL };
static char *envp[] = { NULL };
/* XXX - should really tidy up PAM here too */
@@ -382,6 +372,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* exec binary helper */
args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
+
execve(CHKPWD_HELPER, args, envp);
/* should not get here: exit with error */
@@ -389,13 +381,14 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
exit(PWDB_SUCCESS+1);
} else if (child > 0) {
/* wait for child */
- close(fds[0]);
if (passwd != NULL) { /* send the password to the child */
write(fds[1], passwd, strlen(passwd)+1);
passwd = NULL;
} else {
write(fds[1], "", 1); /* blank password */
}
+ close(fds[0]); /* we close this after the write because we want
+ to avoid a possible SIGPIPE. */
close(fds[1]);
(void) waitpid(child, &retval, 0); /* wait for helper to complete */
retval = (retval == PWDB_SUCCESS) ? PAM_SUCCESS:PAM_AUTH_ERR;
@@ -408,8 +401,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
return retval;
}
-static int _unix_verify_password(pam_handle_t *pamh, const char *name
- , const char *p, unsigned int ctrl)
+static int _unix_verify_password(pam_handle_t *pamh, const char *name,
+ const char *p, unsigned int ctrl)
{
const struct pwdb *pw=NULL;
const struct pwdb_entry *pwe=NULL;
@@ -418,6 +411,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
char *pp;
char *data_name;
int retval;
+ int verify_result;
D(("called"));
@@ -474,7 +468,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (geteuid()) {
/* we are not root perhaps this is the reason? Run helper */
D(("running helper binary"));
- retval = pwdb_run_helper_binary(pamh, p);
+ retval = pwdb_run_helper_binary(pamh, p, name);
} else {
retval = PAM_AUTHINFO_UNAVAIL;
_log_err(LOG_ALERT, "get passwd; %s", pwdb_strerror(retval));
@@ -491,33 +485,56 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
* clear text...
*/
- if ( ( !salt ) && ( !p ) ) {
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
+ if ( data_name == NULL ) {
+ _log_err(LOG_CRIT, "no memory for data-name");
+ }
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
- /* the stored password is NULL */
+ if ( !( (salt && *salt) || (p && *p) ) ) {
- (void) pwdb_entry_delete(&pwe);
- (void) pwdb_delete(&pw);
+ D(("two null passwords to compare"));
+ /* the stored password is NULL */
+ pp = NULL;
if ( off(UNIX__NONULL, ctrl ) ) { /* this means we've succeeded */
- return PAM_SUCCESS;
+ verify_result = PAM_SUCCESS;
} else {
- return PAM_AUTH_ERR;
+ verify_result = PAM_AUTH_ERR;
}
- }
- pp = _pam_md(p, salt);
- p = NULL; /* no longer needed here */
+ } else if ( !( salt && p ) ) {
- data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
- if ( data_name == NULL ) {
- _log_err(LOG_CRIT, "no memory for data-name");
- }
- strcpy(data_name, FAIL_PREFIX);
- strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
+ D(("one of the two to compare are NULL"));
+
+ pp = NULL;
+ verify_result = PAM_AUTH_ERR;
+
+ } else {
- /* the moment of truth -- do we agree with the password? */
+ pp = _pam_md(p, salt);
- if ( strcmp( pp, salt ) == 0 ) {
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ _pam_delete(pp);
+ pp = _pam_md_compat(p, salt);
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ verify_result = PAM_AUTH_ERR;
+ }
+ }
+
+ p = NULL; /* no longer needed here */
+
+ }
+
+ if ( verify_result == PAM_SUCCESS ) {
retval = PAM_SUCCESS;
if (data_name) { /* reset failures */
@@ -538,7 +555,11 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (new != NULL) {
- /* any previous failures for this user ? */
+ new->user = x_strdup(name);
+ new->id = getuid();
+ new->name = x_strdup(getlogin() ? getlogin():"" );
+
+ /* any previous failures for this user ? */
pam_get_data(pamh, data_name, (const void **)&old );
if (old != NULL) {
@@ -547,11 +568,19 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
retval = PAM_MAXTRIES;
}
} else {
+ const char *service=NULL;
+ (void) pam_get_item(pamh, PAM_SERVICE
+ , (const void **)&service);
+ _log_err(LOG_NOTICE
+ , "authentication failure; %s(uid=%d) -> "
+ "%s for %s service"
+ , new->name
+ , new->id
+ , new->user
+ , service == NULL ? "**unknown**":service
+ );
new->count = 1;
}
- new->user = x_strdup(name);
- new->id = getuid();
- new->name = x_strdup(getlogin() ? getlogin():"" );
pam_set_data(pamh, data_name, new, _cleanup_failures);
@@ -568,6 +597,8 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
_pam_delete(data_name);
_pam_delete(pp);
+ D(("done [%d].", retval));
+
return retval;
}
@@ -596,8 +627,9 @@ static int _unix_get_user(pam_handle_t *pamh, unsigned int ctrl
* alphanumeric character.
*/
- if (!isalnum(**user)) {
- if (on(UNIX_DEBUG,ctrl) || **user) {
+ if (*user == NULL || !isalnum(**user)) {
+ D(("bad username"));
+ if (on(UNIX_DEBUG,ctrl)) {
_log_err(LOG_ERR, "bad username [%s]", *user);
}
return PAM_USER_UNKNOWN;
@@ -872,7 +904,7 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh
}
/* ****************************************************************** *
- * Copyright (c) Andrew G. Morgan, <morgan@parc.power.net> 1996.
+ * Copyright (c) Andrew G. Morgan 1996-8.
* Copyright (c) Alex O. Yuriev, 1996.
* Copyright (c) Cristian Gafton 1996.
*