aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2020-02-18 11:26:56 +0000
committerCy Schubert <cy@FreeBSD.org>2020-02-18 11:26:56 +0000
commit0d960f73792a445b1cb703675a03263b36239b5d (patch)
tree3b6bba4367db10046f5eeba8fcd71195d6400e86 /lib
parentf47effabd5235973e5e0959da4b013ef03f24338 (diff)
downloadsrc-0d960f73792a445b1cb703675a03263b36239b5d.tar.gz
src-0d960f73792a445b1cb703675a03263b36239b5d.zip
When pam_login_access(5) fails to match a username it attempts to
match the primary group a user belongs to. This commit extends the match to secondary groups a user belongs to as well, just as the Linux pam_access(5) does. Approved by: des (implicit, blanket)
Notes
Notes: svn path=/head/; revision=358066
Diffstat (limited to 'lib')
-rw-r--r--lib/libpam/modules/pam_login_access/login_access.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/lib/libpam/modules/pam_login_access/login_access.c b/lib/libpam/modules/pam_login_access/login_access.c
index 059667ab2de2..3f74190d8925 100644
--- a/lib/libpam/modules/pam_login_access/login_access.c
+++ b/lib/libpam/modules/pam_login_access/login_access.c
@@ -17,10 +17,12 @@ static char sccsid[] = "%Z% %M% %I% %E% %U%";
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <netdb.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -174,6 +176,9 @@ static int
user_match(const char *tok, const char *string)
{
struct group *group;
+ struct passwd *passwd;
+ gid_t *grouplist;
+ int ngroups = NGROUPS;
int i;
/*
@@ -186,10 +191,37 @@ user_match(const char *tok, const char *string)
return (netgroup_match(tok + 1, (char *) 0, string));
} else if (string_match(tok, string)) { /* ALL or exact match */
return (YES);
- } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */
- for (i = 0; group->gr_mem[i]; i++)
- if (strcasecmp(string, group->gr_mem[i]) == 0)
+ } else {
+ if ((passwd = getpwnam(string)) == NULL)
+ return (NO);
+ errno = 0;
+ if ((group = getgrnam(tok)) == NULL) {/* try group membership */
+ if (errno != 0) {
+ syslog(LOG_ERR, "getgrnam() failed for %s: %s", string, strerror(errno));
+ } else {
+ syslog(LOG_NOTICE, "group not found: %s", string);
+ }
+ return (NO);
+ }
+ errno = 0;
+ if ((grouplist = calloc(ngroups, sizeof(gid_t))) == NULL) {
+ if (errno == ENOMEM) {
+ syslog(LOG_ERR, "cannot allocate memory for grouplist: %s", string);
+ }
+ return (NO);
+ }
+ if (getgrouplist(string, passwd->pw_gid, grouplist, &ngroups) != 0) {
+ syslog(LOG_ERR, "getgrouplist() failed for %s", string);
+ free(grouplist);
+ return (NO);
+ }
+ for (i = 0; i < ngroups; i++) {
+ if (grouplist[i] == group->gr_gid) {
+ free(grouplist);
return (YES);
+ }
+ }
+ free(grouplist);
}
return (NO);
}