1 /*- 2 * Copyright 1998 Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/lib/libpam/modules/pam_unix/pam_unix.c,v 1.4.2.4 2002/08/02 10:14:18 des Exp $ 27 * $DragonFly: src/lib/libpam/modules/pam_unix/Attic/pam_unix.c,v 1.2 2003/06/17 04:26:51 dillon Exp $ 28 */ 29 30 #include <sys/types.h> 31 #include <sys/time.h> 32 #include <login_cap.h> 33 #include <pwd.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <unistd.h> 38 39 #define PAM_SM_AUTH 40 #define PAM_SM_ACCOUNT 41 #include <security/pam_modules.h> 42 43 #include <security/pam_mod_misc.h> 44 45 #define PASSWORD_PROMPT "Password:" 46 47 enum { 48 PAM_OPT_AUTH_AS_SELF = PAM_OPT_STD_MAX, 49 PAM_OPT_NULLOK 50 }; 51 52 static struct opttab other_options[] = { 53 { "auth_as_self", PAM_OPT_AUTH_AS_SELF }, 54 { "nullok", PAM_OPT_NULLOK }, 55 { NULL, 0 } 56 }; 57 58 /* 59 * authentication management 60 */ 61 62 PAM_EXTERN int 63 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, 64 const char **argv) 65 { 66 int retval; 67 const char *user; 68 const char *password, *realpw; 69 struct passwd *pwd; 70 struct options options; 71 72 pam_std_option(&options, other_options, argc, argv); 73 if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) { 74 pwd = getpwnam(getlogin()); 75 } else { 76 retval = pam_get_user(pamh, &user, NULL); 77 if (retval != PAM_SUCCESS) 78 return retval; 79 pwd = getpwnam(user); 80 } 81 if (pwd != NULL) { 82 realpw = pwd->pw_passwd; 83 if (realpw[0] == '\0') { 84 if (!(flags & PAM_DISALLOW_NULL_AUTHTOK) && 85 pam_test_option(&options, PAM_OPT_NULLOK, NULL)) 86 return PAM_SUCCESS; 87 realpw = "*"; 88 } 89 } else { 90 realpw = "*"; 91 } 92 if ((retval = pam_get_pass(pamh, &password, PASSWORD_PROMPT, 93 &options)) != PAM_SUCCESS) 94 return retval; 95 if (strcmp(crypt(password, realpw), realpw) == 0) 96 return PAM_SUCCESS; 97 return PAM_AUTH_ERR; 98 } 99 100 PAM_EXTERN int 101 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 102 { 103 return PAM_SUCCESS; 104 } 105 106 /* 107 * account management 108 * 109 * check pw_change and pw_expire fields 110 */ 111 PAM_EXTERN 112 int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, 113 int argc, const char **argv) 114 { 115 const char *user; 116 struct passwd *pw; 117 struct timeval tp; 118 time_t warntime; 119 login_cap_t *lc = NULL; 120 char buf[128]; 121 int retval; 122 123 retval = pam_get_item(pamh, PAM_USER, (const void **)&user); 124 if (retval != PAM_SUCCESS || user == NULL) 125 /* some implementations return PAM_SUCCESS here */ 126 return PAM_USER_UNKNOWN; 127 128 if ((pw = getpwnam(user)) == NULL) 129 return PAM_USER_UNKNOWN; 130 131 retval = PAM_SUCCESS; 132 lc = login_getpwclass(pw); 133 134 if (pw->pw_change || pw->pw_expire) 135 gettimeofday(&tp, NULL); 136 137 #define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ 138 139 warntime = login_getcaptime(lc, "warnpassword", DEFAULT_WARN, 140 DEFAULT_WARN); 141 142 if (pw->pw_change) { 143 if (tp.tv_sec >= pw->pw_change) 144 /* some implementations return PAM_AUTHTOK_EXPIRED */ 145 retval = PAM_NEW_AUTHTOK_REQD; 146 else if (pw->pw_change - tp.tv_sec < warntime) { 147 snprintf(buf, sizeof(buf), 148 "Warning: your password expires on %s", 149 ctime(&pw->pw_change)); 150 pam_prompt(pamh, PAM_ERROR_MSG, buf, NULL); 151 } 152 } 153 154 warntime = login_getcaptime(lc, "warnexpire", DEFAULT_WARN, 155 DEFAULT_WARN); 156 157 if (pw->pw_expire) { 158 if (tp.tv_sec >= pw->pw_expire) 159 retval = PAM_ACCT_EXPIRED; 160 else if (pw->pw_expire - tp.tv_sec < warntime) { 161 snprintf(buf, sizeof(buf), 162 "Warning: your account expires on %s", 163 ctime(&pw->pw_expire)); 164 pam_prompt(pamh, PAM_ERROR_MSG, buf, NULL); 165 } 166 } 167 168 login_close(lc); 169 return retval; 170 } 171 172 PAM_MODULE_ENTRY("pam_unix"); 173