aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen/getnetgrent.c
diff options
context:
space:
mode:
authorJonathan Chen <jon@FreeBSD.org>2005-07-22 22:20:26 +0000
committerJonathan Chen <jon@FreeBSD.org>2005-07-22 22:20:26 +0000
commitc5a096e0e09eb6c54aa2ba22d6728959a8750a55 (patch)
tree32d46843dd2781bb7b6b3cb2b3de5913073e5e90 /lib/libc/gen/getnetgrent.c
parentaf8418dcb173f43263c7539d4ed93d068a6dbde8 (diff)
downloadsrc-c5a096e0e09eb6c54aa2ba22d6728959a8750a55.tar.gz
src-c5a096e0e09eb6c54aa2ba22d6728959a8750a55.zip
fix innetgr() returning false positives and negatives when reverse netgroup
matching is used. PR: 35506 MFC after: 3 days
Notes
Notes: svn path=/head/; revision=148317
Diffstat (limited to 'lib/libc/gen/getnetgrent.c')
-rw-r--r--lib/libc/gen/getnetgrent.c117
1 files changed, 63 insertions, 54 deletions
diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c
index 25ec5214a701..abc318529ef0 100644
--- a/lib/libc/gen/getnetgrent.c
+++ b/lib/libc/gen/getnetgrent.c
@@ -305,22 +305,44 @@ _listmatch(const char *list, const char *group, int len)
}
static int
-_buildkey(char *key, const char *str, const char *dom, int *rotation)
+_revnetgr_lookup(char* lookupdom, char* map, const char* str,
+ const char* dom, const char* group)
{
- (*rotation)++;
- if (*rotation > 4)
- return(0);
- switch(*rotation) {
- case(1): sprintf((char *)key, "%s.%s", str, dom ? dom : "*");
- break;
- case(2): sprintf((char *)key, "%s.*", str);
- break;
- case(3): sprintf((char *)key, "*.%s", dom ? dom : "*");
- break;
- case(4): sprintf((char *)key, "*.*");
- break;
+ int y, rv, rot;
+ char key[MAXHOSTNAMELEN];
+ char *result;
+ int resultlen;
+
+ for (rot = 0; ; rot++) {
+ switch (rot) {
+ case(0): snprintf(key, MAXHOSTNAMELEN, "%s.%s",
+ str, dom?dom:lookupdom);
+ break;
+ case(1): snprintf(key, MAXHOSTNAMELEN, "%s.*",
+ str);
+ break;
+ case(2): snprintf(key, MAXHOSTNAMELEN, "*.%s",
+ dom?dom:lookupdom);
+ break;
+ case(3): snprintf(key, MAXHOSTNAMELEN, "*.*");
+ break;
+ default: return(0);
+ }
+ y = yp_match(lookupdom, map, key, strlen(key), &result,
+ &resultlen);
+ if (y == 0) {
+ rv = _listmatch(result, group, resultlen);
+ free(result);
+ if (rv) return(1);
+ } else if (y != YPERR_KEY) {
+ /*
+ * If we get an error other than 'no
+ * such key in map' then something is
+ * wrong and we should stop the search.
+ */
+ return(-1);
+ }
}
- return(1);
}
#endif
@@ -331,11 +353,6 @@ int
innetgr(const char *group, const char *host, const char *user, const char *dom)
{
char *hst, *usr, *dm;
-#ifdef YP
- char *result;
- int resultlen;
- int rv;
-#endif
/* Sanity check */
if (group == NULL || !strlen(group))
@@ -350,44 +367,36 @@ innetgr(const char *group, const char *host, const char *user, const char *dom)
/*
* If we're in NIS-only mode, do the search using
* NIS 'reverse netgroup' lookups.
+ *
+ * What happens with 'reverse netgroup' lookups:
+ *
+ * 1) try 'reverse netgroup' lookup
+ * 1.a) if host is specified and user is null:
+ * look in netgroup.byhost
+ * (try host.domain, host.*, *.domain or *.*)
+ * if found, return yes
+ * 1.b) if user is specified and host is null:
+ * look in netgroup.byuser
+ * (try host.domain, host.*, *.domain or *.*)
+ * if found, return yes
+ * 1.c) if both host and user are specified,
+ * don't do 'reverse netgroup' lookup. It won't work.
+ * 1.d) if neither host ane user are specified (why?!?)
+ * don't do 'reverse netgroup' lookup either.
+ * 2) if domain is specified and 'reverse lookup' is done:
+ * 'reverse lookup' was authoritative. bye bye.
+ * 3) otherwise, too bad, try it the slow way.
*/
- if (_use_only_yp) {
- char _key[MAXHOSTNAMELEN];
- int rot = 0, y = 0;
-
+ if (_use_only_yp && (host == NULL) != (user == NULL)) {
+ int ret;
if(yp_get_default_domain(&_netgr_yp_domain))
return(0);
- while(_buildkey(_key, user ? user : host, dom, &rot)) {
- y = yp_match(_netgr_yp_domain, user? "netgroup.byuser":
- "netgroup.byhost", _key, strlen(_key), &result,
- &resultlen);
- if (y) {
- /*
- * If we get an error other than 'no
- * such key in map' then something is
- * wrong and we should stop the search.
- */
- if (y != YPERR_KEY)
- break;
- } else {
- rv = _listmatch(result, group, resultlen);
- free(result);
- if (rv)
- return(1);
- else
- return(0);
- }
- }
- /*
- * Couldn't match using NIS-exclusive mode. If the error
- * was YPERR_MAP, then the failure happened because there
- * was no netgroup.byhost or netgroup.byuser map. The odds
- * are we are talking to a Sun NIS+ server in YP emulation
- * mode; if this is the case, then we have to do the check
- * the 'old-fashioned' way by grovelling through the netgroup
- * map and resolving memberships on the fly.
- */
- if (y != YPERR_MAP)
+ ret = _revnetgr_lookup(_netgr_yp_domain,
+ host?"netgroup.byhost":"netgroup.byuser",
+ host?host:user, dom, group);
+ if (ret == 1)
+ return(1);
+ else if (ret == 0 && dom != NULL)
return(0);
}