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