1/* $NetBSD$ */ 2 3/*- 4 * Copyright (c) 2002-2003 Networks Associates Technology, Inc. 5 * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav 6 * All rights reserved. 7 * 8 * This software was developed for the FreeBSD Project by ThinkSec AS and 9 * Network Associates Laboratories, the Security Research Division of 10 * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 11 * ("CBOSS"), as part of the DARPA CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * Id: pam_unix.c 437 2011-09-13 12:00:13Z des 38 */ 39 40#ifdef HAVE_CONFIG_H 41# include "config.h" 42#endif 43 44#include <sys/param.h> 45 46#include <pwd.h> 47#include <stdlib.h> 48#include <stdio.h> 49#include <string.h> 50#include <unistd.h> 51 52#ifdef HAVE_CRYPT_H 53# include <crypt.h> 54#endif 55 56#include <security/pam_modules.h> 57#include <security/pam_appl.h> 58 59#ifndef OPENPAM 60static char password_prompt[] = "Password:"; 61#endif 62 63#ifndef PAM_EXTERN 64#define PAM_EXTERN 65#endif 66 67PAM_EXTERN int 68pam_sm_authenticate(pam_handle_t *pamh, int flags, 69 int argc, const char *argv[]) 70{ 71#ifndef OPENPAM 72 struct pam_conv *conv; 73 struct pam_message msg; 74 const struct pam_message *msgp; 75 struct pam_response *resp; 76#endif 77 struct passwd *pwd; 78 const char *user; 79 char *crypt_password, *password; 80 int pam_err, retry; 81 82 (void)argc; 83 (void)argv; 84 85 /* identify user */ 86 if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) 87 return (pam_err); 88 if ((pwd = getpwnam(user)) == NULL) 89 return (PAM_USER_UNKNOWN); 90 91 /* get password */ 92#ifndef OPENPAM 93 pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv); 94 if (pam_err != PAM_SUCCESS) 95 return (PAM_SYSTEM_ERR); 96 msg.msg_style = PAM_PROMPT_ECHO_OFF; 97 msg.msg = password_prompt; 98 msgp = &msg; 99#endif 100 for (retry = 0; retry < 3; ++retry) { 101#ifdef OPENPAM 102 pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, 103 (const char **)&password, NULL); 104#else 105 resp = NULL; 106 pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr); 107 if (resp != NULL) { 108 if (pam_err == PAM_SUCCESS) 109 password = resp->resp; 110 else 111 free(resp->resp); 112 free(resp); 113 } 114#endif 115 if (pam_err == PAM_SUCCESS) 116 break; 117 } 118 if (pam_err == PAM_CONV_ERR) 119 return (pam_err); 120 if (pam_err != PAM_SUCCESS) 121 return (PAM_AUTH_ERR); 122 123 /* compare passwords */ 124 if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) || 125 (crypt_password = crypt(password, pwd->pw_passwd)) == NULL || 126 strcmp(crypt_password, pwd->pw_passwd) != 0) 127 pam_err = PAM_AUTH_ERR; 128 else 129 pam_err = PAM_SUCCESS; 130#ifndef OPENPAM 131 free(password); 132#endif 133 return (pam_err); 134} 135 136PAM_EXTERN int 137pam_sm_setcred(pam_handle_t *pamh, int flags, 138 int argc, const char *argv[]) 139{ 140 141 (void)pamh; 142 (void)flags; 143 (void)argc; 144 (void)argv; 145 return (PAM_SUCCESS); 146} 147 148PAM_EXTERN int 149pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, 150 int argc, const char *argv[]) 151{ 152 153 (void)pamh; 154 (void)flags; 155 (void)argc; 156 (void)argv; 157 return (PAM_SUCCESS); 158} 159 160PAM_EXTERN int 161pam_sm_open_session(pam_handle_t *pamh, int flags, 162 int argc, const char *argv[]) 163{ 164 165 (void)pamh; 166 (void)flags; 167 (void)argc; 168 (void)argv; 169 return (PAM_SUCCESS); 170} 171 172PAM_EXTERN int 173pam_sm_close_session(pam_handle_t *pamh, int flags, 174 int argc, const char *argv[]) 175{ 176 177 (void)pamh; 178 (void)flags; 179 (void)argc; 180 (void)argv; 181 return (PAM_SUCCESS); 182} 183 184PAM_EXTERN int 185pam_sm_chauthtok(pam_handle_t *pamh, int flags, 186 int argc, const char *argv[]) 187{ 188 189 (void)pamh; 190 (void)flags; 191 (void)argc; 192 (void)argv; 193 return (PAM_SERVICE_ERR); 194} 195 196#ifdef PAM_MODULE_ENTRY 197PAM_MODULE_ENTRY("pam_unix"); 198#endif 199