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 * Copyright 2023 OmniOS Community Edition (OmniOSce) Association. 26 */ 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 int 54 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) 55 { 56 const char *ttyn, *user; 57 FILE *fp; 58 char defpass[30]; 59 char line[80]; 60 char *p1 = NULL, *p2 = NULL; 61 struct passwd pwd; 62 char pwd_buffer[1024]; 63 char *password = NULL; 64 int retcode; 65 int i; 66 int debug = 0; 67 int res; 68 69 for (i = 0; i < argc; i++) { 70 if (strcasecmp(argv[i], "debug") == 0) 71 debug = 1; 72 else 73 syslog(LOG_DEBUG, "illegal option %s", argv[i]); 74 } 75 76 if ((retcode = pam_get_user(pamh, &user, NULL)) 77 != PAM_SUCCESS || 78 (retcode = pam_get_item(pamh, PAM_TTY, (const void **)&ttyn)) 79 != PAM_SUCCESS) 80 return (retcode); 81 82 if (debug) { 83 syslog(LOG_DEBUG, 84 "Dialpass authenticate user = %s, ttyn = %s", 85 user ? user : "NULL", ttyn ? ttyn : "NULL"); 86 } 87 88 if (ttyn == NULL || *ttyn == '\0') { 89 const char *service; 90 91 (void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service); 92 syslog(LOG_ERR, "pam_dial_auth: terminal-device not specified" 93 "by %s, returning %s.", service, 94 pam_strerror(pamh, PAM_SERVICE_ERR)); 95 return (PAM_SERVICE_ERR); 96 } 97 if (getpwnam_r(user, &pwd, pwd_buffer, sizeof (pwd_buffer)) == NULL) 98 return (PAM_USER_UNKNOWN); 99 100 if ((fp = fopen(DIAL_FILE, "rF")) == NULL) 101 return (PAM_IGNORE); 102 103 while ((p1 = fgets(line, sizeof (line), fp)) != NULL) { 104 while (*p1 != '\n' && *p1 != ' ' && *p1 != '\t') 105 p1++; 106 *p1 = '\0'; 107 if (strcmp(line, ttyn) == 0) 108 break; 109 } 110 111 (void) fclose(fp); 112 113 if ((fp = fopen(DPASS_FILE, "rF")) == NULL) { 114 syslog(LOG_ERR, "pam_dial_auth: %s without %s, returning %s.", 115 DIAL_FILE, DPASS_FILE, 116 pam_strerror(pamh, PAM_SYSTEM_ERR)); 117 (void) memset(line, 0, sizeof (line)); 118 return (PAM_SYSTEM_ERR); 119 } 120 121 if (p1 == NULL) { 122 (void) fclose(fp); 123 (void) memset(line, 0, sizeof (line)); 124 return (PAM_IGNORE); 125 } 126 127 defpass[0] = '\0'; 128 129 while ((p1 = fgets(line, sizeof (line)-1, fp)) != NULL) { 130 while (*p1 && *p1 != ':') 131 p1++; 132 *p1++ = '\0'; 133 p2 = p1; 134 while (*p1 && *p1 != ':') 135 p1++; 136 *p1 = '\0'; 137 if (pwd.pw_shell != NULL && strcmp(pwd.pw_shell, line) == 0) 138 break; 139 140 if (strcmp(SHELL, line) == 0) 141 SCPYN(defpass, p2); 142 p2 = NULL; 143 } 144 145 (void) memset(line, 0, sizeof (line)); 146 (void) fclose(fp); 147 148 if (p2 == NULL) 149 p2 = defpass; 150 151 if (*p2 != '\0') { 152 res = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK, 153 dgettext(TEXT_DOMAIN, "Dialup Password: "), &password); 154 155 if (res != PAM_SUCCESS) { 156 return (res); 157 } 158 159 if (strcmp(crypt(password, p2), p2) != 0) { 160 (void) memset(password, 0, strlen(password)); 161 free(password); 162 return (PAM_AUTH_ERR); 163 } 164 (void) memset(password, 0, strlen(password)); 165 free(password); 166 } 167 168 return (PAM_SUCCESS); 169 } 170 171 /* 172 * dummy pam_sm_setcred - does nothing 173 */ 174 /*ARGSUSED*/ 175 int 176 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 177 { 178 return (PAM_IGNORE); 179 } 180