pam_get_authtok.c revision 107937
11573Srgrimes/*- 21573Srgrimes * Copyright (c) 2002 Networks Associates Technology, Inc. 31573Srgrimes * All rights reserved. 41573Srgrimes * 51573Srgrimes * This software was developed for the FreeBSD Project by ThinkSec AS and 61573Srgrimes * Network Associates Laboratories, the Security Research Division of 71573Srgrimes * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 81573Srgrimes * ("CBOSS"), as part of the DARPA CHATS research program. 91573Srgrimes * 101573Srgrimes * Redistribution and use in source and binary forms, with or without 111573Srgrimes * modification, are permitted provided that the following conditions 121573Srgrimes * are met: 131573Srgrimes * 1. Redistributions of source code must retain the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer. 151573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161573Srgrimes * notice, this list of conditions and the following disclaimer in the 171573Srgrimes * documentation and/or other materials provided with the distribution. 181573Srgrimes * 3. The name of the author may not be used to endorse or promote 191573Srgrimes * products derived from this software without specific prior written 201573Srgrimes * permission. 211573Srgrimes * 221573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 231573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 261573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321573Srgrimes * SUCH DAMAGE. 3392986Sobrien * 3492986Sobrien * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#20 $ 351573Srgrimes */ 361573Srgrimes 371573Srgrimes#include <sys/param.h> 381573Srgrimes 391573Srgrimes#include <stdlib.h> 40218285Sjilles#include <string.h> 41218285Sjilles 42218285Sjilles#include <security/pam_appl.h> 43218285Sjilles#include <security/openpam.h> 44218285Sjilles 45218285Sjilles#include "openpam_impl.h" 46218285Sjilles 47218285Sjillesconst char authtok_prompt[] = "Password:"; 48218285Sjillesconst char oldauthtok_prompt[] = "Old Password:"; 49218285Sjillesconst char newauthtok_prompt[] = "New Password:"; 50218285Sjilles 51218285Sjilles/* 52218285Sjilles * OpenPAM extension 53218285Sjilles * 54218285Sjilles * Retrieve authentication token 55218285Sjilles */ 56218285Sjilles 57218285Sjillesint 58218285Sjillespam_get_authtok(pam_handle_t *pamh, 59218285Sjilles int item, 60218285Sjilles const char **authtok, 61218285Sjilles const char *prompt) 62218285Sjilles{ 63218285Sjilles const void *oldauthtok; 64218285Sjilles const char *default_prompt; 65218285Sjilles char *resp, *resp2; 66218285Sjilles int pitem, r, style, twice; 67218285Sjilles 68218285Sjilles ENTER(); 69218285Sjilles if (pamh == NULL || authtok == NULL) 70218285Sjilles RETURNC(PAM_SYSTEM_ERR); 711573Srgrimes *authtok = NULL; 721573Srgrimes twice = 0; 731573Srgrimes switch (item) { 741573Srgrimes case PAM_AUTHTOK: 751573Srgrimes pitem = PAM_AUTHTOK_PROMPT; 761573Srgrimes default_prompt = authtok_prompt; 771573Srgrimes r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok); 781573Srgrimes if (r == PAM_SUCCESS && oldauthtok != NULL) { 791573Srgrimes default_prompt = newauthtok_prompt; 801573Srgrimes twice = 1; 811573Srgrimes } 821573Srgrimes break; 831573Srgrimes case PAM_OLDAUTHTOK: 841573Srgrimes pitem = PAM_OLDAUTHTOK_PROMPT; 851573Srgrimes default_prompt = oldauthtok_prompt; 861573Srgrimes twice = 0; 871573Srgrimes break; 881573Srgrimes default: 891573Srgrimes RETURNC(PAM_SYMBOL_ERR); 901573Srgrimes } 911573Srgrimes if (openpam_get_option(pamh, "try_first_pass") || 921573Srgrimes openpam_get_option(pamh, "use_first_pass")) { 931573Srgrimes r = pam_get_item(pamh, item, (const void **)authtok); 941573Srgrimes if (r == PAM_SUCCESS && *authtok != NULL) 951573Srgrimes RETURNC(PAM_SUCCESS); 961573Srgrimes else if (openpam_get_option(pamh, "use_first_pass")) 971573Srgrimes RETURNC(r == PAM_SUCCESS ? PAM_AUTH_ERR : r); 981573Srgrimes } 991573Srgrimes if (prompt == NULL) { 1001573Srgrimes r = pam_get_item(pamh, pitem, (const void **)&prompt); 1011573Srgrimes if (r != PAM_SUCCESS || prompt == NULL) 1021573Srgrimes prompt = default_prompt; 1031573Srgrimes } 1041573Srgrimes style = openpam_get_option(pamh, "echo_pass") ? 1051573Srgrimes PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; 1061573Srgrimes r = pam_prompt(pamh, style, &resp, "%s", prompt); 10747289Speter if (r != PAM_SUCCESS) 108 RETURNC(r); 109 if (twice) { 110 r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt); 111 if (r != PAM_SUCCESS) { 112 free(resp); 113 RETURNC(r); 114 } 115 if (strcmp(resp, resp2) != 0) { 116 free(resp); 117 resp = NULL; 118 } 119 free(resp2); 120 } 121 if (resp == NULL) 122 RETURNC(PAM_TRY_AGAIN); 123 r = pam_set_item(pamh, item, resp); 124 free(resp); 125 if (r != PAM_SUCCESS) 126 RETURNC(r); 127 RETURNC(pam_get_item(pamh, item, (const void **)authtok)); 128} 129 130/* 131 * Error codes: 132 * 133 * =pam_get_item 134 * =pam_prompt 135 * =pam_set_item 136 * !PAM_SYMBOL_ERR 137 * PAM_TRY_AGAIN 138 */ 139 140/** 141 * The =pam_get_authtok function returns the cached authentication token, 142 * or prompts the user if no token is currently cached. Either way, a 143 * pointer to the authentication token is stored in the location pointed 144 * to by the =authtok argument. 145 * 146 * The =item argument must have one of the following values: 147 * 148 * =PAM_AUTHTOK: 149 * Returns the current authentication token, or the new token 150 * when changing authentication tokens. 151 * =PAM_OLDAUTHTOK: 152 * Returns the previous authentication token when changing 153 * authentication tokens. 154 * 155 * The =prompt argument specifies a prompt to use if no token is cached. 156 * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, 157 * as appropriate, will be used. If that item is also =NULL, a hardcoded 158 * default prompt will be used. 159 * 160 * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK 161 * item, =pam_get_authtok will ask the user to confirm the new token by 162 * retyping it. If there is a mismatch, =pam_get_authtok will return 163 * =PAM_TRY_AGAIN. 164 * 165 * >pam_get_item 166 * >pam_get_user 167 */ 168