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 #include <crypt.h> 27 #include <pwd.h> 28 #include <shadow.h> 29 #include <string.h> 30 #include <stdlib.h> 31 #include <syslog.h> 32 #include <security/pam_appl.h> 33 #include <security/pam_modules.h> 34 #include "../../libpam/pam_impl.h" 35 36 #include <libintl.h> 37 38 /* 39 * Various useful files and string constants 40 */ 41 #define DIAL_FILE "/etc/dialups" 42 #define DPASS_FILE "/etc/d_passwd" 43 #define SHELL "/usr/bin/sh" 44 #define SCPYN(a, b) (void) strncpy(a, b, sizeof (a)) 45 46 /* 47 * pam_sm_authenticate - This is the top level function in the 48 * module called by pam_auth_port in the framework 49 * Returns: PAM_AUTH_ERR on failure, 0 on success 50 */ 51 /*ARGSUSED*/ 52 int 53 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) 54 { 55 char *ttyn, *user; 56 FILE *fp; 57 char defpass[30]; 58 char line[80]; 59 char *p1 = NULL, *p2 = NULL; 60 struct passwd pwd; 61 char pwd_buffer[1024]; 62 char *password = NULL; 63 int retcode; 64 int i; 65 int debug = 0; 66 int res; 67 68 for (i = 0; i < argc; i++) { 69 if (strcasecmp(argv[i], "debug") == 0) 70 debug = 1; 71 else 72 syslog(LOG_DEBUG, "illegal option %s", argv[i]); 73 } 74 75 if ((retcode = pam_get_user(pamh, &user, NULL)) 76 != PAM_SUCCESS || 77 (retcode = pam_get_item(pamh, PAM_TTY, (void **)&ttyn)) 78 != PAM_SUCCESS) 79 return (retcode); 80 81 if (debug) { 82 syslog(LOG_DEBUG, 83 "Dialpass authenticate user = %s, ttyn = %s", 84 user ? user : "NULL", ttyn ? ttyn : "NULL"); 85 } 86 87 if (ttyn == NULL || *ttyn == '\0') { 88 char *service; 89 90 (void) pam_get_item(pamh, PAM_SERVICE, (void **)&service); 91 syslog(LOG_ERR, "pam_dial_auth: terminal-device not specified" 92 "by %s, returning %s.", service, 93 pam_strerror(pamh, PAM_SERVICE_ERR)); 94 return (PAM_SERVICE_ERR); 95 } 96 if (getpwnam_r(user, &pwd, pwd_buffer, sizeof (pwd_buffer)) == NULL) 97 return (PAM_USER_UNKNOWN); 98 99 if ((fp = fopen(DIAL_FILE, "rF")) == NULL) 100 return (PAM_IGNORE); 101 102 while ((p1 = fgets(line, sizeof (line), fp)) != NULL) { 103 while (*p1 != '\n' && *p1 != ' ' && *p1 != '\t') 104 p1++; 105 *p1 = '\0'; 106 if (strcmp(line, ttyn) == 0) 107 break; 108 } 109 110 (void) fclose(fp); 111 112 if ((fp = fopen(DPASS_FILE, "rF")) == NULL) { 113 syslog(LOG_ERR, "pam_dial_auth: %s without %s, returning %s.", 114 DIAL_FILE, DPASS_FILE, 115 pam_strerror(pamh, PAM_SYSTEM_ERR)); 116 (void) memset(line, 0, sizeof (line)); 117 return (PAM_SYSTEM_ERR); 118 } 119 120 if (p1 == NULL) { 121 (void) fclose(fp); 122 (void) memset(line, 0, sizeof (line)); 123 return (PAM_IGNORE); 124 } 125 126 defpass[0] = '\0'; 127 128 while ((p1 = fgets(line, sizeof (line)-1, fp)) != NULL) { 129 while (*p1 && *p1 != ':') 130 p1++; 131 *p1++ = '\0'; 132 p2 = p1; 133 while (*p1 && *p1 != ':') 134 p1++; 135 *p1 = '\0'; 136 if (pwd.pw_shell != NULL && strcmp(pwd.pw_shell, line) == 0) 137 break; 138 139 if (strcmp(SHELL, line) == 0) 140 SCPYN(defpass, p2); 141 p2 = NULL; 142 } 143 144 (void) memset(line, 0, sizeof (line)); 145 (void) fclose(fp); 146 147 if (p2 == NULL) 148 p2 = defpass; 149 150 if (*p2 != '\0') { 151 res = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK, 152 dgettext(TEXT_DOMAIN, "Dialup Password: "), &password); 153 154 if (res != PAM_SUCCESS) { 155 return (res); 156 } 157 158 if (strcmp(crypt(password, p2), p2) != 0) { 159 (void) memset(password, 0, strlen(password)); 160 free(password); 161 return (PAM_AUTH_ERR); 162 } 163 (void) memset(password, 0, strlen(password)); 164 free(password); 165 } 166 167 return (PAM_SUCCESS); 168 } 169 170 /* 171 * dummy pam_sm_setcred - does nothing 172 */ 173 /*ARGSUSED*/ 174 int 175 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 176 { 177 return (PAM_IGNORE); 178 } 179