*/
#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 int
internal_function
-__nss_shadow_nonlocal_lookup(service_user **ni, const char *fct_name,
- void **fctp)
+__nss_shadow_nonlocal_lookup2(service_user **ni, const char *fct_name,
+ const char *fct2_name, void **fctp)
{
if (__nss_shadow_nonlocal_database == NULL
&& __nss_database_lookup("shadow_nonlocal", NULL, NULL,
*ni = __nss_shadow_nonlocal_database;
*fctp = __nss_lookup_function(*ni, fct_name);
+ if (*fctp == NULL && fct2_name != NULL)
+ *fctp = __nss_lookup_function(*ni, fct2_name);
return 0;
}
+static bool spent_initialized = false;
static service_user *spent_startp, *spent_nip;
static void *spent_fct_start;
static union {
{
enum nss_status status;
const struct walk_nss w = {
- .lookup = &__nss_shadow_nonlocal_lookup, .fct_name = "setspent",
+ .lookup2 = &__nss_shadow_nonlocal_lookup2, .fct_name = "setspent",
.status = &status
};
const __typeof__(&_nss_nonlocal_setspent) self = NULL;
if (status != NSS_STATUS_SUCCESS)
return status;
- if (spent_fct_start == NULL)
- __nss_shadow_nonlocal_lookup(&spent_startp, spent_fct_name,
- &spent_fct_start);
+ if (!spent_initialized) {
+ __nss_shadow_nonlocal_lookup2(&spent_startp, spent_fct_name, NULL,
+ &spent_fct_start);
+ __sync_synchronize();
+ spent_initialized = true;
+ }
spent_nip = spent_startp;
spent_fct.ptr = spent_fct_start;
return NSS_STATUS_SUCCESS;
{
enum nss_status status;
const struct walk_nss w = {
- .lookup = &__nss_shadow_nonlocal_lookup, .fct_name = "endspent",
+ .lookup2 = &__nss_shadow_nonlocal_lookup2, .fct_name = "endspent",
.status = &status
};
const __typeof__(&_nss_nonlocal_endspent) self = NULL;
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)
if (status == NSS_STATUS_SUCCESS)
return NSS_STATUS_SUCCESS;
- } while (__nss_next(&spent_nip, spent_fct_name, &spent_fct.ptr, status, 0) == 0);
+ } while (__nss_next2(&spent_nip, spent_fct_name, NULL, &spent_fct.ptr,
+ status, 0) == 0);
spent_nip = NULL;
return NSS_STATUS_NOTFOUND;
{
enum nss_status status;
const struct walk_nss w = {
- .lookup = __nss_shadow_nonlocal_lookup, .fct_name = "getspnam_r",
+ .lookup2 = __nss_shadow_nonlocal_lookup2, .fct_name = "getspnam_r",
.status = &status, .errnop = errnop
};
const __typeof__(&_nss_nonlocal_getspnam_r) self = NULL;