diff options
author | bushman <bushman@FreeBSD.org> | 2007-12-12 10:08:03 +0000 |
---|---|---|
committer | bushman <bushman@FreeBSD.org> | 2007-12-12 10:08:03 +0000 |
commit | b02556dae5c4b2e396b5bee2c663fe38f28d369b (patch) | |
tree | c40928e3eb8bab77c816a763945d3d4a10c59962 /lib/libc/net/nsdispatch.c | |
parent | b52b3d4702084768bfb2db0f76743d7a3b993690 (diff) | |
download | FreeBSD-src-b02556dae5c4b2e396b5bee2c663fe38f28d369b.zip FreeBSD-src-b02556dae5c4b2e396b5bee2c663fe38f28d369b.tar.gz |
Implementing 'fallback' nsswitch source. 'fallback' source is used
when particular function can't be found in nsswitch-module. For
example, getgrouplist(3) will use module-supplied 'getgroupmembership'
function (which can work in an optimal way for such source as LDAP) and
will fall back to the stanard iterate-through-all-groups implementation
otherwise.
PR: ports/114655
Submitted by: Michael Hanselmann <freebsd AT hansmi DOT ch>
Reviewed by: brooks (mentor)
Diffstat (limited to 'lib/libc/net/nsdispatch.c')
-rw-r--r-- | lib/libc/net/nsdispatch.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/libc/net/nsdispatch.c b/lib/libc/net/nsdispatch.c index ad3f208..7f30e4f 100644 --- a/lib/libc/net/nsdispatch.c +++ b/lib/libc/net/nsdispatch.c @@ -136,6 +136,15 @@ static void *nss_cache_cycle_prevention_func = NULL; #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 + */ +static int fallback_dispatch = 0; + +/* * Attempt to spew relatively uniform messages to syslog. */ #define nss_log(level, fmt, ...) \ @@ -600,7 +609,7 @@ _nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database, va_list ap; const ns_dbt *dbt; const ns_src *srclist; - nss_method method; + nss_method method, fb_method; void *mdata; int isthreaded, serrno, i, result, srclistsize; @@ -609,6 +618,9 @@ _nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database, nss_cache_data *cache_data_p; int cache_flag; #endif + + dbt = NULL; + fb_method = NULL; isthreaded = __isthreaded; serrno = errno; @@ -624,8 +636,13 @@ _nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database, result = NS_UNAVAIL; goto fin; } - dbt = vector_search(&database, _nsmap, _nsmapsize, sizeof(*_nsmap), - string_compare); + if (fallback_dispatch == 0) { + dbt = vector_search(&database, _nsmap, _nsmapsize, sizeof(*_nsmap), + string_compare); + fb_method = nss_method_lookup(NSSRC_FALLBACK, database, + method_name, disp_tab, &mdata); + } + if (dbt != NULL) { srclist = dbt->srclist; srclistsize = dbt->srclistsize; @@ -684,6 +701,12 @@ _nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database, if (result & (srclist[i].flags)) break; + } else if (fb_method != NULL) { + fallback_dispatch = 1; + va_start(ap, defaults); + result = fb_method(retval, (void *)srclist[i].name, ap); + va_end(ap); + fallback_dispatch = 0; } } |