diff options
Diffstat (limited to 'contrib/openpam/lib/pam_get_authtok.c')
-rw-r--r-- | contrib/openpam/lib/pam_get_authtok.c | 100 |
1 files changed, 89 insertions, 11 deletions
diff --git a/contrib/openpam/lib/pam_get_authtok.c b/contrib/openpam/lib/pam_get_authtok.c index e7edc66..8dd8238 100644 --- a/contrib/openpam/lib/pam_get_authtok.c +++ b/contrib/openpam/lib/pam_get_authtok.c @@ -31,16 +31,22 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#12 $ + * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#15 $ */ #include <sys/param.h> +#include <stdlib.h> + #include <security/pam_appl.h> #include <security/openpam.h> #include "openpam_impl.h" +const char authtok_prompt[] = "Password:"; +const char oldauthtok_prompt[] = "Old Password:"; +const char newauthtok_prompt[] = "New Password:"; + /* * OpenPAM extension * @@ -49,34 +55,76 @@ int pam_get_authtok(pam_handle_t *pamh, + int item, const char **authtok, const char *prompt) { - char *p, *resp; - int r, style; + const void *oldauthtok; + const char *default_prompt; + char *resp, *resp2; + int pitem, r, style, twice; if (pamh == NULL || authtok == NULL) return (PAM_SYSTEM_ERR); + *authtok = NULL; + twice = 0; + switch (item) { + case PAM_AUTHTOK: + pitem = PAM_AUTHTOK_PROMPT; + default_prompt = authtok_prompt; + r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok); + if (r == PAM_SUCCESS && oldauthtok != NULL) { + default_prompt = newauthtok_prompt; + twice = 1; + } + break; + case PAM_OLDAUTHTOK: + pitem = PAM_OLDAUTHTOK_PROMPT; + default_prompt = oldauthtok_prompt; + twice = 0; + break; + default: + return (PAM_SYMBOL_ERR); + } + if (openpam_get_option(pamh, "try_first_pass") || openpam_get_option(pamh, "use_first_pass")) { - r = pam_get_item(pamh, PAM_AUTHTOK, (const void **)authtok); + r = pam_get_item(pamh, item, (const void **)authtok); if (r == PAM_SUCCESS && *authtok != NULL) return (PAM_SUCCESS); else if (openpam_get_option(pamh, "use_first_pass")) return (r == PAM_SUCCESS ? PAM_AUTH_ERR : r); } - if (pam_get_item(pamh, PAM_AUTHTOK_PROMPT, - (const void **)&p) != PAM_SUCCESS || p == NULL) - if (prompt == NULL) - prompt = "Password:"; + if (prompt == NULL) { + r = pam_get_item(pamh, pitem, (const void **)&prompt); + if (r != PAM_SUCCESS || prompt == NULL) + prompt = default_prompt; + } style = openpam_get_option(pamh, "echo_pass") ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; - r = pam_prompt(pamh, style, &resp, "%s", p ? p : prompt); + r = pam_prompt(pamh, style, &resp, "%s", prompt); + if (r != PAM_SUCCESS) + return (r); + if (twice) { + r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt); + if (r != PAM_SUCCESS) { + free(resp); + return (r); + } + if (strcmp(resp, resp2) != 0) { + free(resp); + resp = NULL; + } + free(resp2); + } + if (resp == NULL) + return (PAM_TRY_AGAIN); + r = pam_set_item(pamh, pitem, resp); + free(resp); if (r != PAM_SUCCESS) return (r); - *authtok = resp; - return (pam_set_item(pamh, PAM_AUTHTOK, *authtok)); + return (pam_get_item(pamh, pitem, (const void **)authtok)); } /* @@ -86,4 +134,34 @@ pam_get_authtok(pam_handle_t *pamh, * =pam_prompt * =pam_set_item * !PAM_SYMBOL_ERR + * PAM_TRY_AGAIN + */ + +/** + * The =pam_get_authtok function returns the cached authentication token, + * or prompts the user if no token is currently cached. Either way, a + * pointer to the authentication token is stored in the location pointed + * to by the =authtok argument. + * + * The =item argument must have one of the following values: + * + * =PAM_AUTHTOK + * Returns the current authentication token, or the new token + * when changing authentication tokens. + * =PAM_OLDAUTHTOK + * Returns the previous authentication token when changing + * authentication tokens. + * + * The =prompt argument specifies a prompt to use if no token is cached. + * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, + * as appropriate, will be used. If that item is also =NULL, a hardcoded + * default prompt will be used. + * + * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK + * item, =pam_get_authtok will ask the user to confirm the new token by + * retyping it. If there is a mismatch, =pam_get_authtok will return + * =PAM_TRY_AGAIN. + * + * >pam_get_item + * >pam_get_user */ |