pam_get_authtok.c revision 110556
191094Sdes/*- 292289Sdes * Copyright (c) 2002 Networks Associates Technology, Inc. 391094Sdes * All rights reserved. 491094Sdes * 591094Sdes * This software was developed for the FreeBSD Project by ThinkSec AS and 699158Sdes * Network Associates Laboratories, the Security Research Division of 799158Sdes * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 899158Sdes * ("CBOSS"), as part of the DARPA CHATS research program. 991094Sdes * 1091094Sdes * Redistribution and use in source and binary forms, with or without 1191094Sdes * modification, are permitted provided that the following conditions 1291094Sdes * are met: 1391094Sdes * 1. Redistributions of source code must retain the above copyright 1491094Sdes * notice, this list of conditions and the following disclaimer. 1591094Sdes * 2. Redistributions in binary form must reproduce the above copyright 1691094Sdes * notice, this list of conditions and the following disclaimer in the 1791094Sdes * documentation and/or other materials provided with the distribution. 1891094Sdes * 3. The name of the author may not be used to endorse or promote 1991094Sdes * products derived from this software without specific prior written 2091094Sdes * permission. 2191094Sdes * 2291094Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2391094Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2491094Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2591094Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2691094Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2791094Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2891094Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2991094Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3091094Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3191094Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3291094Sdes * SUCH DAMAGE. 3391094Sdes * 34110556Sdes * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#21 $ 3591094Sdes */ 3691094Sdes 3791094Sdes#include <sys/param.h> 3891094Sdes 3993982Sdes#include <stdlib.h> 4096364Sdes#include <string.h> 4193982Sdes 4291094Sdes#include <security/pam_appl.h> 4391094Sdes#include <security/openpam.h> 4491094Sdes 4591094Sdes#include "openpam_impl.h" 4691094Sdes 4793982Sdesconst char authtok_prompt[] = "Password:"; 4893982Sdesconst char oldauthtok_prompt[] = "Old Password:"; 4993982Sdesconst char newauthtok_prompt[] = "New Password:"; 5093982Sdes 5191094Sdes/* 5291094Sdes * OpenPAM extension 5391094Sdes * 5491094Sdes * Retrieve authentication token 5591094Sdes */ 5691094Sdes 5791094Sdesint 5891094Sdespam_get_authtok(pam_handle_t *pamh, 5993982Sdes int item, 6091094Sdes const char **authtok, 6191094Sdes const char *prompt) 6291094Sdes{ 6393982Sdes const void *oldauthtok; 6493982Sdes const char *default_prompt; 6593982Sdes char *resp, *resp2; 6693982Sdes int pitem, r, style, twice; 6791094Sdes 68107937Sdes ENTER(); 6991094Sdes if (pamh == NULL || authtok == NULL) 70107937Sdes RETURNC(PAM_SYSTEM_ERR); 7193982Sdes *authtok = NULL; 7293982Sdes twice = 0; 7393982Sdes switch (item) { 7493982Sdes case PAM_AUTHTOK: 7593982Sdes pitem = PAM_AUTHTOK_PROMPT; 7693982Sdes default_prompt = authtok_prompt; 7793982Sdes r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok); 7893982Sdes if (r == PAM_SUCCESS && oldauthtok != NULL) { 7993982Sdes default_prompt = newauthtok_prompt; 8093982Sdes twice = 1; 8193982Sdes } 8293982Sdes break; 8393982Sdes case PAM_OLDAUTHTOK: 8493982Sdes pitem = PAM_OLDAUTHTOK_PROMPT; 8593982Sdes default_prompt = oldauthtok_prompt; 8693982Sdes twice = 0; 8793982Sdes break; 8893982Sdes default: 89107937Sdes RETURNC(PAM_SYMBOL_ERR); 9093982Sdes } 9191100Sdes if (openpam_get_option(pamh, "try_first_pass") || 9291100Sdes openpam_get_option(pamh, "use_first_pass")) { 9393982Sdes r = pam_get_item(pamh, item, (const void **)authtok); 9491100Sdes if (r == PAM_SUCCESS && *authtok != NULL) 95107937Sdes RETURNC(PAM_SUCCESS); 9691100Sdes else if (openpam_get_option(pamh, "use_first_pass")) 97107937Sdes RETURNC(r == PAM_SUCCESS ? PAM_AUTH_ERR : r); 9891100Sdes } 9993982Sdes if (prompt == NULL) { 10093982Sdes r = pam_get_item(pamh, pitem, (const void **)&prompt); 10193982Sdes if (r != PAM_SUCCESS || prompt == NULL) 10293982Sdes prompt = default_prompt; 10393982Sdes } 10491100Sdes style = openpam_get_option(pamh, "echo_pass") ? 10591100Sdes PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; 10693982Sdes r = pam_prompt(pamh, style, &resp, "%s", prompt); 10791094Sdes if (r != PAM_SUCCESS) 108107937Sdes RETURNC(r); 10993982Sdes if (twice) { 11093982Sdes r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt); 11193982Sdes if (r != PAM_SUCCESS) { 11293982Sdes free(resp); 113107937Sdes RETURNC(r); 11493982Sdes } 11593982Sdes if (strcmp(resp, resp2) != 0) { 11693982Sdes free(resp); 11793982Sdes resp = NULL; 11893982Sdes } 11993982Sdes free(resp2); 12093982Sdes } 12193982Sdes if (resp == NULL) 122107937Sdes RETURNC(PAM_TRY_AGAIN); 12394706Sdes r = pam_set_item(pamh, item, resp); 12493982Sdes free(resp); 12593982Sdes if (r != PAM_SUCCESS) 126107937Sdes RETURNC(r); 127110556Sdes r = pam_get_item(pamh, item, (const void **)authtok); 128110556Sdes RETURNC(r); 12991094Sdes} 13091100Sdes 13191100Sdes/* 13291100Sdes * Error codes: 13391100Sdes * 13491100Sdes * =pam_get_item 13591100Sdes * =pam_prompt 13691100Sdes * =pam_set_item 13791100Sdes * !PAM_SYMBOL_ERR 13893982Sdes * PAM_TRY_AGAIN 13991100Sdes */ 14093982Sdes 14193982Sdes/** 14293982Sdes * The =pam_get_authtok function returns the cached authentication token, 14393982Sdes * or prompts the user if no token is currently cached. Either way, a 14493982Sdes * pointer to the authentication token is stored in the location pointed 14593982Sdes * to by the =authtok argument. 14693982Sdes * 14793982Sdes * The =item argument must have one of the following values: 14893982Sdes * 14995908Sdes * =PAM_AUTHTOK: 15093982Sdes * Returns the current authentication token, or the new token 15193982Sdes * when changing authentication tokens. 15295908Sdes * =PAM_OLDAUTHTOK: 15393982Sdes * Returns the previous authentication token when changing 15493982Sdes * authentication tokens. 15593982Sdes * 15693982Sdes * The =prompt argument specifies a prompt to use if no token is cached. 15793982Sdes * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, 15893982Sdes * as appropriate, will be used. If that item is also =NULL, a hardcoded 15993982Sdes * default prompt will be used. 16093982Sdes * 16193982Sdes * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK 16293982Sdes * item, =pam_get_authtok will ask the user to confirm the new token by 16393982Sdes * retyping it. If there is a mismatch, =pam_get_authtok will return 16493982Sdes * =PAM_TRY_AGAIN. 16593982Sdes * 16693982Sdes * >pam_get_item 16793982Sdes * >pam_get_user 16893982Sdes */ 169