Date: Thu, 9 Jul 2015 13:30:37 +0000 (UTC) From: Dag-Erling Smørgrav <des@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r285317 - stable/10/lib/libc/net Message-ID: <201507091330.t69DUb83050072@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: des Date: Thu Jul 9 13:30:37 2015 New Revision: 285317 URL: https://svnweb.freebsd.org/changeset/base/285317 Log: MFH (r275020): partial fix for getgrouplist() in group_compat case PR: 190055 Approved by: re (marius) Modified: stable/10/lib/libc/net/nsdispatch.c Directory Properties: stable/10/ (props changed) Modified: stable/10/lib/libc/net/nsdispatch.c ============================================================================== --- stable/10/lib/libc/net/nsdispatch.c Thu Jul 9 13:23:29 2015 (r285316) +++ stable/10/lib/libc/net/nsdispatch.c Thu Jul 9 13:30:37 2015 (r285317) @@ -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); @@ -616,6 +619,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; @@ -647,7 +651,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, @@ -716,12 +721,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", @@ -753,6 +759,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?201507091330.t69DUb83050072>