diff options
author | wpaul <wpaul@FreeBSD.org> | 1995-03-24 05:46:47 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1995-03-24 05:46:47 +0000 |
commit | 946e0fba44d43f6f80e015eca2bf1205f304aee3 (patch) | |
tree | 10fd58723e66cbffa4e2e64a5a7852a9954cad81 /lib/libc | |
parent | 5ece83c427b5b00cfe870c57d90626384ad586f7 (diff) | |
download | FreeBSD-src-946e0fba44d43f6f80e015eca2bf1205f304aee3.zip FreeBSD-src-946e0fba44d43f6f80e015eca2bf1205f304aee3.tar.gz |
As per Justin T. Gibbs's request, agument the +@netgroup/-@netgroup
remapping mechanism in the following manner: if given an entry +@foo
and there is no netgroup named 'foo,' try searching for a regular
user group called 'foo' and build the cache using the members of
group 'foo' instead. If both a netgroup 'foo' and a user group 'foo'
exist, the 'foo' netgroup takes precedence, since we're primarily
interested in netgroup matching anyway.
This allows access control schemes based on ordinary user groups
(which are also available via NIS) rather than netgroups, since
netgroups on some systems are limited in really brain-damaged ways.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/getpwent.c | 108 |
1 files changed, 72 insertions, 36 deletions
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 452aa21..af93478 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -288,18 +288,23 @@ __hashpw(key) #ifdef YP /* - * Build special +@netgroup and -@netgroup caches. We handle ordinary - * +user/-user translations too, since there's no other way to have it - * work right in all situations. The +user/-user stuff is somewhat - * non-standard -- I don't think any other OSes use it -- but handling - * it here is simple, so why not. This also lets us have just one + * Build special +@netgroup and -@netgroup caches. We also handle ordinary + * +user/-user entries, *and* +@group/-@group entries, which are special + * cases of the +@netgroup/-@netgroup substitutions: if we can't find + * netgroup 'foo', we look for a regular user group called 'foo' and + * match against that instead. The netgroup takes precedence since the + * +group/-group support is basically just a hack to make Justin T. Gibbs + * happy. :) Sorting out all the funny business here lets us have a * yp_enabled flag with a simple on or off value instead of the somewhat * bogus setup we had before. + * * We cache everything here in one shot so that we only have to scan - * each netgroup once. The alternative is to use innetgr() inside the + * each netgroup/group once. The alternative is to use innetgr() inside the * NIS lookup functions, which would make retrieving the whole password - * database though getpwent() very slow. + * database though getpwent() very slow. +user/-user entries are treated + * like @groups/@netgroups with only one member. */ +#include <grp.h> static void _createcaches() { @@ -310,6 +315,7 @@ _createcaches() struct _pw_cache *p, *m; struct _namelist *n, *namehead; char *user, *host, *domain; + struct group *grp; /* * Assume that the database has already been initialized @@ -319,7 +325,7 @@ _createcaches() if (!_yp_enabled) return; /* - * For the plus lists, we have to store both the linked list of + * For the plus list, we have to store both the linked list of * names and the +entries from the password database so we can * do the substitution later if we find a match. */ @@ -334,15 +340,36 @@ _createcaches() key.size = (sizeof(i)) + 1; if (__hashpw(&key)) { p = (struct _pw_cache *)malloc(sizeof (struct _pw_cache)); - if (_pw_passwd.pw_name[1]) + if (strlen(_pw_passwd.pw_name) > 2 && _pw_passwd.pw_name[1] == '@') { setnetgrent(_pw_passwd.pw_name+2); - namehead = NULL; - while(getnetgrent(&host, &user, &domain)) { - n = (struct _namelist *)malloc(sizeof (struct _namelist)); - n->name = strdup(user); - n->next = namehead; - namehead = n; + namehead = NULL; + while(getnetgrent(&host, &user, &domain)) { + n = (struct _namelist *)malloc(sizeof (struct _namelist)); + n->name = strdup(user); + n->next = namehead; + namehead = n; + } + /* + * If netgroup 'foo' doesn't exist, + * try group 'foo' instead. + */ + if (namehead == NULL && (grp = getgrnam(_pw_passwd.pw_name+2)) != NULL) { + while(*grp->gr_mem) { + n = (struct _namelist *)malloc(sizeof (struct _namelist)); + n->name = strdup(*grp->gr_mem); + n->next = namehead; + namehead = n; + grp->gr_mem++; + } + } + } else { + if (_pw_passwd.pw_name[1] != '@') { + namehead = (struct _namelist *)malloc(sizeof (struct _namelist)); + namehead->name = strdup(_pw_passwd.pw_name+1); + namehead->next = NULL; + } } + p->namelist = namehead; p->pw_entry.pw_name = strdup(_pw_passwd.pw_name); p->pw_entry.pw_passwd = strdup(_pw_passwd.pw_passwd); p->pw_entry.pw_uid = _pw_passwd.pw_uid; @@ -354,12 +381,6 @@ _createcaches() p->pw_entry.pw_dir = strdup(_pw_passwd.pw_dir); p->pw_entry.pw_shell = strdup(_pw_passwd.pw_shell); p->pw_entry.pw_fields = _pw_passwd.pw_fields; - if (_pw_passwd.pw_name[1] != '@') { - p->namelist = (struct _namelist *)malloc(sizeof (struct _namelist)); - p->namelist->name = strdup(_pw_passwd.pw_name+1); - p->namelist->next = NULL; - } else - p->namelist = namehead; p->next = _plushead; _plushead = p; } @@ -367,8 +388,8 @@ _createcaches() } /* - * All we need for the minuslist are the usernames. - * The actual -entries can be ignored since no substitution + * All we need for the minuslist is the usernames. + * The actual -entries data can be ignored since no substitution * will be done: anybody on the minus list is treated like a * non-person. */ @@ -383,21 +404,36 @@ _createcaches() key.size = (sizeof(i)) + 1; if (__hashpw(&key)) { m = (struct _pw_cache *)malloc(sizeof (struct _pw_cache)); - if (_pw_passwd.pw_name[1]) + if (strlen (_pw_passwd.pw_name) > 2 && _pw_passwd.pw_name[1] == '@') { + namehead = NULL; setnetgrent(_pw_passwd.pw_name+2); - namehead = NULL; - while(getnetgrent(&host, &user, &domain)) { - n = (struct _namelist *)malloc(sizeof (struct _namelist)); - n->name = strdup(user); - n->next = namehead; - namehead = n; + while(getnetgrent(&host, &user, &domain)) { + n = (struct _namelist *)malloc(sizeof (struct _namelist)); + n->name = strdup(user); + n->next = namehead; + namehead = n; + } + /* + * If netgroup 'foo' doesn't exist, + * try group 'foo' instead. + */ + if (namehead == NULL && (grp = getgrnam(_pw_passwd.pw_name+2)) != NULL) { + while(*grp->gr_mem) { + n = (struct _namelist *)malloc(sizeof (struct _namelist)); + n->name = strdup(*grp->gr_mem); + n->next = namehead; + namehead = n; + grp->gr_mem++; + } + } + } else { + if (_pw_passwd.pw_name[1] != '@') { + namehead = (struct _namelist *)malloc(sizeof (struct _namelist)); + namehead->name = strdup(_pw_passwd.pw_name+1); + namehead->next = NULL; + } } - if (_pw_passwd.pw_name[1] != '@') { - m->namelist = (struct _namelist *)malloc(sizeof (struct _namelist)); - m->namelist->name = strdup(_pw_passwd.pw_name+1); - m->namelist->next = NULL; - } else - m->namelist = namehead; + m->namelist = namehead; m->next = _minushead; _minushead = m; } |