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