From: Anders Kaseorg Date: Thu, 13 Jun 2013 03:24:34 +0000 (-0400) Subject: Merge tag '2.1' into debian X-Git-Tag: debian/2.1-0debathena1~4 X-Git-Url: http://andersk.mit.edu/gitweb/nss_nonlocal.git/commitdiff_plain/27dad42dc185c20117c403f95cf3e288701c4132?hp=b07434b7ce587d806abf9dc4542d4b5654f341f3 Merge tag '2.1' into debian nss_nonlocal 2.1 --- diff --git a/Makefile.am b/Makefile.am index a22eb6e..6d7ba8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ lib_LTLIBRARIES = libnss_nonlocal.la libnss_nonlocal_la_SOURCES = \ nonlocal-passwd.c nonlocal-group.c nonlocal-shadow.c \ - nonlocal.h nsswitch-internal.h + nonlocal.h nsswitch-internal.h walk_nss.h libnss_nonlocal_la_LDFLAGS = \ -version-info 2:0:0 \ -export-symbols-regex '^_nss_nonlocal_' \ @@ -10,3 +10,6 @@ libnss_nonlocal_la_LDFLAGS = \ install-exec-hook: rm -f $(DESTDIR)$(libdir)/libnss_nonlocal.so rm -f $(DESTDIR)$(libdir)/libnss_nonlocal.la + +uninstall-local: + rm -f $(DESTDIR)$(libdir)/libnss_nonlocal.so.* diff --git a/configure.ac b/configure.ac index 115ea61..6718d77 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([nss_nonlocal], [2.0], [andersk@mit.edu]) +AC_INIT([nss_nonlocal], [2.1], [andersk@mit.edu]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([-Wall -Werror foreign]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) @@ -6,7 +6,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_PREFIX_DEFAULT([/]) AC_DISABLE_STATIC AC_PROG_CC -AC_PROG_INSTALL +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL AC_HEADER_STDBOOL diff --git a/nonlocal-group.c b/nonlocal-group.c index 5b4dd7d..57f01e2 100644 --- a/nonlocal-group.c +++ b/nonlocal-group.c @@ -24,18 +24,20 @@ */ #define _GNU_SOURCE + #include -#include -#include -#include -#include #include -#include -#include #include -#include #include #include +#include +#include +#include +#include +#include +#include +#include + #include "nsswitch-internal.h" #include "nonlocal.h" @@ -169,6 +171,7 @@ get_local_group(const char *name, struct group *grp, char **buffer, int *errnop) return status; } +static bool grent_initialized = false; static service_user *grent_startp, *grent_nip; static void *grent_fct_start; static union { @@ -193,9 +196,12 @@ _nss_nonlocal_setgrent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (grent_fct_start == NULL) + if (!grent_initialized) { __nss_group_nonlocal_lookup(&grent_startp, grent_fct_name, &grent_fct_start); + __sync_synchronize(); + grent_initialized = true; + } grent_nip = grent_startp; grent_fct.ptr = grent_fct_start; return NSS_STATUS_SUCCESS; @@ -207,7 +213,7 @@ _nss_nonlocal_endgrent(void) enum nss_status status; const struct walk_nss w = { .lookup = &__nss_group_nonlocal_lookup, .fct_name = "endgrent", - .status = &status + .status = &status, .all_values = 1, }; const __typeof__(&_nss_nonlocal_endgrent) self = NULL; @@ -355,7 +361,7 @@ _nss_nonlocal_initgroups_dyn(const char *user, gid_t group, long int *start, enum nss_status status; const struct walk_nss w = { .lookup = &__nss_group_nonlocal_lookup, .fct_name = "initgroups_dyn", - .status = &status, .errnop = errnop + .status = &status, .all_values = 1, .errnop = errnop }; const __typeof__(&_nss_nonlocal_initgroups_dyn) self = NULL; @@ -444,7 +450,9 @@ _nss_nonlocal_initgroups_dyn(const char *user, gid_t group, long int *start, #define args (user, group, start, size, groupsp, limit, errnop) #include "walk_nss.h" #undef args - if (status != NSS_STATUS_SUCCESS) + if (status == NSS_STATUS_NOTFOUND || status == NSS_STATUS_UNAVAIL) + return NSS_STATUS_SUCCESS; + else if (status != NSS_STATUS_SUCCESS) return status; for (; in < *start; ++in) { diff --git a/nonlocal-passwd.c b/nonlocal-passwd.c index 7529d9b..41ea498 100644 --- a/nonlocal-passwd.c +++ b/nonlocal-passwd.c @@ -25,18 +25,19 @@ #define _GNU_SOURCE + #include -#include -#include -#include -#include #include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include + #include "nsswitch-internal.h" #include "nonlocal.h" @@ -161,6 +162,7 @@ get_nonlocal_passwd(const char *name, struct passwd *pwd, char **buffer, } +static bool pwent_initialized = false; static service_user *pwent_startp, *pwent_nip; static void *pwent_fct_start; static union { @@ -185,9 +187,12 @@ _nss_nonlocal_setpwent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (pwent_fct_start == NULL) + if (!pwent_initialized) { __nss_passwd_nonlocal_lookup(&pwent_startp, pwent_fct_name, &pwent_fct_start); + __sync_synchronize(); + pwent_initialized = true; + } pwent_nip = pwent_startp; pwent_fct.ptr = pwent_fct_start; return NSS_STATUS_SUCCESS; @@ -199,7 +204,7 @@ _nss_nonlocal_endpwent(void) enum nss_status status; const struct walk_nss w = { .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "endpwent", - .status = &status + .status = &status, .all_values = 1, }; const __typeof__(&_nss_nonlocal_endpwent) self = NULL; diff --git a/nonlocal-shadow.c b/nonlocal-shadow.c index ab8f442..98142e1 100644 --- a/nonlocal-shadow.c +++ b/nonlocal-shadow.c @@ -23,17 +23,17 @@ */ #define _GNU_SOURCE + #include -#include -#include -#include -#include #include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include #include "nsswitch-internal.h" #include "nonlocal.h" @@ -58,6 +58,7 @@ __nss_shadow_nonlocal_lookup(service_user **ni, const char *fct_name, } +static bool spent_initialized = false; static service_user *spent_startp, *spent_nip; static void *spent_fct_start; static union { @@ -82,9 +83,12 @@ _nss_nonlocal_setspent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (spent_fct_start == NULL) + if (!spent_initialized) { __nss_shadow_nonlocal_lookup(&spent_startp, spent_fct_name, &spent_fct_start); + __sync_synchronize(); + spent_initialized = true; + } spent_nip = spent_startp; spent_fct.ptr = spent_fct_start; return NSS_STATUS_SUCCESS; @@ -113,6 +117,11 @@ _nss_nonlocal_getspent_r(struct spwd *pwd, char *buffer, size_t buflen, int *errnop) { enum nss_status status; + + char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV); + if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0') + return NSS_STATUS_UNAVAIL; + if (spent_nip == NULL) { status = _nss_nonlocal_setspent(0); if (status != NSS_STATUS_SUCCESS) diff --git a/nonlocal.h b/nonlocal.h index 9574ff8..7b8ca2f 100644 --- a/nonlocal.h +++ b/nonlocal.h @@ -49,6 +49,7 @@ typedef bool _Bool; struct walk_nss { enum nss_status *status; + int all_values; int (*lookup)(service_user **ni, const char *fct_name, void **fctp) internal_function; const char *fct_name; diff --git a/walk_nss.h b/walk_nss.h index 93af177..24cf4c5 100644 --- a/walk_nss.h +++ b/walk_nss.h @@ -24,8 +24,9 @@ */ { - static service_user *startp = NULL; - static void *fct_start = NULL; + static bool initialized = false; + static service_user *startp; + static void *fct_start; service_user *nip; union { @@ -34,10 +35,13 @@ } fct; int old_errno = errno; - if (fct_start == NULL && - w.lookup(&startp, w.fct_name, &fct_start) != 0) { - *w.status = NSS_STATUS_UNAVAIL; - goto walk_nss_out; + if (!initialized) { + if (w.lookup(&startp, w.fct_name, &fct_start) != 0) { + *w.status = NSS_STATUS_UNAVAIL; + goto walk_nss_out; + } + __sync_synchronize(); + initialized = true; } nip = startp; @@ -75,7 +79,8 @@ } goto walk_nss_morebuf; } - } while (__nss_next(&nip, w.fct_name, &fct.ptr, *w.status, 0) == 0); + } while (__nss_next(&nip, w.fct_name, &fct.ptr, *w.status, w.all_values) == + 0); if (w.buf != NULL && *w.status != NSS_STATUS_SUCCESS) { free(*w.buf);