/* * Copyright (c) 1997 by Sun Microsystems, Inc. * All rights reserved. */ #pragma ident "@(#)su_group0.c 1.1" /* * su_group0.c - disallows su root for users no in group "0", like in * SunOS 4.x. This is for PAM in Solaris 2.6 and later. * * Compile: * * cc su_group0.c -o su_group0.so.1 -Kpic -G * * Install: * * cp su_group0.so.1 /usr/lib/security * chmod 644 /usr/lib/security/su_group0.so.1 * ln -s su_group0.so.1 /usr/lib/security/su_group0.so * * Add the following two lines to /etc/pam.conf: * su auth requisite /usr/lib/security/su_group0.so.1 * su auth required /usr/lib/security/pam_unix.so.1 * * (assuming that there weren't any su lines before; the second su line * is a copy from the "other auth" line w/ su substitued for other) * * Casper Dik */ #include #include #include #include #include char NO_SU_MESSAGE[] = { "not a member of group0" }; /* * pam_sm_authenticate - Access allowed ? */ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *username = NULL; char pwd_buf[1024]; char grp_buf[4096]; struct passwd pwd; struct group grp; struct pam_conv *conversation; struct pam_message message; struct pam_message *pmessage = &message; struct pam_response *resp = NULL; /* Root is allowed anything, not like it was in SunOS 4.x */ if (getuid() == 0) return PAM_SUCCESS; /* Who do we su to? */ if (pam_get_item(pamh, PAM_USER, (void**)&username) != PAM_SUCCESS) return PAM_SERVICE_ERR; if (getpwnam_r(username, &pwd, pwd_buf, sizeof(pwd_buf)) == NULL) return PAM_USER_UNKNOWN; /* Su to non-root - always allowed */ if (pwd.pw_uid != 0) return PAM_SUCCESS; /* Who's calling us? */ if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) == NULL) return PAM_USER_UNKNOWN; /* Group 0 exists?? */ if (getgrgid_r(0, &grp, grp_buf, sizeof(grp_buf)) == NULL) return PAM_AUTH_ERR; /* No members - no su restrictions */ if (grp.gr_mem[0] == 0) return PAM_SUCCESS; /* Check membership */ for (; grp.gr_mem[0]; grp.gr_mem++) { if (strcmp(grp.gr_mem[0], pwd.pw_name) == 0) { return PAM_SUCCESS; } } message.msg_style = PAM_ERROR_MSG; message.msg = NO_SU_MESSAGE; pam_get_item (pamh, PAM_CONV, (void**)&conversation); conversation->conv(1, (struct pam_message**)&pmessage, &resp, conversation->appdata_ptr); free (message.msg); return PAM_AUTH_ERR; } /* This module doesn't set credentials */ pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { return (PAM_SUCCESS); }