diff options
author | Thorsten Kukuk <kukuk@thkukuk.de> | 2008-12-03 14:16:33 +0000 |
---|---|---|
committer | Thorsten Kukuk <kukuk@thkukuk.de> | 2008-12-03 14:16:33 +0000 |
commit | f326d04ccd16631d57134487e56bb73074f0dd0e (patch) | |
tree | be55fce45e805e98057c1920a5f0ebaffa2b6650 /modules | |
parent | de63f0160c57494553e400aca215ffe316e946b7 (diff) | |
download | pam-f326d04ccd16631d57134487e56bb73074f0dd0e.tar.gz pam-f326d04ccd16631d57134487e56bb73074f0dd0e.tar.bz2 pam-f326d04ccd16631d57134487e56bb73074f0dd0e.zip |
Relevant BUGIDs:
Purpose of commit: new feature
Commit summary:
---------------
2008-12-03 Thorsten Kukuk <kukuk@suse.de>
* doc/man/Makefile.am: Add pam_get_authtok.3.xml.
* doc/man/pam_get_authtok.3.xml: New.
* libpam/Makefile.am: Add pam_get_authtok.c.
* libpam/libpam.map: Export pam_get_authtok.
* libpam/pam_get_authtok.c: New.
* libpam/pam_private.h: Add mod_argc and mod_argv to pam_handle.
* libpam_include/security/pam_ext.h: Add pam_get_authtok
prototype.
* modules/pam_cracklib/pam_cracklib.c: Use pam_get_authtok.
* modules/pam_pwhistory/pam_pwhistory.c: Likewise.
* po/POTFILES.in: Add libpam/pam_get_authtok.c.
* xtests/tst-pam_cracklib1.c: Adjust error codes.
* modules/pam_timestamp/Makefile.am: Remove hmactest.c from
EXTRA_DIST.
* po/*.po: Regenerated.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_cracklib/pam_cracklib.c | 236 | ||||
-rw-r--r-- | modules/pam_pwhistory/pam_pwhistory.c | 151 | ||||
-rw-r--r-- | modules/pam_timestamp/Makefile.am | 2 |
3 files changed, 102 insertions, 287 deletions
diff --git a/modules/pam_cracklib/pam_cracklib.c b/modules/pam_cracklib/pam_cracklib.c index 4b2052fc..398727e1 100644 --- a/modules/pam_cracklib/pam_cracklib.c +++ b/modules/pam_cracklib/pam_cracklib.c @@ -200,14 +200,6 @@ _pam_parse (pam_handle_t *pamh, struct cracklib_options *opt, /* Helper functions */ -/* use this to free strings. ESPECIALLY password strings */ -static char *_pam_delete(register char *xx) -{ - _pam_overwrite(xx); - free(xx); - return NULL; -} - /* * can't be a palindrome - like `R A D A R' or `M A D A M' */ @@ -624,183 +616,83 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, return PAM_SUCCESS; } else if (flags & PAM_UPDATE_AUTHTOK) { int retval; - char *token1, *token2, *resp; const void *oldtoken; + int tries; D(("do update")); - retval = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldtoken); - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_ERR,"Can not get old passwd"); - oldtoken=NULL; - retval = PAM_SUCCESS; - } - - do { - /* - * make sure nothing inappropriate gets returned - */ - token1 = token2 = NULL; - - if (!options.retry_times) { - D(("returning %s because maxtries reached", - pam_strerror(pamh, retval))); - return retval; - } - /* Planned modus operandi: - * Get a passwd. - * Verify it against cracklib. - * If okay get it a second time. - * Check to be the same with the first one. - * set PAM_AUTHTOK and return - */ - - if (options.use_authtok == 1 || options.try_first_pass == 1) { - const void *item = NULL; - - retval = pam_get_item(pamh, PAM_AUTHTOK, &item); - if (retval != PAM_SUCCESS) { - /* very strange. */ - pam_syslog(pamh, LOG_ALERT, - "pam_get_item returned error to pam_cracklib"); - } else if (item != NULL) { /* we have a password! */ - token1 = x_strdup(item); - item = NULL; - options.use_authtok = 1; /* don't ask for the password again */ - } else { - retval = PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */ - } - } - - if (options.use_authtok != 1) { - /* Prepare to ask the user for the first time */ - resp = NULL; - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - PROMPT1, options.prompt_type, - options.prompt_type[0]?" ":""); - - if (retval == PAM_SUCCESS) { /* a good conversation */ - token1 = resp; - if (token1 == NULL) { - pam_syslog(pamh, LOG_NOTICE, - "could not recover authentication token 1"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - } - } else { - retval = (retval == PAM_SUCCESS) ? - PAM_AUTHTOK_RECOVERY_ERR:retval ; - } - } + retval = pam_get_item (pamh, PAM_OLDAUTHTOK, &oldtoken); if (retval != PAM_SUCCESS) { - token1 = _pam_delete(token1); if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"unable to obtain a password"); - continue; + pam_syslog(pamh,LOG_ERR,"Can not get old passwd"); + oldtoken = NULL; } - D(("testing password, retval = %s", pam_strerror(pamh, retval))); - /* now test this passwd against cracklib */ - { - const char *crack_msg; - - D(("against cracklib")); - if ((crack_msg = FascistCheck(token1,options.cracklib_dictpath))) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"bad password: %s",crack_msg); - pam_error(pamh, _("BAD PASSWORD: %s"), crack_msg); - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } else { - /* check it for strength too... */ - D(("for strength")); - retval = _pam_unix_approve_pass (pamh, ctrl, &options, - oldtoken, token1); - if (retval != PAM_SUCCESS) { - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } - } + tries = 0; + while (tries < options.retry_times) { + const char *crack_msg; + const char *newtoken = NULL; + + + tries++; + + /* Planned modus operandi: + * Get a passwd. + * Verify it against cracklib. + * If okay get it a second time. + * Check to be the same with the first one. + * set PAM_AUTHTOK and return + */ + + retval = pam_get_authtok (pamh, PAM_AUTHTOK, &newtoken, NULL); + if (retval != PAM_SUCCESS) { + pam_syslog(pamh, LOG_ERR, "pam_get_authtok returned error: %s", + pam_strerror (pamh, retval)); + continue; + } else if (newtoken == NULL) { /* user aborted password change, quit */ + return PAM_AUTHTOK_ERR; + } + + D(("testing password")); + /* now test this passwd against cracklib */ + + D(("against cracklib")); + if ((crack_msg = FascistCheck (newtoken, options.cracklib_dictpath))) { + if (ctrl & PAM_DEBUG_ARG) + pam_syslog(pamh,LOG_DEBUG,"bad password: %s",crack_msg); + pam_error (pamh, _("BAD PASSWORD: %s"), crack_msg); + if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) + { + retval = PAM_AUTHTOK_ERR; + continue; + } + } + + /* check it for strength too... */ + D(("for strength")); + retval = _pam_unix_approve_pass (pamh, ctrl, &options, + oldtoken, newtoken); + if (retval != PAM_SUCCESS) { + if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) + { + retval = PAM_AUTHTOK_ERR; + continue; + } + } + return PAM_SUCCESS; } - D(("after testing: retval = %s", pam_strerror(pamh, retval))); - /* if cracklib/strength check said it is a bad passwd... */ - if ((retval != PAM_SUCCESS) && (retval != PAM_IGNORE)) { - int temp_unused; + D(("returning because maxtries reached")); - temp_unused = pam_set_item(pamh, PAM_AUTHTOK, NULL); - token1 = _pam_delete(token1); - continue; - } - - /* Now we have a good passwd. Ask for it once again */ - - if (options.use_authtok == 0) { - resp = NULL; - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - PROMPT2, options.prompt_type, - options.prompt_type[0]?" ":""); - if (retval == PAM_SUCCESS) { /* a good conversation */ - token2 = resp; - if (token2 == NULL) { - pam_syslog(pamh,LOG_NOTICE, - "could not recover authentication token 2"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - } - } - - /* No else, the a retval == PAM_SUCCESS path can change retval - to a failure code. */ - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"unable to obtain retyped password"); - token1 = _pam_delete(token1); - continue; - } - - /* Hopefully now token1 and token2 the same password ... */ - if (strcmp(token1,token2) != 0) { - /* tell the user */ - pam_error(pamh, "%s", MISTYPED_PASS); - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - pam_set_item(pamh, PAM_AUTHTOK, NULL); - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_NOTICE,"Password mistyped"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - continue; - } - - /* Yes, the password was typed correct twice - * we store this password as an item - */ - - { - const void *item = NULL; - - retval = pam_set_item(pamh, PAM_AUTHTOK, token1); - - /* clean up */ - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - - if ( (retval != PAM_SUCCESS) || - ((retval = pam_get_item(pamh, PAM_AUTHTOK, &item) - ) != PAM_SUCCESS) ) { - pam_syslog(pamh, LOG_CRIT, "error manipulating password"); - continue; - } - item = NULL; /* break link to password */ - return PAM_SUCCESS; - } - } + pam_set_item (pamh, PAM_AUTHTOK, NULL); - } while (options.retry_times--); + /* if we have only one try, we can use the real reason, + else say that there were too many tries. */ + if (options.retry_times > 1) + return PAM_MAXTRIES; + else + return retval; } else { if (ctrl & PAM_DEBUG_ARG) diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c index 424be38e..c555ac39 100644 --- a/modules/pam_pwhistory/pam_pwhistory.c +++ b/modules/pam_pwhistory/pam_pwhistory.c @@ -58,17 +58,10 @@ #include "opasswd.h" -/* For Translators: "%s%s" could be replaced with "<service> " or "". */ -#define NEW_PASSWORD_PROMPT _("New %s%spassword: ") -/* For Translators: "%s%s" could be replaced with "<service> " or "". */ -#define AGAIN_PASSWORD_PROMPT _("Retype new %s%spassword: ") -#define MISTYPED_PASSWORD _("Sorry, passwords do not match.") - #define DEFAULT_BUFLEN 2048 struct options_t { int debug; - int use_authtok; int enforce_for_root; int remember; int tries; @@ -80,12 +73,12 @@ typedef struct options_t options_t; static void parse_option (pam_handle_t *pamh, const char *argv, options_t *options) { - if (strcasecmp (argv, "use_first_pass") == 0) + if (strcasecmp (argv, "try_first_pass") == 0) /* ignore */; else if (strcasecmp (argv, "use_first_pass") == 0) /* ignore */; else if (strcasecmp (argv, "use_authtok") == 0) - options->use_authtok = 1; + /* ignore, handled by pam_get_authtok */; else if (strcasecmp (argv, "debug") == 0) options->debug = 1; else if (strncasecmp (argv, "remember=", 9) == 0) @@ -115,10 +108,9 @@ PAM_EXTERN int pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; - char *newpass; + const char *newpass; const char *user; - void *newpass_void; - int retval, tries; + int retval, tries; options_t options; memset (&options, 0, sizeof (options)); @@ -191,126 +183,57 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) return retval; } - retval = pam_get_item (pamh, PAM_AUTHTOK, (const void **) &newpass_void); - newpass = (char *) newpass_void; - if (retval != PAM_SUCCESS) - return retval; - if (options.debug) - { - if (newpass) - pam_syslog (pamh, LOG_DEBUG, "got new auth token"); - else - pam_syslog (pamh, LOG_DEBUG, "new auth token not set"); - } - - /* If we haven't been given a password yet, prompt for one... */ - if (newpass == NULL) + newpass = NULL; + tries = 0; + while ((newpass == NULL) && (tries < options.tries)) { - if (options.use_authtok) - /* We are not allowed to ask for a new password */ - return PAM_AUTHTOK_ERR; + retval = pam_get_authtok (pamh, PAM_AUTHTOK, &newpass, NULL); + if (retval != PAM_SUCCESS && retval != PAM_TRY_AGAIN) + return retval; + tries++; - tries = 0; + if (newpass == NULL || retval == PAM_TRY_AGAIN) + continue; - while ((newpass == NULL) && (tries++ < options.tries)) + if (options.debug) { - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &newpass, - NEW_PASSWORD_PROMPT, options.prompt_type, - strlen (options.prompt_type) > 0?" ":""); - if (retval != PAM_SUCCESS) - { - _pam_drop (newpass); - if (retval == PAM_CONV_AGAIN) - retval = PAM_INCOMPLETE; - return retval; - } - - if (newpass == NULL) - { - /* We want to abort the password change */ - pam_error (pamh, _("Password change aborted.")); - return PAM_AUTHTOK_ERR; - } - - if (options.debug) - pam_syslog (pamh, LOG_DEBUG, "check against old password file"); - - if (check_old_password (pamh, user, newpass, - options.debug) != PAM_SUCCESS) - { - pam_error (pamh, - _("Password has been already used. Choose another.")); - _pam_overwrite (newpass); - _pam_drop (newpass); - if (tries >= options.tries) - { - if (options.debug) - pam_syslog (pamh, LOG_DEBUG, - "Aborted, too many tries"); - return PAM_MAXTRIES; - } - } + if (newpass) + pam_syslog (pamh, LOG_DEBUG, "got new auth token"); else - { - int failed; - char *new2; - - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &new2, - AGAIN_PASSWORD_PROMPT, - options.prompt_type, - strlen (options.prompt_type) > 0?" ":""); - if (retval != PAM_SUCCESS) - return retval; - - if (new2 == NULL) - { /* Aborting password change... */ - pam_error (pamh, _("Password change aborted.")); - return PAM_AUTHTOK_ERR; - } - - failed = (strcmp (newpass, new2) != 0); - - _pam_overwrite (new2); - _pam_drop (new2); - - if (failed) - { - pam_error (pamh, MISTYPED_PASSWORD); - _pam_overwrite (newpass); - _pam_drop (newpass); - if (tries >= options.tries) - { - if (options.debug) - pam_syslog (pamh, LOG_DEBUG, - "Aborted, too many tries"); - return PAM_MAXTRIES; - } - } - } + pam_syslog (pamh, LOG_DEBUG, "got no auth token"); + } + + if (retval != PAM_SUCCESS || newpass == NULL) + { + if (retval == PAM_CONV_AGAIN) + retval = PAM_INCOMPLETE; + return retval; } - /* Remember new password */ - pam_set_item (pamh, PAM_AUTHTOK, (void *) newpass); - } - else /* newpass != NULL, we found an old password */ - { if (options.debug) - pam_syslog (pamh, LOG_DEBUG, "look in old password file"); + pam_syslog (pamh, LOG_DEBUG, "check against old password file"); if (check_old_password (pamh, user, newpass, options.debug) != PAM_SUCCESS) { pam_error (pamh, _("Password has been already used. Choose another.")); - /* We are only here, because old password was set. - So overwrite it, else it will be stored! */ + newpass = NULL; + /* Remove password item, else following module will use it */ pam_set_item (pamh, PAM_AUTHTOK, (void *) NULL); - - return PAM_AUTHTOK_ERR; + continue; } } - return PAM_SUCCESS; + if (newpass == NULL && tries >= options.tries) + { + if (options.debug) + pam_syslog (pamh, LOG_DEBUG, "Aborted, too many tries"); + return PAM_MAXTRIES; + } + + /* Remember new password */ + return pam_set_item (pamh, PAM_AUTHTOK, newpass); } diff --git a/modules/pam_timestamp/Makefile.am b/modules/pam_timestamp/Makefile.am index 373f483c..37cbabf9 100644 --- a/modules/pam_timestamp/Makefile.am +++ b/modules/pam_timestamp/Makefile.am @@ -9,7 +9,7 @@ XMLS = README.xml pam_timestamp.8.xml pam_timestamp_check.8.xml man_MANS = pam_timestamp.8 pam_timestamp_check.8 TESTS = tst-pam_timestamp hmacfile -EXTRA_DIST = $(man_MANS) hmactest.c $(XMLS) $(TESTS) +EXTRA_DIST = $(man_MANS) $(XMLS) $(TESTS) securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) |