diff options
author | Matthew Luckam <mcl209@vt.edu> | 2024-01-17 17:24:40 -0500 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2024-08-13 08:00:00 +0000 |
commit | 83c344ee5a5eb4796e435bce897b83cae3465243 (patch) | |
tree | 24f94f2f77b1ad68e3a66d87ae01bf9c5f33fcb9 /modules | |
parent | 10071e284ea4a496ab97b56d477e23cf09d972ec (diff) | |
download | pam-83c344ee5a5eb4796e435bce897b83cae3465243.tar.gz pam-83c344ee5a5eb4796e435bce897b83cae3465243.tar.bz2 pam-83c344ee5a5eb4796e435bce897b83cae3465243.zip |
pam_access: support UID and GID in access.conf
Extend access.conf(5) syntax to support UID and GID in addition to
user and group names.
Co-authored-by: blueskycs2c <lili.ding@cs2c.com>
Signed-off-by: Dmitry V. Levin <ldv@strace.io>
Resolves: https://github.com/linux-pam/linux-pam/issues/114
Resolves: https://github.com/linux-pam/linux-pam/pull/186
Resolves: https://github.com/linux-pam/linux-pam/pull/601
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_access/access.conf.5.xml | 10 | ||||
-rw-r--r-- | modules/pam_access/pam_access.c | 61 |
2 files changed, 65 insertions, 6 deletions
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml index 2dc5d477..35a1a8fe 100644 --- a/modules/pam_access/access.conf.5.xml +++ b/modules/pam_access/access.conf.5.xml @@ -63,10 +63,10 @@ <para> The second field, the <replaceable>users</replaceable>/<replaceable>group</replaceable> - field, should be a list of one or more login names, group names, or + field, should be a list of one or more login names, group names, uid, gid, or <emphasis>ALL</emphasis> (which always matches). To differentiate user entries from group entries, group entries should be written - with brackets, e.g. <emphasis>(group)</emphasis>. + with brackets, e.g. <emphasis>(group)</emphasis> or <emphasis>(gid)</emphasis>. </para> <para> @@ -176,6 +176,12 @@ <para>-:root:ALL</para> <para> + A user with uid <emphasis>1003</emphasis> and a group with gid + <emphasis>1000</emphasis> should be allowed to get access + from all other sources. + </para> + <para>+:(1000) 1003:ALL</para> + <para> User <emphasis>foo</emphasis> and members of netgroup <emphasis>admins</emphasis> should be allowed to get access from all sources. This will only work if netgroup service is available. diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c index 2ab1ca94..0540176e 100644 --- a/modules/pam_access/pam_access.c +++ b/modules/pam_access/pam_access.c @@ -605,7 +605,30 @@ netgroup_match (pam_handle_t *pamh, const char *netgroup, return retval; } -/* user_match - match a username against one token */ +/* user_name_or_uid_match - match a username or user uid against one token */ +static int +user_name_or_uid_match(pam_handle_t *pamh, const char *tok, + const struct login_info *item) +{ + /* ALL or exact match of username */ + int rv = string_match(pamh, tok, item->user->pw_name, item->debug); + if (rv != NO) + return rv; + + if (tok[strspn(tok, "0123456789")] != '\0') + return NO; + + char buf[sizeof(long long) * 3 + 1]; + snprintf(buf, sizeof(buf), "%llu", + zero_extend_signed_to_ull(item->user->pw_uid)); + if (item->debug) + pam_syslog(pamh, LOG_DEBUG, "user_match: tok=%s, uid=%s", tok, buf); + + /* check for exact match of uid */ + return string_match (pamh, tok, buf, item->debug); +} + +/* user_match - match a user against one token */ static int user_match (pam_handle_t *pamh, char *tok, struct login_info *item) @@ -656,7 +679,7 @@ user_match (pam_handle_t *pamh, char *tok, struct login_info *item) hostname = item->hostname; } return (netgroup_match (pamh, tok + 1, hostname, string, item->debug)); - } else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */ + } else if ((rv=user_name_or_uid_match(pamh, tok, item)) != NO) /* ALL or exact match */ return rv; else if (item->only_new_group_syntax == NO && pam_modutil_user_in_group_nam_nam (pamh, @@ -668,6 +691,36 @@ user_match (pam_handle_t *pamh, char *tok, struct login_info *item) } +/* group_name_or_gid_match - match a group name or group gid against one token */ +static int +group_name_or_gid_match(pam_handle_t *pamh, const char *tok, + const char *usr, int debug) +{ + /* check for exact match of group name */ + if (pam_modutil_user_in_group_nam_nam(pamh, usr, tok) != NO) + return YES; + + if (tok[strspn(tok, "0123456789")] != '\0') + return NO; + + char *endptr = NULL; + errno = 0; + unsigned long int ul = strtoul(tok, &endptr, 10); + gid_t gid = (gid_t) ul; + if (errno != 0 + || tok == endptr + || *endptr != '\0' + || (unsigned long) zero_extend_signed_to_ull(gid) != ul) { + return NO; + } + + if (debug) + pam_syslog(pamh, LOG_DEBUG, "group_match: user=%s, gid=%s", usr, tok); + + /* check for exact match of gid */ + return pam_modutil_user_in_group_nam_gid(pamh, usr, gid); +} + /* group_match - match a username against token named group */ static int @@ -684,10 +737,10 @@ group_match (pam_handle_t *pamh, char *tok, const char* usr, int debug) tok++; tok[strlen(tok) - 1] = '\0'; - if (pam_modutil_user_in_group_nam_nam(pamh, usr, tok)) + if (group_name_or_gid_match (pamh, usr, tok, debug)) return YES; - return NO; + return NO; } |