summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-03-19 06:16:03 +0000
committerwpaul <wpaul@FreeBSD.org>1995-03-19 06:16:03 +0000
commit42a3c01e4dc2cc1277ae548b67328a7fc289f071 (patch)
treefa7499943d2791fdd9caa89a92e81fb8c3e6e381
parentdff6bf2b1c31946e18d2307b624bbd4ae6ba368b (diff)
downloadFreeBSD-src-42a3c01e4dc2cc1277ae548b67328a7fc289f071.zip
FreeBSD-src-42a3c01e4dc2cc1277ae548b67328a7fc289f071.tar.gz
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).
-rw-r--r--lib/libc/gen/getnetgrent.c75
1 files 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')
OpenPOWER on IntegriCloud