From 42a3c01e4dc2cc1277ae548b67328a7fc289f071 Mon Sep 17 00:00:00 2001 From: wpaul Date: Sun, 19 Mar 1995 06:16:03 +0000 Subject: Two major changes: - Added support for reading netgroups from NIS/YP in addition to the local /etc/netgroups file. (Note that SunOS and many other systems only support reading netgroups via NIS, which is a bit odd.) - Fix Evil Null Pointer Dereferences From Hell (tm) that caused parse_netgrp() to SEGV when expanding netgroups that include references to other netgroups. Funny how nobody else noticed this. This is the first step in implimenting +@netgroup substitution in getpwent.c and any other places that could use it and don't already support it (which is probably everywhere). --- lib/libc/gen/getnetgrent.c | 75 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c index cc70c96..df2164e 100644 --- a/lib/libc/gen/getnetgrent.c +++ b/lib/libc/gen/getnetgrent.c @@ -83,6 +83,11 @@ int getnetgrent(), innetgr(); #define LINSIZ 1024 /* Length of netgroup file line */ +#ifdef YP +static int _netgr_yp_stepping; +static int _netgr_yp_enabled; +#endif + /* * setnetgrent() * Parse the netgroup file looking for the netgroup and build the list @@ -109,6 +114,9 @@ setnetgrent(group) } } nextgrp = grouphead.gr; +#ifdef YP + _netgr_yp_stepping = 0; +#endif } /* @@ -164,6 +172,9 @@ endnetgrent() free((char *)ogp); } grouphead.gr = (struct netgrp *)0; +#ifdef YP + _netgr_yp_stepping = 0; +#endif } /* @@ -217,7 +228,8 @@ parse_netgrp(group) } else lp->l_parsed = 1; pos = lp->l_line; - while (*pos != '\0') { + /* Watch for null pointer dereferences, dammit! */ + while (pos != NULL && *pos != '\0') { if (*pos == '(') { grp = (struct netgrp *)malloc(sizeof (struct netgrp)); bzero((char *)grp, sizeof (struct netgrp)); @@ -248,8 +260,10 @@ parse_netgrp(group) if (parse_netgrp(spos)) return (1); } - while (*pos == ' ' || *pos == ',' || *pos == '\t') - pos++; + /* Watch for null pointer dereferences, dammit! */ + if (pos != NULL) + while (*pos == ' ' || *pos == ',' || *pos == '\t') + pos++; } return (0); errout: @@ -271,9 +285,62 @@ read_for_group(group) int cont; struct linelist *lp; char line[LINSIZ + 1]; +#ifdef YP + static char *_netgr_yp_domain; + static char *key, *lastkey; + static int keylen; + char *result; + int resultlen; + /* XXX There's a small amount of magic at work here: + * once the '+' has been found that tells us to use NIS, + * we have to avoid checking the actual /etc/netgroups file + * again until we're finished reading the netgroup map. + * Therefore, we count on the second half of the test in + * the while() loop not being executed so long as the first + * part evaluates to true. + */ + while (_netgr_yp_enabled || fgets(line, LINSIZ, netf) != NULL) { + if (_netgr_yp_enabled) { + if(!_netgr_yp_domain) + if(yp_get_default_domain(&_netgr_yp_domain)) { + _netgr_yp_enabled = 0; + _netgr_yp_stepping = 0; + continue; + } + if (_netgr_yp_stepping) { + lastkey = key; + if(yp_next(_netgr_yp_domain, "netgroup", key, + keylen, &key, &keylen, &result, &resultlen)) { + _netgr_yp_enabled = 0; + _netgr_yp_stepping = 0; + free(lastkey); + continue; + } + free(lastkey); + } else { + if(key) free(key); + if (yp_first(_netgr_yp_domain, "netgroup", + &key, &keylen, &result, &resultlen)) { + _netgr_yp_enabled = 0; + _netgr_yp_stepping = 0; + continue; + } + _netgr_yp_stepping = 1; + } + sprintf(line, "%s %s", key, result); + free(result); + } +#else while (fgets(line, LINSIZ, netf) != NULL) { - pos = line; +#endif + pos = (char *)&line; +#ifdef YP + if (*pos == '+') { + _netgr_yp_enabled = 1; + continue; + } +#endif if (*pos == '#') continue; while (*pos == ' ' || *pos == '\t') -- cgit v1.1