pam_get_authtok.c revision 115619
150397Sobrien/*- 290075Sobrien * Copyright (c) 2002-2003 Networks Associates Technology, Inc. 350397Sobrien * All rights reserved. 450397Sobrien * 590075Sobrien * This software was developed for the FreeBSD Project by ThinkSec AS and 650397Sobrien * Network Associates Laboratories, the Security Research Division of 790075Sobrien * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 890075Sobrien * ("CBOSS"), as part of the DARPA CHATS research program. 990075Sobrien * 1090075Sobrien * Redistribution and use in source and binary forms, with or without 1150397Sobrien * modification, are permitted provided that the following conditions 1290075Sobrien * are met: 1390075Sobrien * 1. Redistributions of source code must retain the above copyright 1490075Sobrien * notice, this list of conditions and the following disclaimer. 1590075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1650397Sobrien * notice, this list of conditions and the following disclaimer in the 1750397Sobrien * documentation and/or other materials provided with the distribution. 1890075Sobrien * 3. The name of the author may not be used to endorse or promote 1990075Sobrien * products derived from this software without specific prior written 2090075Sobrien * permission. 2150397Sobrien * 2250397Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2350397Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2450397Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2590075Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2690075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2790075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2850397Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2950397Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3050397Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3190075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3250397Sobrien * SUCH DAMAGE. 3352284Sobrien * 3450397Sobrien * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#25 $ 3590075Sobrien */ 3652284Sobrien 3790075Sobrien#include <sys/param.h> 3890075Sobrien 3950397Sobrien#include <stdlib.h> 4052284Sobrien#include <string.h> 4152284Sobrien 4290075Sobrien#include <security/pam_appl.h> 4390075Sobrien#include <security/openpam.h> 4452284Sobrien 4552284Sobrien#include "openpam_impl.h" 4652284Sobrien 4752284Sobrienconst char authtok_prompt[] = "Password:"; 4852284Sobrienconst char oldauthtok_prompt[] = "Old Password:"; 4952284Sobrienconst char newauthtok_prompt[] = "New Password:"; 5052284Sobrien 5152284Sobrien/* 5252284Sobrien * OpenPAM extension 5352284Sobrien * 5452284Sobrien * Retrieve authentication token 5552284Sobrien */ 5652284Sobrien 5790075Sobrienint 5890075Sobrienpam_get_authtok(pam_handle_t *pamh, 5990075Sobrien int item, 6052284Sobrien const char **authtok, 6190075Sobrien const char *prompt) 6290075Sobrien{ 6390075Sobrien const void *oldauthtok; 6490075Sobrien const char *default_prompt; 6590075Sobrien char *resp, *resp2; 6652284Sobrien int pitem, r, style, twice; 6752284Sobrien 6852284Sobrien ENTER(); 6952284Sobrien if (pamh == NULL || authtok == NULL) 7090075Sobrien RETURNC(PAM_SYSTEM_ERR); 7190075Sobrien *authtok = NULL; 7252284Sobrien twice = 0; 7390075Sobrien switch (item) { 7452284Sobrien case PAM_AUTHTOK: 7552284Sobrien pitem = PAM_AUTHTOK_PROMPT; 7690075Sobrien default_prompt = authtok_prompt; 7752284Sobrien r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok); 7852284Sobrien if (r == PAM_SUCCESS && oldauthtok != NULL) { 7952284Sobrien default_prompt = newauthtok_prompt; 8052284Sobrien twice = 1; 8152284Sobrien } 8252284Sobrien break; 8352284Sobrien case PAM_OLDAUTHTOK: 8490075Sobrien pitem = PAM_OLDAUTHTOK_PROMPT; 8590075Sobrien default_prompt = oldauthtok_prompt; 8690075Sobrien twice = 0; 8790075Sobrien break; 8850397Sobrien default: 8990075Sobrien RETURNC(PAM_SYMBOL_ERR); 9090075Sobrien } 9190075Sobrien if (openpam_get_option(pamh, "try_first_pass") || 9290075Sobrien openpam_get_option(pamh, "use_first_pass")) { 9390075Sobrien r = pam_get_item(pamh, item, (const void **)authtok); 9490075Sobrien if (r == PAM_SUCCESS && *authtok != NULL) 9590075Sobrien RETURNC(PAM_SUCCESS); 9690075Sobrien else if (openpam_get_option(pamh, "use_first_pass")) 9790075Sobrien RETURNC(r == PAM_SUCCESS ? PAM_AUTH_ERR : r); 9890075Sobrien } 9990075Sobrien if (prompt == NULL) { 10090075Sobrien r = pam_get_item(pamh, pitem, (const void **)&prompt); 10190075Sobrien if (r != PAM_SUCCESS || prompt == NULL) 10290075Sobrien prompt = default_prompt; 10390075Sobrien } 10490075Sobrien style = openpam_get_option(pamh, "echo_pass") ? 10590075Sobrien PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; 10690075Sobrien r = pam_prompt(pamh, style, &resp, "%s", prompt); 10790075Sobrien if (r != PAM_SUCCESS) 10890075Sobrien RETURNC(r); 10990075Sobrien if (twice) { 11090075Sobrien r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt); 11190075Sobrien if (r != PAM_SUCCESS) { 11290075Sobrien FREE(resp); 11350397Sobrien RETURNC(r); 11450397Sobrien } 11590075Sobrien if (strcmp(resp, resp2) != 0) 11650397Sobrien FREE(resp); 11750397Sobrien FREE(resp2); 11850397Sobrien } 11952284Sobrien if (resp == NULL) 12052284Sobrien RETURNC(PAM_TRY_AGAIN); 12152284Sobrien r = pam_set_item(pamh, item, resp); 12252284Sobrien FREE(resp); 12352284Sobrien if (r != PAM_SUCCESS) 12450397Sobrien RETURNC(r); 12550397Sobrien r = pam_get_item(pamh, item, (const void **)authtok); 12690075Sobrien RETURNC(r); 12750397Sobrien} 12850397Sobrien 12950397Sobrien/* 13050397Sobrien * Error codes: 13150397Sobrien * 13250397Sobrien * =pam_get_item 13350397Sobrien * =pam_prompt 13450397Sobrien * =pam_set_item 13550397Sobrien * !PAM_SYMBOL_ERR 13650397Sobrien * PAM_TRY_AGAIN 13790075Sobrien */ 13850397Sobrien 13990075Sobrien/** 14090075Sobrien * The =pam_get_authtok function returns the cached authentication token, 14190075Sobrien * or prompts the user if no token is currently cached. Either way, a 14290075Sobrien * pointer to the authentication token is stored in the location pointed 14390075Sobrien * to by the =authtok argument. 14490075Sobrien * 14590075Sobrien * The =item argument must have one of the following values: 14690075Sobrien * 14790075Sobrien * =PAM_AUTHTOK: 14890075Sobrien * Returns the current authentication token, or the new token 14990075Sobrien * when changing authentication tokens. 15090075Sobrien * =PAM_OLDAUTHTOK: 15190075Sobrien * Returns the previous authentication token when changing 15250397Sobrien * authentication tokens. 15390075Sobrien * 15490075Sobrien * The =prompt argument specifies a prompt to use if no token is cached. 15550397Sobrien * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, 15650397Sobrien * as appropriate, will be used. If that item is also =NULL, a hardcoded 15750397Sobrien * default prompt will be used. 15850397Sobrien * 15950397Sobrien * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK 16050397Sobrien * item, =pam_get_authtok will ask the user to confirm the new token by 16150397Sobrien * retyping it. If there is a mismatch, =pam_get_authtok will return 16250397Sobrien * =PAM_TRY_AGAIN. 16350397Sobrien * 16450397Sobrien * >pam_get_item 16550397Sobrien * >pam_get_user 16690075Sobrien */ 16790075Sobrien