diff options
author | Tomas Mraz <tmraz@fedoraproject.org> | 2016-04-06 14:27:07 +0200 |
---|---|---|
committer | Tomas Mraz <tmraz@fedoraproject.org> | 2016-04-06 14:27:07 +0200 |
commit | 7e09188c5dc4d0372ac7016f682cf63c686afe4a (patch) | |
tree | 8a926f06f3e527f5a1daffe4289f4c00178172fc | |
parent | 3c4328635ade0cd7bc1fb9d5f145f4dff76f9c1b (diff) | |
download | pam-7e09188c5dc4d0372ac7016f682cf63c686afe4a.tar.gz pam-7e09188c5dc4d0372ac7016f682cf63c686afe4a.tar.bz2 pam-7e09188c5dc4d0372ac7016f682cf63c686afe4a.zip |
pam_unix: Use pam_get_authtok() instead of direct pam_prompt() calls.
We have to drop support for not_set_pass option which is not much useful
anyway. Instead we get proper support for authtok_type option.
* modules/pam_unix/pam_unix.8.xml: Removed not_set_pass option, added authtok_ty
pe
option.
* modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Replace _unix_read_pas
sword()
call with equivalent pam_get_authtok() call.
* modules/pam_unix/pam_unix_passwd.c (pam_sm_chauthtok): Likewise and also drop
support for not_set_pass.
* modules/pam_unix/support.c (_unix_read_password): Remove.
* modules/pam_unix/support.h: Remove UNIX_NOT_SET_PASS add UNIX_AUTHTOK_TYPE.
-rw-r--r-- | modules/pam_unix/pam_unix.8.xml | 8 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_auth.c | 5 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 58 | ||||
-rw-r--r-- | modules/pam_unix/support.c | 154 | ||||
-rw-r--r-- | modules/pam_unix/support.h | 6 |
5 files changed, 23 insertions, 208 deletions
diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 6d8e4ba0..60d90979 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -217,13 +217,13 @@ </varlistentry> <varlistentry> <term> - <option>not_set_pass</option> + <option>authtok_type=<replaceable>type</replaceable></option> </term> <listitem> <para> - This argument is used to inform the module that it is not to - pay attention to/make available the old or new passwords from/to - other (stacked) password modules. + This argument can be used to modify the password prompt + when changing passwords to include the type of the password. + Empty by default. </para> </listitem> </varlistentry> diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c index 9f66c5d6..673861e4 100644 --- a/modules/pam_unix/pam_unix_auth.c +++ b/modules/pam_unix/pam_unix_auth.c @@ -103,7 +103,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) unsigned int ctrl; int retval, *ret_data = NULL; const char *name; - const void *p; + const char *p; D(("called.")); @@ -151,8 +151,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) } /* get this user's authentication token */ - retval = _unix_read_password(pamh, ctrl, NULL, _("Password: "), NULL - ,_UNIX_AUTHTOK, &p); + retval = pam_get_authtok(pamh, PAM_AUTHTOK, &p , NULL); if (retval != PAM_SUCCESS) { if (retval != PAM_CONV_AGAIN) { pam_syslog(pamh, LOG_CRIT, diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index fa293278..c2e43423 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -612,7 +612,8 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) /* <DO NOT free() THESE> */ const char *user; - const void *pass_old, *pass_new; + const void *item; + const char *pass_old, *pass_new; /* </DO NOT free() THESE> */ D(("called.")); @@ -680,8 +681,6 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) * obtain and verify the current password (OLDAUTHTOK) for * the user. */ - char *Announce; - D(("prelim check")); if (_unix_blankpasswd(pamh, ctrl, user)) { @@ -689,22 +688,12 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) } else if (off(UNIX__IAMROOT, ctrl) || (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, user, 0, 1))) { /* instruct user what is happening */ - if (asprintf(&Announce, _("Changing password for %s."), - user) < 0) { - pam_syslog(pamh, LOG_CRIT, - "password - out of memory"); - return PAM_BUF_ERR; + if (off(UNIX__QUIET, ctrl)) { + retval = pam_info(pamh, _("Changing password for %s."), user); + if (retval != PAM_SUCCESS) + return retval; } - - lctrl = ctrl; - set(UNIX__OLD_PASSWD, lctrl); - retval = _unix_read_password(pamh, lctrl - ,Announce - ,_("(current) UNIX password: ") - ,NULL - ,_UNIX_OLD_AUTHTOK - ,&pass_old); - free(Announce); + retval = pam_get_authtok(pamh, PAM_OLDAUTHTOK, &pass_old, NULL); if (retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_NOTICE, @@ -725,12 +714,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) pass_old = NULL; return retval; } - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old); pass_old = NULL; - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "failed to set PAM_OLDAUTHTOK"); - } retval = _unix_verify_shadow(pamh,user, ctrl); if (retval == PAM_AUTHTOK_ERR) { if (off(UNIX__IAMROOT, ctrl)) @@ -760,23 +744,14 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) * previous call to this function]. */ - if (off(UNIX_NOT_SET_PASS, ctrl)) { - retval = pam_get_item(pamh, PAM_OLDAUTHTOK - ,&pass_old); - } else { - retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK - ,&pass_old); - if (retval == PAM_NO_MODULE_DATA) { - retval = PAM_SUCCESS; - pass_old = NULL; - } - } - D(("pass_old [%s]", pass_old)); + retval = pam_get_item(pamh, PAM_OLDAUTHTOK, &item); if (retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_NOTICE, "user not authenticated"); return retval; } + pass_old = item; + D(("pass_old [%s]", pass_old)); D(("get new password now")); @@ -785,7 +760,9 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) if (on(UNIX_USE_AUTHTOK, lctrl)) { set(UNIX_USE_FIRST_PASS, lctrl); } - retry = 0; + if (on(UNIX_USE_FIRST_PASS, lctrl)) { + retry = MAX_PASSWD_TRIES-1; + } retval = PAM_AUTHTOK_ERR; while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) { /* @@ -793,12 +770,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) * password -- needed for pluggable password strength checking */ - retval = _unix_read_password(pamh, lctrl - ,NULL - ,_("Enter new UNIX password: ") - ,_("Retype new UNIX password: ") - ,_UNIX_NEW_AUTHTOK - ,&pass_new); + retval = pam_get_authtok(pamh, PAM_AUTHTOK, &pass_new, NULL); if (retval != PAM_SUCCESS) { if (on(UNIX_DEBUG, ctrl)) { @@ -822,7 +794,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new, pass_min_len); - if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) { + if (retval != PAM_SUCCESS) { pam_set_item(pamh, PAM_AUTHTOK, NULL); } } diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 0fd1dba4..fc8595e9 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -853,160 +853,6 @@ cleanup: return retval; } -/* - * obtain a password from the user - */ - -int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const void **pass) -{ - int authtok_flag; - int retval = PAM_SUCCESS; - char *token; - - D(("called")); - - /* - * make sure nothing inappropriate gets returned - */ - - *pass = token = NULL; - - /* - * which authentication token are we getting? - */ - - authtok_flag = on(UNIX__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK; - - /* - * should we obtain the password from a PAM item ? - */ - - if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) { - retval = pam_get_item(pamh, authtok_flag, pass); - if (retval != PAM_SUCCESS) { - /* very strange. */ - pam_syslog(pamh, LOG_ALERT, - "pam_get_item returned error to unix-read-password" - ); - return retval; - } else if (*pass != NULL) { /* we have a password! */ - return PAM_SUCCESS; - } else if (on(UNIX_USE_AUTHTOK, ctrl) - && off(UNIX__OLD_PASSWD, ctrl)) { - return PAM_AUTHTOK_ERR; - } else if (on(UNIX_USE_FIRST_PASS, ctrl)) { - return PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */ - } - } - /* - * getting here implies we will have to get the password from the - * user directly. - */ - - { - int replies=1; - char *resp[2] = { NULL, NULL }; - - if (comment != NULL && off(UNIX__QUIET, ctrl)) { - retval = pam_info(pamh, "%s", comment); - } - - if (retval == PAM_SUCCESS) { - retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, - &resp[0], "%s", prompt1); - - if (retval == PAM_SUCCESS && prompt2 != NULL) { - retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, - &resp[1], "%s", prompt2); - ++replies; - } - } - - if (resp[0] != NULL && resp[replies-1] != NULL) { - /* interpret the response */ - - if (retval == PAM_SUCCESS) { /* a good conversation */ - - token = resp[0]; - if (token != NULL) { - if (replies == 2) { - /* verify that password entered correctly */ - if (strcmp(token, resp[replies - 1])) { - /* mistyped */ - retval = PAM_AUTHTOK_RECOVERY_ERR; - _make_remark(pamh, ctrl, - PAM_ERROR_MSG, MISTYPED_PASS); - } - } - } else { - pam_syslog(pamh, LOG_NOTICE, - "could not recover authentication token"); - } - - } - - } else { - retval = (retval == PAM_SUCCESS) - ? PAM_AUTHTOK_RECOVERY_ERR : retval; - } - - resp[0] = NULL; - if (replies > 1) - _pam_delete(resp[1]); - } - - if (retval != PAM_SUCCESS) { - _pam_delete(token); - - if (on(UNIX_DEBUG, ctrl)) - pam_syslog(pamh, LOG_DEBUG, - "unable to obtain a password"); - return retval; - } - /* 'token' is the entered password */ - - if (off(UNIX_NOT_SET_PASS, ctrl)) { - - /* we store this password as an item */ - - retval = pam_set_item(pamh, authtok_flag, token); - _pam_delete(token); /* clean it up */ - if (retval != PAM_SUCCESS - || (retval = pam_get_item(pamh, authtok_flag, pass)) - != PAM_SUCCESS) { - - *pass = NULL; - pam_syslog(pamh, LOG_CRIT, "error manipulating password"); - return retval; - - } - } else { - /* - * then store it as data specific to this module. pam_end() - * will arrange to clean it up. - */ - - retval = pam_set_data(pamh, data_name, (void *) token, _cleanup); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "error manipulating password data [%s]", - pam_strerror(pamh, retval)); - _pam_delete(token); - return retval; - } - *pass = token; - token = NULL; /* break link to password */ - } - - return PAM_SUCCESS; -} - /* ****************************************************************** * * Copyright (c) Jan Rêkorajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index b767c265..b4c279c3 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -18,8 +18,6 @@ * typed were not the same. */ -#define MISTYPED_PASS "Sorry, passwords do not match" - /* type definition for the control options */ typedef struct { @@ -72,7 +70,7 @@ typedef struct { some information may be sensitive */ #define UNIX_USE_FIRST_PASS 4 #define UNIX_TRY_FIRST_PASS 5 -#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */ +#define UNIX_AUTHTOK_TYPE 6 /* TYPE for pam_get_authtok() */ #define UNIX__PRELIM 7 /* internal */ #define UNIX__UPDATE 8 /* internal */ @@ -116,7 +114,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* UNIX_AUDIT */ {"audit", _ALL_ON_, 010, 0}, /* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020, 0}, /* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040, 0}, -/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100, 0}, +/* UNIX_AUTHTOK_TYPE */ {"authtok_type=", _ALL_ON_, 0100, 0}, /* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200, 0}, /* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400, 0}, /* UNIX__NONULL */ {NULL, _ALL_ON_, 01000, 0}, |