summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorSerghei Anicheev <serghei.anicheev@gmail.com>2020-02-18 21:07:02 +1100
committerGitHub <noreply@github.com>2020-02-18 11:07:02 +0100
commitf07a873240de53e07897d4ef9d1d3fd0c28fe7bb (patch)
treede3502f32098fc8e723522af05ba3d63c9a490e1 /modules
parenta96e66f788b1460a8ef4c2883207d4474b829d10 (diff)
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)
Diffstat (limited to 'modules')
-rw-r--r--modules/pam_succeed_if/pam_succeed_if.8.xml12
-rw-r--r--modules/pam_succeed_if/pam_succeed_if.c30
2 files changed, 29 insertions, 13 deletions
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 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><option>user ingroup group</option></term>
+ <term><option>user ingroup group[:group:....]</option></term>
<listitem>
- <para>User is in given group.</para>
+ <para>User is in given group(s).</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>user notingroup group</option></term>
+ <term><option>user notingroup group[:group:....]</option></term>
<listitem>
- <para>User is not in given group.</para>
+ <para>User is not in given group(s).</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -271,10 +271,10 @@
<title>EXAMPLES</title>
<para>
To emulate the behaviour of <emphasis>pam_wheel</emphasis>, 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:
</para>
<programlisting>
-auth required pam_succeed_if.so quiet user ingroup wheel
+auth required pam_succeed_if.so quiet user ingroup wheel:root
</programlisting>
<para>
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);
}