pam_get_authtok.c revision 115619
191094Sdes/*- 2115619Sdes * Copyright (c) 2002-2003 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 * 34115619Sdes * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#25 $ 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) { 112115619Sdes FREE(resp); 113107937Sdes RETURNC(r); 11493982Sdes } 115115619Sdes if (strcmp(resp, resp2) != 0) 116115619Sdes FREE(resp); 117115619Sdes FREE(resp2); 11893982Sdes } 11993982Sdes if (resp == NULL) 120107937Sdes RETURNC(PAM_TRY_AGAIN); 12194706Sdes r = pam_set_item(pamh, item, resp); 122115619Sdes FREE(resp); 12393982Sdes if (r != PAM_SUCCESS) 124107937Sdes RETURNC(r); 125110556Sdes r = pam_get_item(pamh, item, (const void **)authtok); 126110556Sdes RETURNC(r); 12791094Sdes} 12891100Sdes 12991100Sdes/* 13091100Sdes * Error codes: 13191100Sdes * 13291100Sdes * =pam_get_item 13391100Sdes * =pam_prompt 13491100Sdes * =pam_set_item 13591100Sdes * !PAM_SYMBOL_ERR 13693982Sdes * PAM_TRY_AGAIN 13791100Sdes */ 13893982Sdes 13993982Sdes/** 14093982Sdes * The =pam_get_authtok function returns the cached authentication token, 14193982Sdes * or prompts the user if no token is currently cached. Either way, a 14293982Sdes * pointer to the authentication token is stored in the location pointed 14393982Sdes * to by the =authtok argument. 14493982Sdes * 14593982Sdes * The =item argument must have one of the following values: 14693982Sdes * 14795908Sdes * =PAM_AUTHTOK: 14893982Sdes * Returns the current authentication token, or the new token 14993982Sdes * when changing authentication tokens. 15095908Sdes * =PAM_OLDAUTHTOK: 15193982Sdes * Returns the previous authentication token when changing 15293982Sdes * authentication tokens. 15393982Sdes * 15493982Sdes * The =prompt argument specifies a prompt to use if no token is cached. 15593982Sdes * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, 15693982Sdes * as appropriate, will be used. If that item is also =NULL, a hardcoded 15793982Sdes * default prompt will be used. 15893982Sdes * 15993982Sdes * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK 16093982Sdes * item, =pam_get_authtok will ask the user to confirm the new token by 16193982Sdes * retyping it. If there is a mismatch, =pam_get_authtok will return 16293982Sdes * =PAM_TRY_AGAIN. 16393982Sdes * 16493982Sdes * >pam_get_item 16593982Sdes * >pam_get_user 16693982Sdes */ 167