From d454389cc2c86709d8d97b3bf2119e5bacccf82e Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Sat, 2 Sep 1995 04:08:55 +0000 Subject: [PATCH] getpwent.c: turn the code that checks the override caches into a seperate function to avoid duplication. Also fix getpwent() a small bit to properly handle the case where the magic NIS '+' entry appears before the end of the password file. getgrent.c: be a little more SunOS-ish. Make it look like the NIS group map is 'inserted' at the the point(s) where the magic NIS '+' entry/entries appear. getgrent: fix a file descriptor leak: remember to close the netgroup file after we determine that we're using NIS-only innetgr() lookups. --- lib/libc/gen/getgrent.c | 9 ++- lib/libc/gen/getnetgrent.c | 9 ++- lib/libc/gen/getpwent.c | 135 ++++++++++++++++++------------------- 3 files changed, 79 insertions(+), 74 deletions(-) diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index 3a4a067b9648..0d393bee96f9 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -69,8 +69,10 @@ getgrent() #ifdef YP if (_gr_stepping_yp) { - return (_nextypgroup(&_gr_group) ? &_gr_group : 0); + if (_nextypgroup(&_gr_group)) + return(&_gr_group); } +tryagain: #endif if (!grscan(0, 0, NULL)) @@ -80,7 +82,10 @@ getgrent() _getypgroup(&_gr_group, &_gr_group.gr_name[1], "group.byname"); } else if(_gr_group.gr_name[0] == '+') { - return (_nextypgroup(&_gr_group) ? &_gr_group : 0); + if (!_nextypgroup(&_gr_group)) + goto tryagain; + else + return(&_gr_group); } #endif return(&_gr_group); diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c index 572a93a38825..3301b7664658 100644 --- a/lib/libc/gen/getnetgrent.c +++ b/lib/libc/gen/getnetgrent.c @@ -90,7 +90,7 @@ static char sccsid[] = "@(#)getnetgrent.c 8.1 (Berkeley) 6/4/93"; #include #include static char *_netgr_yp_domain; -static int _use_only_yp; +int _use_only_yp; static int _netgr_yp_enabled; static int _yp_innetgr; #endif @@ -163,6 +163,8 @@ setnetgrent(group) strcmp(group, grouphead.grname)) { endnetgrent(); #ifdef YP + /* Presumed guilty until proven innocent. */ + _use_only_yp = 0; /* * IF /etc/netgroup doesn't exist or is empty, * use NIS exclusively. @@ -187,8 +189,11 @@ setnetgrent(group) * lookup and we're in NIS-only mode, short-circuit * parse_netgroup() and cut directly to the chase. */ - if (_use_only_yp && _yp_innetgr) + if (_use_only_yp && _yp_innetgr) { + /* dohw! */ + fclose(netf); return; + } #else if (netf = fopen(_PATH_NETGROUP, "r")) { #endif diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 83ef1ac539c7..605ecac10779 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -70,8 +70,10 @@ struct _pw_cache { static int _pluscnt, _minuscnt; static struct _pw_cache *_plushead = NULL, *_minushead = NULL; static void _createcaches(), _freecaches(); +static int _scancaches(char *); static int _yp_enabled; /* set true when yp enabled */ static int _pw_stepping_yp; /* set true when stepping thru map */ +static int _yp_done; #endif static int __hashpw(), __initdb(); @@ -92,11 +94,14 @@ getpwent() #ifdef YP if(_pw_stepping_yp) { _pw_passwd = _pw_copy; - return (_nextyppass(&_pw_passwd) ? &_pw_passwd : 0); + if (_nextyppass(&_pw_passwd)) + return (&_pw_passwd); + else + _yp_done = 1; } -#else -tryagain: #endif +tryagain: + ++_pw_keynum; bf[0] = _PW_KEYBYNUM; bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); @@ -107,7 +112,10 @@ getpwent() #ifdef YP if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { _pw_copy = _pw_passwd; - return (_nextyppass(&_pw_passwd) ? &_pw_passwd : 0); + if (_yp_done || !_nextyppass(&_pw_passwd)) + goto tryagain; + else + return (&_pw_passwd); } #else /* Ignore YP password file entries when YP is disabled. */ @@ -197,7 +205,7 @@ setpassent(stayopen) { _pw_keynum = 0; #ifdef YP - _pw_stepping_yp = 0; + _pw_stepping_yp = _yp_done = 0; #endif _pw_stayopen = stayopen; return(1); @@ -208,7 +216,7 @@ setpwent() { _pw_keynum = 0; #ifdef YP - _pw_stepping_yp = 0; + _pw_stepping_yp = _yp_done = 0; #endif _pw_stayopen = 0; return(1); @@ -219,7 +227,7 @@ endpwent() { _pw_keynum = 0; #ifdef YP - _pw_stepping_yp = 0; + _pw_stepping_yp = _yp_done = 0; #endif if (_pw_db) { (void)(_pw_db->close)(_pw_db); @@ -322,6 +330,7 @@ _createcaches() struct _namelist *n, *namehead; char *user, *host, *domain; struct group *grp; + extern int ___use_only_yp; /* * Assume that the database has already been initialized @@ -404,7 +413,7 @@ _createcaches() key.size = 1; if (!(_pw_db->get)(_pw_db, &key, &data, 0)) { _minuscnt = (int)*((char *)data.data); - for (i = 0; i < _minuscnt; i++) { + for (i = _minuscnt; i > -1; i--) { bf[0] = _PW_KEYMINUSBYNUM; bcopy(&i, bf + 1, sizeof(i) + 1); key.size = (sizeof(i)) + 1; @@ -439,6 +448,8 @@ _createcaches() namehead->next = NULL; } } + /* Save just the name */ + m->pw_entry.pw_name = strdup(_pw_passwd.pw_name); m->namelist = namehead; m->next = _minushead; _minushead = m; @@ -492,6 +503,40 @@ struct _namelist *n; _pluscnt = _minuscnt = 0; } +static int _scancaches(user) +char *user; +{ + register struct _pw_cache *m, *p; + register struct _namelist *n; + + if (_minuscnt && _minushead) { + m = _minushead; + while (m) { + n = m->namelist; + while (n) { + if (!strcmp(n->name,user) || *n->name == '\0') + return (1); + n = n->next; + } + m = m->next; + } + } + if (_pluscnt && _plushead) { + p = _plushead; + while (p) { + n = p->namelist; + while (n) { + if (!strcmp(n->name, user) || *n->name == '\0') + bcopy((char *)&p->pw_entry, + (char *)&_pw_passwd, sizeof(p->pw_entry)); + n = n->next; + } + p = p->next; + } + } + return(0); +} + static int _pw_breakout_yp(struct passwd *pw, char *result, int master) { @@ -600,9 +645,7 @@ _getyppass(struct passwd *pw, const char *name, const char *map) int resultlen; char mastermap[1024]; int gotmaster = 0; - struct _pw_cache *m, *p; - struct _namelist *n; - char user[UT_NAMESIZE]; + char user[UT_NAMESIZE+2]; if(!_pw_yp_domain) { if(yp_get_default_domain(&_pw_yp_domain)) @@ -629,34 +672,11 @@ _getyppass(struct passwd *pw, const char *name, const char *map) strcpy(resultbuf, result); sprintf (user, "%.*s", (strchr(result, ':') - result), result); _pw_passwd.pw_fields = -1; /* Impossible value */ - if (_minuscnt && _minushead) { - m = _minushead; - while (m) { - n = m->namelist; - while (n) { - if (!strcmp(n->name,user) || *n->name == '\0') { - free(result); - return (0); - } - n = n->next; - } - m = m->next; - } - } - if (_pluscnt && _plushead) { - p = _plushead; - while (p) { - n = p->namelist; - while (n) { - if (!strcmp(n->name, user) || *n->name == '\0') - bcopy((char *)&p->pw_entry, - (char *)&_pw_passwd, sizeof(p->pw_entry)); - n = n->next; - } - p = p->next; - } - } - free(result); + if (_scancaches((char *)&user)) { + free(result); + return(0); + } else + free(result); /* No hits in the plus or minus lists: Bzzt! reject. */ if (_pw_passwd.pw_fields == -1) return(0); @@ -675,9 +695,7 @@ _nextyppass(struct passwd *pw) int rv; char *map = "passwd.byname"; int gotmaster = 0; - struct _pw_cache *m, *p; - struct _namelist *n; - char user[UT_NAMESIZE]; + char user[UT_NAMESIZE+2]; if(!_pw_yp_domain) { if(yp_get_default_domain(&_pw_yp_domain)) @@ -720,34 +738,11 @@ _nextyppass(struct passwd *pw) strcpy(resultbuf, result); sprintf(user, "%.*s", (strchr(result, ':') - result), result); _pw_passwd.pw_fields = -1; /* Impossible value */ - if (_minuscnt && _minushead) { - m = _minushead; - while (m) { - n = m->namelist; - while (n) { - if (!strcmp(n->name, user) || *n->name == '\0') { - free(result); - goto tryagain; - } - n = n->next; - } - m = m->next; - } - } - if (_pluscnt && _plushead) { - p = _plushead; - while (p) { - n = p->namelist; - while (n) { - if (!strcmp(n->name, user) || *n->name == '\0') - bcopy((char *)&p->pw_entry, - (char*)&_pw_passwd, sizeof(p->pw_entry)); - n = n->next; - } - p = p->next; - } - } - free(result); + if (_scancaches((char *)&user)) { + free(result); + goto tryagain; + } else + free(result); /* No plus or minus hits: Bzzzt! reject. */ if (_pw_passwd.pw_fields == -1) goto tryagain;