Date: Tue, 25 Nov 2014 09:47:16 +0000 (UTC) From: Dag-Erling Smørgrav <des@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r275020 - head/lib/libc/net Message-ID: <201411250947.sAP9lGRG053890@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: des Date: Tue Nov 25 09:47:15 2014 New Revision: 275020 URL: https://svnweb.freebsd.org/changeset/base/275020 Log: The fallback flag in nsdispatch prevents the fallback implementation of getgroupmembership() from invoking the correct backend in the compat case. Replace it with a nesting depth counter so it only blocks one level (the first is the group -> group_compat translation, the second is the actual backend). This is one of two bugs that break getgrouplist() in the compat case, the second being that the backend's own getgroupmembership() method is ignored. Unfortunately, that is not easily fixable without a redesign of our nss implementation (which is also needed to implement the +@group syntax in /etc/passwd). PR: 190055 MFC after: 1 week Modified: head/lib/libc/net/nsdispatch.c Modified: head/lib/libc/net/nsdispatch.c ============================================================================== --- head/lib/libc/net/nsdispatch.c Tue Nov 25 08:39:46 2014 (r275019) +++ head/lib/libc/net/nsdispatch.c Tue Nov 25 09:47:15 2014 (r275020) @@ -132,14 +132,17 @@ static void *nss_cache_cycle_preventio #endif /* - * When this is set to 1, nsdispatch won't use nsswitch.conf - * but will consult the 'defaults' source list only. - * NOTE: nested fallbacks (when nsdispatch calls fallback functions, - * which in turn calls nsdispatch, which should call fallback - * function) are not supported + * We keep track of nsdispatch() nesting depth in dispatch_depth. When a + * fallback method is invoked from nsdispatch(), we temporarily set + * fallback_depth to the current dispatch depth plus one. Subsequent + * calls at that exact depth will run in fallback mode (restricted to the + * same source as the call that was handled by the fallback method), while + * calls below that depth will be handled normally, allowing fallback + * methods to perform arbitrary lookups. */ struct fb_state { - int fb_dispatch; + int dispatch_depth; + int fallback_depth; }; static void fb_endstate(void *); NSS_TLS_HANDLING(fb); @@ -613,6 +616,7 @@ _nsdispatch(void *retval, const ns_dtab void *mdata; int isthreaded, serrno, i, result, srclistsize; struct fb_state *st; + int saved_depth; #ifdef NS_CACHING nss_cache_data cache_data; @@ -644,7 +648,8 @@ _nsdispatch(void *retval, const ns_dtab result = NS_UNAVAIL; goto fin; } - if (st->fb_dispatch == 0) { + ++st->dispatch_depth; + if (st->dispatch_depth > st->fallback_depth) { dbt = vector_search(&database, _nsmap, _nsmapsize, sizeof(*_nsmap), string_compare); fb_method = nss_method_lookup(NSSRC_FALLBACK, database, @@ -713,12 +718,13 @@ _nsdispatch(void *retval, const ns_dtab break; } else { if (fb_method != NULL) { - st->fb_dispatch = 1; + saved_depth = st->fallback_depth; + st->fallback_depth = st->dispatch_depth + 1; va_start(ap, defaults); result = fb_method(retval, (void *)srclist[i].name, ap); va_end(ap); - st->fb_dispatch = 0; + st->fallback_depth = saved_depth; } else nss_log(LOG_DEBUG, "%s, %s, %s, not found, " "and no fallback provided", @@ -750,6 +756,7 @@ _nsdispatch(void *retval, const ns_dtab if (isthreaded) (void)_pthread_rwlock_unlock(&nss_lock); + --st->dispatch_depth; fin: errno = serrno; return (result);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411250947.sAP9lGRG053890>