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_' \
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.*
-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])])
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
*/
#define _GNU_SOURCE
+
#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
#include <dlfcn.h>
-#include <stdio.h>
-#include <syslog.h>
#include <errno.h>
-#include <pwd.h>
#include <grp.h>
#include <nss.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
#include "nsswitch-internal.h"
#include "nonlocal.h"
return status;
}
+static bool grent_initialized = false;
static service_user *grent_startp, *grent_nip;
static void *grent_fct_start;
static union {
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;
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;
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;
#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) {
#define _GNU_SOURCE
+
#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
#include <dlfcn.h>
-#include <stdio.h>
-#include <syslog.h>
#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
#include <nss.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
#include "nsswitch-internal.h"
#include "nonlocal.h"
}
+static bool pwent_initialized = false;
static service_user *pwent_startp, *pwent_nip;
static void *pwent_fct_start;
static union {
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;
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;
*/
#define _GNU_SOURCE
+
#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
#include <dlfcn.h>
-#include <stdio.h>
-#include <syslog.h>
#include <errno.h>
-#include <shadow.h>
#include <nss.h>
+#include <shadow.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
#include "nsswitch-internal.h"
#include "nonlocal.h"
}
+static bool spent_initialized = false;
static service_user *spent_startp, *spent_nip;
static void *spent_fct_start;
static union {
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;
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)
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;
*/
{
- 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 {
} 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;
}
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);