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 2004 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 <syslog.h> 30 #include <pwd.h> 31 #include <unistd.h> 32 #include <strings.h> 33 #include <security/pam_appl.h> 34 #include <security/pam_modules.h> 35 #include <libintl.h> 36 37 static int parse_allow_name(char *, char *); 38 39 /* 40 * pam_sm_acct_mgmt main account managment routine. 41 * XXX: The routine just prints out a warning message. 42 * It may need to force the user to change his/her 43 * passwd. 44 */ 45 46 int 47 pam_sm_acct_mgmt( 48 pam_handle_t *pamh, 49 int flags, 50 int argc, 51 const char **argv) 52 { 53 char *user; 54 char *pg; 55 int i; 56 /*LINTED - set but not used. Would be used in a real module. */ 57 int debug = 0; 58 /*LINTED - set but not used. Would be used in a real module. */ 59 int nowarn = 0; 60 int error = 0; 61 62 if (argc == 0) 63 return (PAM_SUCCESS); 64 65 if (pam_get_item(pamh, PAM_USER, (void **)&user) != PAM_SUCCESS) 66 return (PAM_SERVICE_ERR); 67 68 if (pam_get_item(pamh, PAM_SERVICE, (void **)&pg) != PAM_SUCCESS) 69 return (PAM_SERVICE_ERR); 70 71 /* 72 * kludge alert. su needs to be handled specially for allow policy. 73 * we want to use the policy of the current user not the "destination" 74 * user. This will enable us to prevent su to root but not to rlogin, 75 * telnet, rsh, ftp to root. 76 * 77 * description of problem: user name is the "destination" name. not 78 * the current name. The allow policy needs to be applied to the 79 * current name in the case of su. user is "root" in this case and 80 * we will be getting the root policy instead of the user policy. 81 */ 82 if (strcmp(pg, "su") == 0) { 83 struct passwd *pw; 84 uid_t uid; 85 uid = getuid(); 86 pw = getpwuid(uid); 87 if (pw == NULL) 88 return (PAM_SYSTEM_ERR); 89 user = pw->pw_name; 90 } 91 92 if (user == 0 || *user == '\0' || (strcmp(user, "root") == 0)) 93 return (PAM_SUCCESS); 94 95 for (i = 0; i < argc; i++) { 96 if (strcasecmp(argv[i], "debug") == 0) 97 debug = 1; 98 else if (strcasecmp(argv[i], "nowarn") == 0) { 99 nowarn = 1; 100 flags = flags | PAM_SILENT; 101 } else if (strncmp(argv[i], "allow=", 6) == 0) 102 error |= parse_allow_name(user, (char *)(argv[i]+6)); 103 else 104 syslog(LOG_DEBUG, "illegal option %s", argv[i]); 105 } 106 return (error?PAM_SUCCESS:PAM_AUTH_ERR); 107 } 108 109 static int 110 parse_allow_name(char *who, char *cp) 111 { 112 char name[256]; 113 static char *getname(); 114 115 /* catch "allow=" */ 116 if (*cp == '\0') 117 return (0); 118 while (cp) { 119 cp = getname(cp, name); 120 /* catch things such as =, and ,, */ 121 if (*name == '\0') 122 continue; 123 if (strcmp(who, name) == 0) 124 return (1); 125 } 126 return (0); 127 } 128 129 static char * 130 getname(char *cp, char *name) 131 { 132 /* force name to be initially null string */ 133 *name = '\0'; 134 135 /* end of string? */ 136 if (*cp == '\0') 137 return ((char *)0); 138 while (*cp) { 139 /* end of name? */ 140 if (*cp == ',' || *cp == '\0') 141 break; 142 *name++ = *cp++; 143 } 144 /* make name into string */ 145 *name++ = '\0'; 146 return ((*cp == '\0')? (char *)0 : ++cp); 147 } 148