From f07a873240de53e07897d4ef9d1d3fd0c28fe7bb Mon Sep 17 00:00:00 2001 From: Serghei Anicheev Date: Tue, 18 Feb 2020 21:07:02 +1100 Subject: pam_succeed_if: Add list support for group membership checks Examples: account requisite pam_succeed_if.so user ingroup group1:group2 OR account requisite pam_succeed_if.so user notingroup group1:group2 OR account requisite pam_succeed_if.so user ingroup wheel OR account requisite pam_succeed_if.so user notingroup wheel Can be very convenient to grant access based on complex group memberships (LDAP, etc) --- modules/pam_succeed_if/pam_succeed_if.8.xml | 12 ++++++------ modules/pam_succeed_if/pam_succeed_if.c | 30 ++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) (limited to 'modules/pam_succeed_if') diff --git a/modules/pam_succeed_if/pam_succeed_if.8.xml b/modules/pam_succeed_if/pam_succeed_if.8.xml index 7bdcb024..14d939a3 100644 --- a/modules/pam_succeed_if/pam_succeed_if.8.xml +++ b/modules/pam_succeed_if/pam_succeed_if.8.xml @@ -198,15 +198,15 @@ - + - User is in given group. + User is in given group(s). - + - User is not in given group. + User is not in given group(s). @@ -271,10 +271,10 @@ EXAMPLES To emulate the behaviour of pam_wheel, except - there is no fallback to group 0: + there is no fallback to group 0 being only approximated by checking also the root group membership: -auth required pam_succeed_if.so quiet user ingroup wheel +auth required pam_succeed_if.so quiet user ingroup wheel:root diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c index 2a791d26..b02b93d2 100644 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ b/modules/pam_succeed_if/pam_succeed_if.c @@ -217,17 +217,33 @@ evaluate_notinlist(const char *left, const char *right) static int evaluate_ingroup(pam_handle_t *pamh, const char *user, const char *group) { - if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 1) - return PAM_SUCCESS; + char *ptr = NULL; + const char const *delim = ":"; + char const *grp = NULL; + + grp = strtok_r(group, delim, &ptr); + while(grp != NULL) { + if (pam_modutil_user_in_group_nam_nam(pamh, user, grp) == 1) + return PAM_SUCCESS; + grp = strtok_r(NULL, delim, &ptr); + } return PAM_AUTH_ERR; } /* Return PAM_SUCCESS if the user is NOT in the group. */ static int evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *group) { - if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 0) - return PAM_SUCCESS; - return PAM_AUTH_ERR; + char *ptr = NULL; + const char const *delim = ":"; + char const *grp = NULL; + + grp = strtok_r(group, delim, &ptr); + while(grp != NULL) { + if (pam_modutil_user_in_group_nam_nam(pamh, user, grp) == 1) + return PAM_AUTH_ERR; + grp = strtok_r(NULL, delim, &ptr); + } + return PAM_SUCCESS; } #ifdef HAVE_INNETGR @@ -403,11 +419,11 @@ evaluate(pam_handle_t *pamh, int debug, if (strcasecmp(qual, "notin") == 0) { return evaluate_notinlist(left, right); } - /* User is in this group. */ + /* User is in this group(s). */ if (strcasecmp(qual, "ingroup") == 0) { return evaluate_ingroup(pamh, user, right); } - /* User is not in this group. */ + /* User is not in this group(s). */ if (strcasecmp(qual, "notingroup") == 0) { return evaluate_notingroup(pamh, user, right); } -- cgit v1.2.3