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).
This commit is contained in:
Bill Paul 1995-03-19 06:16:03 +00:00
parent 9346bafa46
commit 409495f6c7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7149

View file

@ -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')