| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include "config.h" |
| |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <syslog.h> |
| #include <stdarg.h> |
| #include <sys/types.h> |
| #include <pwd.h> |
| #include <grp.h> |
| |
| |
| |
| |
| |
| |
| |
| |
| #define PAM_SM_AUTH |
| #define PAM_SM_ACCOUNT |
| |
| #include <security/pam_modules.h> |
| #include <security/pam_modutil.h> |
| #include <security/pam_ext.h> |
| |
| |
| static int is_on_list(char * const *list, const char *member) |
| { |
| while (list && *list) { |
| if (strcmp(*list, member) == 0) |
| return 1; |
| list++; |
| } |
| return 0; |
| } |
| |
| |
| |
| #define PAM_DEBUG_ARG 0x0001 |
| #define PAM_USE_UID_ARG 0x0002 |
| #define PAM_TRUST_ARG 0x0004 |
| #define PAM_DENY_ARG 0x0010 |
| #define PAM_ROOT_ONLY_ARG 0x0020 |
| |
| static int |
| _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, |
| char *use_group, size_t group_length) |
| { |
| int ctrl=0; |
| |
| memset(use_group, '\0', group_length); |
| |
| |
| for (ctrl=0; argc-- > 0; ++argv) { |
| |
| |
| |
| if (!strcmp(*argv,"debug")) |
| ctrl |= PAM_DEBUG_ARG; |
| else if (!strcmp(*argv,"use_uid")) |
| ctrl |= PAM_USE_UID_ARG; |
| else if (!strcmp(*argv,"trust")) |
| ctrl |= PAM_TRUST_ARG; |
| else if (!strcmp(*argv,"deny")) |
| ctrl |= PAM_DENY_ARG; |
| else if (!strcmp(*argv,"root_only")) |
| ctrl |= PAM_ROOT_ONLY_ARG; |
| else if (!strncmp(*argv,"group=",6)) |
| strncpy(use_group,*argv+6,group_length-1); |
| else { |
| pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); |
| } |
| } |
| |
| return ctrl; |
| } |
| |
| static int |
| perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) |
| { |
| const char *username = NULL; |
| const char *fromsu; |
| struct passwd *pwd, *tpwd = NULL; |
| struct group *grp; |
| int retval = PAM_AUTH_ERR; |
| |
| retval = pam_get_user(pamh, &username, NULL); |
| if ((retval != PAM_SUCCESS) || (!username)) { |
| if (ctrl & PAM_DEBUG_ARG) { |
| pam_syslog(pamh, LOG_DEBUG, "can not get the username"); |
| } |
| return PAM_SERVICE_ERR; |
| } |
| |
| pwd = pam_modutil_getpwnam (pamh, username); |
| if (!pwd) { |
| if (ctrl & PAM_DEBUG_ARG) { |
| pam_syslog(pamh, LOG_NOTICE, "unknown user %s", username); |
| } |
| return PAM_USER_UNKNOWN; |
| } |
| if (ctrl & PAM_ROOT_ONLY_ARG) { |
| |
| if (pwd->pw_uid != 0) { |
| return PAM_IGNORE; |
| } |
| } |
| |
| if (ctrl & PAM_USE_UID_ARG) { |
| tpwd = pam_modutil_getpwuid (pamh, getuid()); |
| if (tpwd == NULL) { |
| if (ctrl & PAM_DEBUG_ARG) { |
| pam_syslog(pamh, LOG_NOTICE, "who is running me ?!"); |
| } |
| return PAM_SERVICE_ERR; |
| } |
| fromsu = tpwd->pw_name; |
| } else { |
| fromsu = pam_modutil_getlogin(pamh); |
| |
| |
| if (fromsu == NULL) { |
| const char *rhostname; |
| |
| retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhostname); |
| if (retval != PAM_SUCCESS || rhostname == NULL) { |
| retval = pam_get_item(pamh, PAM_RUSER, (const void **)&fromsu); |
| } |
| } |
| |
| if (fromsu != NULL) { |
| tpwd = pam_modutil_getpwnam (pamh, fromsu); |
| } |
| |
| if (fromsu == NULL || tpwd == NULL) { |
| if (ctrl & PAM_DEBUG_ARG) { |
| pam_syslog(pamh, LOG_NOTICE, "who is running me ?!"); |
| } |
| return PAM_SERVICE_ERR; |
| } |
| } |
| |
| |
| |
| |
| |
| if (!use_group[0]) { |
| if ((grp = pam_modutil_getgrnam (pamh, "wheel")) == NULL) { |
| grp = pam_modutil_getgrgid (pamh, 0); |
| } |
| } else { |
| grp = pam_modutil_getgrnam (pamh, use_group); |
| } |
| |
| if (!grp || (!grp->gr_mem && (tpwd->pw_gid != grp->gr_gid))) { |
| if (ctrl & PAM_DEBUG_ARG) { |
| if (!use_group[0]) { |
| pam_syslog(pamh, LOG_NOTICE, "no members in a GID 0 group"); |
| } else { |
| pam_syslog(pamh, LOG_NOTICE, |
| "no members in '%s' group", use_group); |
| } |
| } |
| if (ctrl & PAM_DENY_ARG) { |
| |
| |
| |
| |
| return PAM_IGNORE; |
| } else { |
| return PAM_AUTH_ERR; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| if (is_on_list(grp->gr_mem, fromsu) || (tpwd->pw_gid == grp->gr_gid)) { |
| |
| if (ctrl & PAM_DENY_ARG) { |
| retval = PAM_PERM_DENIED; |
| |
| } else if (ctrl & PAM_TRUST_ARG) { |
| retval = PAM_SUCCESS; |
| |
| } else { |
| retval = PAM_IGNORE; |
| } |
| |
| } else { |
| |
| if (ctrl & PAM_DENY_ARG) { |
| |
| if (ctrl & PAM_TRUST_ARG) { |
| retval = PAM_SUCCESS; |
| } else { |
| retval = PAM_IGNORE; |
| } |
| |
| } else { |
| retval = PAM_PERM_DENIED; |
| } |
| } |
| |
| if (ctrl & PAM_DEBUG_ARG) { |
| if (retval == PAM_IGNORE) { |
| pam_syslog(pamh, LOG_NOTICE, |
| "Ignoring access request '%s' for '%s'", |
| fromsu, username); |
| } else { |
| pam_syslog(pamh, LOG_NOTICE, "Access %s to '%s' for '%s'", |
| (retval != PAM_SUCCESS) ? "denied":"granted", |
| fromsu, username); |
| } |
| } |
| |
| return retval; |
| } |
| |
| |
| |
| int |
| pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, |
| int argc, const char **argv) |
| { |
| char use_group[BUFSIZ]; |
| int ctrl; |
| |
| ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group)); |
| |
| return perform_check(pamh, ctrl, use_group); |
| } |
| |
| int |
| pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, |
| int argc UNUSED, const char **argv UNUSED) |
| { |
| return PAM_SUCCESS; |
| } |
| |
| int |
| pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED, |
| int argc, const char **argv) |
| { |
| char use_group[BUFSIZ]; |
| int ctrl; |
| |
| ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group)); |
| |
| return perform_check(pamh, ctrl, use_group); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |