diff --git a/lib/libc/net/nsdispatch.c b/lib/libc/net/nsdispatch.c --- a/lib/libc/net/nsdispatch.c +++ b/lib/libc/net/nsdispatch.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -124,10 +125,10 @@ #ifdef NS_CACHING /* - * Cache lookup cycle prevention function - if !NULL then no cache lookups + * Cache lookup cycle prevention symbol - if !NULL then no cache lookups * will be made */ -static void *nss_cache_cycle_prevention_func = NULL; +static void *nss_cache_cycle_prevention_sym = NULL; #endif /* @@ -394,8 +395,8 @@ #ifdef NS_CACHING handle = libc_dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); if (handle != NULL) { - nss_cache_cycle_prevention_func = dlsym(handle, - "_nss_cache_cycle_prevention_function"); + nss_cache_cycle_prevention_sym = dlsym(handle, + "_nss_cache_cycle_prevention_symbol"); dlclose(handle); } #endif @@ -641,6 +642,13 @@ nss_cache_data cache_data; nss_cache_data *cache_data_p; int cache_flag; + bool seen_cache; + bool is_nscd; + + seen_cache = 0; + cache_flag = 0; + cache_data_p = NULL; + is_nscd = nss_cache_cycle_prevention_sym != NULL; #endif dbt = NULL; @@ -685,19 +693,28 @@ srclistsize++; } + for (i = 0; i < srclistsize; i++) { #ifdef NS_CACHING - cache_data_p = NULL; - cache_flag = 0; + bool is_cache; + + is_cache = strcmp(srclist[i].name, NSSRC_CACHE) == 0; + + if (is_cache) { + seen_cache = 1; + + if (is_nscd) { + /* don't try to call nscd inside nscd */ + continue; + } + } #endif - for (i = 0; i < srclistsize; i++) { result = NS_NOTFOUND; method = nss_method_lookup(srclist[i].name, database, method_name, disp_tab, &mdata); if (method != NULL) { #ifdef NS_CACHING - if (strcmp(srclist[i].name, NSSRC_CACHE) == 0 && - nss_cache_cycle_prevention_func == NULL) { + if (is_cache) { #ifdef NS_STRICT_LIBC_EID_CHECKING if (issetugid() != 0) continue; @@ -733,8 +750,6 @@ va_end(ap); #endif /* NS_CACHING */ - if (result & (srclist[i].flags)) - break; } else { if (fb_method != NULL) { saved_depth = st->fallback_depth; @@ -749,10 +764,12 @@ "and no fallback provided", srclist[i].name, database, method_name); } + if (result & (srclist[i].flags)) + break; } #ifdef NS_CACHING - if (cache_data_p != NULL && + if (!is_nscd && seen_cache && cache_data_p != NULL && (result & (NS_NOTFOUND | NS_SUCCESS)) && cache_flag == 0) { va_start(ap, defaults); if (result == NS_SUCCESS) {