From 83c344ee5a5eb4796e435bce897b83cae3465243 Mon Sep 17 00:00:00 2001 From: Matthew Luckam Date: Wed, 17 Jan 2024 17:24:40 -0500 Subject: 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 Signed-off-by: Dmitry V. Levin 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 --- modules/pam_access/access.conf.5.xml | 10 ++++-- modules/pam_access/pam_access.c | 61 +++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 6 deletions(-) (limited to 'modules/pam_access') 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 @@ The second field, the users/group - 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 ALL (which always matches). To differentiate user entries from group entries, group entries should be written - with brackets, e.g. (group). + with brackets, e.g. (group) or (gid). @@ -175,6 +175,12 @@ -:root:ALL + + A user with uid 1003 and a group with gid + 1000 should be allowed to get access + from all other sources. + + +:(1000) 1003:ALL User foo and members of netgroup admins should be allowed to get access 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; } -- cgit v1.2.3