1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <crypt.h> 29 #include <pwd.h> 30 #include <shadow.h> 31 #include <string.h> 32 #include <stdlib.h> 33 #include <syslog.h> 34 #include <security/pam_appl.h> 35 #include <security/pam_modules.h> 36 #include "../../libpam/pam_impl.h" 37 38 #include <libintl.h> 39 40 /* 41 * Various useful files and string constants 42 */ 43 #define DIAL_FILE "/etc/dialups" 44 #define DPASS_FILE "/etc/d_passwd" 45 #define SHELL "/usr/bin/sh" 46 #define SCPYN(a, b) (void) strncpy(a, b, sizeof (a)) 47 48 /* 49 * pam_sm_authenticate - This is the top level function in the 50 * module called by pam_auth_port in the framework 51 * Returns: PAM_AUTH_ERR on failure, 0 on success 52 */ 53 /*ARGSUSED*/ 54 int 55 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) 56 { 57 char *ttyn, *user; 58 FILE *fp; 59 char defpass[30]; 60 char line[80]; 61 char *p1 = NULL, *p2 = NULL; 62 struct passwd pwd; 63 char pwd_buffer[1024]; 64 char *password = NULL; 65 int retcode; 66 int i; 67 int debug = 0; 68 int res; 69 70 for (i = 0; i < argc; i++) { 71 if (strcasecmp(argv[i], "debug") == 0) 72 debug = 1; 73 else 74 syslog(LOG_DEBUG, "illegal option %s", argv[i]); 75 } 76 77 if ((retcode = pam_get_user(pamh, &user, NULL)) 78 != PAM_SUCCESS || 79 (retcode = pam_get_item(pamh, PAM_TTY, (void **)&ttyn)) 80 != PAM_SUCCESS) 81 return (retcode); 82 83 if (debug) { 84 syslog(LOG_DEBUG, 85 "Dialpass authenticate user = %s, ttyn = %s", 86 user ? user : "NULL", ttyn ? ttyn : "NULL"); 87 } 88 89 if (ttyn == NULL || *ttyn == '\0') { 90 char *service; 91 92 (void) pam_get_item(pamh, PAM_SERVICE, (void **)&service); 93 syslog(LOG_ERR, "pam_dial_auth: terminal-device not specified" 94 "by %s, returning %s.", service, 95 pam_strerror(pamh, PAM_SERVICE_ERR)); 96 return (PAM_SERVICE_ERR); 97 } 98 if (getpwnam_r(user, &pwd, pwd_buffer, sizeof (pwd_buffer)) == NULL) 99 return (PAM_USER_UNKNOWN); 100 101 if ((fp = fopen(DIAL_FILE, "rF")) == NULL) 102 return (PAM_IGNORE); 103 104 while ((p1 = fgets(line, sizeof (line), fp)) != NULL) { 105 while (*p1 != '\n' && *p1 != ' ' && *p1 != '\t') 106 p1++; 107 *p1 = '\0'; 108 if (strcmp(line, ttyn) == 0) 109 break; 110 } 111 112 (void) fclose(fp); 113 114 if ((fp = fopen(DPASS_FILE, "rF")) == NULL) { 115 syslog(LOG_ERR, "pam_dial_auth: %s without %s, returning %s.", 116 DIAL_FILE, DPASS_FILE, 117 pam_strerror(pamh, PAM_SYSTEM_ERR)); 118 (void) memset(line, 0, sizeof (line)); 119 return (PAM_SYSTEM_ERR); 120 } 121 122 if (p1 == NULL) { 123 (void) fclose(fp); 124 (void) memset(line, 0, sizeof (line)); 125 return (PAM_IGNORE); 126 } 127 128 defpass[0] = '\0'; 129 130 while ((p1 = fgets(line, sizeof (line)-1, fp)) != NULL) { 131 while (*p1 && *p1 != ':') 132 p1++; 133 *p1++ = '\0'; 134 p2 = p1; 135 while (*p1 && *p1 != ':') 136 p1++; 137 *p1 = '\0'; 138 if (pwd.pw_shell != NULL && strcmp(pwd.pw_shell, line) == 0) 139 break; 140 141 if (strcmp(SHELL, line) == 0) 142 SCPYN(defpass, p2); 143 p2 = NULL; 144 } 145 146 (void) memset(line, 0, sizeof (line)); 147 (void) fclose(fp); 148 149 if (p2 == NULL) 150 p2 = defpass; 151 152 if (*p2 != '\0') { 153 res = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK, 154 dgettext(TEXT_DOMAIN, "Dialup Password: "), &password); 155 156 if (res != PAM_SUCCESS) { 157 return (res); 158 } 159 160 if (strcmp(crypt(password, p2), p2) != 0) { 161 (void) memset(password, 0, strlen(password)); 162 free(password); 163 return (PAM_AUTH_ERR); 164 } 165 (void) memset(password, 0, strlen(password)); 166 free(password); 167 } 168 169 return (PAM_SUCCESS); 170 } 171 172 /* 173 * dummy pam_sm_setcred - does nothing 174 */ 175 /*ARGSUSED*/ 176 int 177 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 178 { 179 return (PAM_IGNORE); 180 } 181