svn commit: r285317 - stable/10/lib/libc/net
Dag-Erling Smørgrav
des at FreeBSD.org
Thu Jul 9 13:30:38 UTC 2015
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);
More information about the svn-src-all
mailing list