diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 663f1f3..9bfbdf0 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -38,6 +38,8 @@ #define PROMPT _("Password: ") /* For Translators: "%s%s" could be replaced with " " or "". */ +#define PROMPTCURRENT _("Current %s%spassword: ") +/* For Translators: "%s%s" could be replaced with " " or "". */ #define PROMPT1 _("New %s%spassword: ") /* For Translators: "%s%s" could be replaced with " " or "". */ #define PROMPT2 _("Retype new %s%spassword: ") @@ -89,12 +91,14 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, /* PAM_AUTHTOK in password stack returns new password, which needs to be verified. */ - if (item == PAM_AUTHTOK && pamh->choice == PAM_CHAUTHTOK) + if (pamh->choice == PAM_CHAUTHTOK) { - chpass = 1; - if (!(flags & PAM_GETAUTHTOK_NOVERIFY)) - ++chpass; - + if (item == PAM_AUTHTOK) + { + chpass = 1; + if (!(flags & PAM_GETAUTHTOK_NOVERIFY)) + ++chpass; + } authtok_type = get_option (pamh, "authtok_type"); if (authtok_type == NULL) { @@ -144,6 +148,10 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, PROMPT2, authtok_type, strlen (authtok_type) > 0?" ":""); } + else if (item == PAM_OLDAUTHTOK) + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], + PROMPTCURRENT, authtok_type, + strlen (authtok_type) > 0?" ":""); else retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], "%s", PROMPT); diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 6d8e4ba..60d9097 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -217,13 +217,13 @@ - + - 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. diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c index 9f66c5d..673861e 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 fa29327..49dd831 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) /* */ const char *user; - const void *pass_old, *pass_new; + const void *item; + const char *pass_old, *pass_new; /* */ 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 0fd1dba..fc8595e 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 b767c26..b4c279c 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}, From a1765a0bc62fff8c22091c661aafa10167ec7da8 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 4 Apr 2016 14:23:22 +0200 Subject: [PATCH] pam_unix: Make password expiration messages more user-friendly. * modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): Make password expiration messages more user-friendly. --- modules/pam_unix/pam_unix_acct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 17a0890..782d84a 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -258,13 +258,13 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) "expired password for user %s (root enforced)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (root enforced)")); + _("You are required to change your password immediately (administrator enforced)")); } else { pam_syslog(pamh, LOG_DEBUG, "expired password for user %s (password aged)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (password aged)")); + _("You are required to change your password immediately (password expired)")); } break; case PAM_AUTHTOK_EXPIRED: -- 2.5.5