summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.developer1
-rw-r--r--lib/nss_wrapper/nss_wrapper.c2744
-rw-r--r--lib/nss_wrapper/nss_wrapper.h171
-rw-r--r--lib/nss_wrapper/testsuite.c958
-rw-r--r--lib/nss_wrapper/wscript111
-rw-r--r--lib/nss_wrapper/wscript_build10
-rw-r--r--wscript1
7 files changed, 2460 insertions, 1536 deletions
diff --git a/configure.developer b/configure.developer
index 50336702095..b8cf6d68b10 100755
--- a/configure.developer
+++ b/configure.developer
@@ -2,5 +2,4 @@
`dirname $0`/configure -C \
--enable-developer \
--enable-socket-wrapper \
- --enable-nss-wrapper \
"$@"
diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c
index 8767fbfd892..7c5a413ee78 100644
--- a/lib/nss_wrapper/nss_wrapper.c
+++ b/lib/nss_wrapper/nss_wrapper.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) Stefan Metzmacher 2007 <metze@samba.org>
* Copyright (C) Guenther Deschner 2009 <gd@samba.org>
+ * Copyright (C) Andreas Schneider 2013 <asn@samba.org>
*
* All rights reserved.
*
@@ -32,120 +33,229 @@
* SUCH DAMAGE.
*/
-#ifdef _SAMBA_BUILD_
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
-/* defining this gives us the posix getpwnam_r() calls on solaris
- Thanks to heimdal for this */
+/*
+ * Defining _POSIX_PTHREAD_SEMANTICS before including pwd.h and grp.h gives us
+ * the posix getpwnam_r(), getpwuid_r(), getgrnam_r and getgrgid_r calls on
+ * Solaris
+ */
#ifndef _POSIX_PTHREAD_SEMANTICS
#define _POSIX_PTHREAD_SEMANTICS
#endif
-#define NSS_WRAPPER_NOT_REPLACE
-#include "../replace/replace.h"
-#include "system/passwd.h"
-#include "system/filesys.h"
-#include "../nsswitch/nsstest.h"
+#include <pwd.h>
+#include <grp.h>
+
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <dlfcn.h>
-#else /* _SAMBA_BUILD_ */
+#if defined(HAVE_NSS_H)
+/* Linux and BSD */
+#include <nss.h>
-#error nss_wrapper_only_supported_in_samba_yet
+typedef enum nss_status NSS_STATUS;
+#elif defined(HAVE_NSS_COMMON_H)
+/* Solaris */
+#include <nss_common.h>
+#include <nss_dbdefs.h>
+#include <nsswitch.h>
+
+typedef nss_status_t NSS_STATUS;
+
+# define NSS_STATUS_SUCCESS NSS_SUCCESS
+# define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+# define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+# define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+#else
+# error "No nsswitch support detected"
+#endif
+#ifndef PTR_DIFF
+#define PTR_DIFF(p1, p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
#endif
#ifndef _PUBLIC_
#define _PUBLIC_
#endif
-/* not all systems have _r functions... */
-#ifndef HAVE_GETPWNAM_R
-#define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
-#endif
-#ifndef HAVE_GETPWUID_R
-#define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
+#ifndef EAI_NODATA
+#define EAI_NODATA EAI_NONAME
#endif
-#ifndef HAVE_GETPWENT_R
-#define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
+
+#ifndef EAI_ADDRFAMILY
+#define EAI_ADDRFAMILY EAI_FAMILY
#endif
-#ifndef HAVE_GETGRNAM_R
-#define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
+
+#ifndef __STRING
+#define __STRING(x) #x
#endif
-#ifndef HAVE_GETGRGID_R
-#define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
+
+#ifndef __STRINGSTRING
+#define __STRINGSTRING(x) __STRING(x)
#endif
-#ifndef HAVE_GETGRENT_R
-#define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
+
+#ifndef __LINESTR__
+#define __LINESTR__ __STRINGSTRING(__LINE__)
#endif
-/* not all systems have getgrouplist */
-#ifndef HAVE_GETGROUPLIST
-#define getgrouplist(user, group, groups, ngroups) 0
+#ifndef __location__
+#define __location__ __FILE__ ":" __LINESTR__
#endif
-/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
- * for now */
-#define REWRITE_CALLS
+/* GCC have printf type attribute check. */
+#ifdef HAVE_ATTRIBUTE_PRINTF_FORMAT
+#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#else
+#define PRINTF_ATTRIBUTE(a,b)
+#endif /* HAVE_ATTRIBUTE_PRINTF_FORMAT */
-#ifdef REWRITE_CALLS
+#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
+#define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
+#else
+#define DESTRUCTOR_ATTRIBUTE
+#endif /* HAVE_DESTRUCTOR_ATTRIBUTE */
-#define real_getpwnam getpwnam
-#define real_getpwnam_r getpwnam_r
-#define real_getpwuid getpwuid
-#define real_getpwuid_r getpwuid_r
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
-#define real_setpwent setpwent
-#define real_getpwent getpwent
-#define real_getpwent_r getpwent_r
-#define real_endpwent endpwent
+enum nwrap_dbglvl_e {
+ NWRAP_LOG_ERROR = 0,
+ NWRAP_LOG_WARN,
+ NWRAP_LOG_DEBUG,
+ NWRAP_LOG_TRACE
+};
-/*
-#define real_getgrlst getgrlst
-#define real_getgrlst_r getgrlst_r
-#define real_initgroups_dyn initgroups_dyn
-*/
-#define real_initgroups initgroups
-#define real_getgrouplist getgrouplist
-
-#define real_getgrnam getgrnam
-#define real_getgrnam_r getgrnam_r
-#define real_getgrgid getgrgid
-#define real_getgrgid_r getgrgid_r
-
-#define real_setgrent setgrent
-#define real_getgrent getgrent
-#define real_getgrent_r getgrent_r
-#define real_endgrent endgrent
+#ifdef NDEBUG
+# define NWRAP_LOG(...)
+#else
-#endif
+static void nwrap_log(enum nwrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
+# define NWRAP_LOG(dbglvl, ...) nwrap_log((dbglvl), __func__, __VA_ARGS__)
-#if 0
-# ifdef DEBUG
-# define NWRAP_ERROR(args) DEBUG(0, args)
-# else
-# define NWRAP_ERROR(args) printf args
-# endif
+static void nwrap_log(enum nwrap_dbglvl_e dbglvl,
+ const char *func,
+ const char *format, ...)
+{
+ char buffer[1024];
+ va_list va;
+ const char *d;
+ unsigned int lvl = 0;
+ int pid = getpid();
+
+ d = getenv("NSS_WRAPPER_DEBUGLEVEL");
+ if (d != NULL) {
+ lvl = atoi(d);
+ }
+
+ va_start(va, format);
+ vsnprintf(buffer, sizeof(buffer), format, va);
+ va_end(va);
+
+ if (lvl >= dbglvl) {
+ switch (dbglvl) {
+ case NWRAP_LOG_ERROR:
+ fprintf(stderr,
+ "NWRAP_ERROR(%d) - %s: %s\n",
+ pid, func, buffer);
+ break;
+ case NWRAP_LOG_WARN:
+ fprintf(stderr,
+ "NWRAP_WARN(%d) - %s: %s\n",
+ pid, func, buffer);
+ break;
+ case NWRAP_LOG_DEBUG:
+ fprintf(stderr,
+ "NWRAP_DEBUG(%d) - %s: %s\n",
+ pid, func, buffer);
+ break;
+ case NWRAP_LOG_TRACE:
+ fprintf(stderr,
+ "NWRAP_TRACE(%d) - %s: %s\n",
+ pid, func, buffer);
+ break;
+ }
+ }
+}
+#endif /* NDEBUG NWRAP_LOG */
+
+struct nwrap_libc_fns {
+ struct passwd *(*_libc_getpwnam)(const char *name);
+ int (*_libc_getpwnam_r)(const char *name, struct passwd *pwd,
+ char *buf, size_t buflen, struct passwd **result);
+ struct passwd *(*_libc_getpwuid)(uid_t uid);
+ int (*_libc_getpwuid_r)(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result);
+ void (*_libc_setpwent)(void);
+ struct passwd *(*_libc_getpwent)(void);
+#ifdef HAVE_SOLARIS_GETPWENT_R
+ struct passwd *(*_libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen);
#else
-#define NWRAP_ERROR(args)
+ int (*_libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
#endif
-
-#if 0
-# ifdef DEBUG
-# define NWRAP_DEBUG(args) DEBUG(0, args)
-# else
-# define NWRAP_DEBUG(args) printf args
-# endif
+ void (*_libc_endpwent)(void);
+ int (*_libc_initgroups)(const char *user, gid_t gid);
+ struct group *(*_libc_getgrnam)(const char *name);
+ int (*_libc_getgrnam_r)(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);
+ struct group *(*_libc_getgrgid)(gid_t gid);
+ int (*_libc_getgrgid_r)(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);
+ void (*_libc_setgrent)(void);
+ struct group *(*_libc_getgrent)(void);
+#ifdef HAVE_SOLARIS_GETGRENT_R
+ struct group *(*_libc_getgrent_r)(struct group *group, char *buf, size_t buflen);
#else
-#define NWRAP_DEBUG(args)
+ int (*_libc_getgrent_r)(struct group *group, char *buf, size_t buflen, struct group **result);
#endif
+ void (*_libc_endgrent)(void);
+ int (*_libc_getgrouplist)(const char *user, gid_t group, gid_t *groups, int *ngroups);
-#if 0
-# ifdef DEBUG
-# define NWRAP_VERBOSE(args) DEBUG(0, args)
-# else
-# define NWRAP_VERBOSE(args) printf args
-# endif
-#else
-#define NWRAP_VERBOSE(args)
+ void (*_libc_sethostent)(int stayopen);
+ struct hostent *(*_libc_gethostent)(void);
+ void (*_libc_endhostent)(void);
+
+ struct hostent *(*_libc_gethostbyname)(const char *name);
+#ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */
+ struct hostent *(*_libc_gethostbyname2)(const char *name, int af);
+#endif
+ struct hostent *(*_libc_gethostbyaddr)(const void *addr, socklen_t len, int type);
+
+ int (*_libc_getaddrinfo)(const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res);
+ int (*_libc_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags);
+ int (*_libc_gethostname)(char *name, size_t len);
+#ifdef HAVE_GETHOSTBYNAME_R
+ int (*_libc_gethostbyname_r)(const char *name,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop);
+#endif
+#ifdef HAVE_GETHOSTBYADDR_R
+ int (*_libc_gethostbyaddr_r)(const void *addr, socklen_t len, int type,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop);
#endif
+};
struct nwrap_module_nss_fns {
NSS_STATUS (*_nss_getpwnam_r)(const char *name, struct passwd *result, char *buffer,
@@ -213,6 +323,11 @@ struct nwrap_ops {
void (*nw_endgrent)(struct nwrap_backend *b);
};
+/* Public prototypes */
+
+bool nss_wrapper_enabled(void);
+bool nss_wrapper_hosts_enabled(void);
+
/* prototypes for files backend */
@@ -328,10 +443,18 @@ struct nwrap_ops nwrap_module_ops = {
.nw_endgrent = nwrap_module_endgrent,
};
+struct nwrap_libc {
+ void *handle;
+ void *nsl_handle;
+ void *sock_handle;
+ struct nwrap_libc_fns *fns;
+};
+
struct nwrap_main {
const char *nwrap_switch;
int num_backends;
struct nwrap_backend *backends;
+ struct nwrap_libc *libc;
};
struct nwrap_main *nwrap_main_global;
@@ -372,8 +495,550 @@ struct nwrap_gr {
struct nwrap_cache __nwrap_cache_gr;
struct nwrap_gr nwrap_gr_global;
+static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line);
+static void nwrap_he_unload(struct nwrap_cache *nwrap);
+
+struct nwrap_addrdata {
+ unsigned char host_addr[16]; /* IPv4 or IPv6 address */
+ char *h_addr_ptrs[2]; /* host_addr pointer + NULL */
+};
+
+struct nwrap_entdata {
+ struct nwrap_addrdata *addr;
+ struct hostent ht;
+};
+
+struct nwrap_he {
+ struct nwrap_cache *cache;
+
+ struct nwrap_entdata *list;
+ int num;
+ int idx;
+};
+
+struct nwrap_cache __nwrap_cache_he;
+struct nwrap_he nwrap_he_global;
+
+
+/*********************************************************
+ * NWRAP PROTOTYPES
+ *********************************************************/
+
+static void nwrap_init(void);
static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line);
static void nwrap_gr_unload(struct nwrap_cache *nwrap);
+void nwrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
+
+/*********************************************************
+ * NWRAP LIBC LOADER FUNCTIONS
+ *********************************************************/
+
+enum nwrap_lib {
+ NWRAP_LIBC,
+ NWRAP_LIBNSL,
+ NWRAP_LIBSOCKET,
+};
+
+#ifndef NDEBUG
+static const char *nwrap_str_lib(enum nwrap_lib lib)
+{
+ switch (lib) {
+ case NWRAP_LIBC:
+ return "libc";
+ case NWRAP_LIBNSL:
+ return "libnsl";
+ case NWRAP_LIBSOCKET:
+ return "libsocket";
+ }
+
+ /* Compiler would warn us about unhandled enum value if we get here */
+ return "unknown";
+}
+#endif
+
+static void *nwrap_load_lib_handle(enum nwrap_lib lib)
+{
+ int flags = RTLD_LAZY;
+ void *handle = NULL;
+ int i;
+
+#ifdef HAVE_APPLE
+ return RTLD_NEXT;
+#endif
+
+#ifdef RTLD_DEEPBIND
+ flags |= RTLD_DEEPBIND;
+#endif
+
+ switch (lib) {
+ case NWRAP_LIBNSL:
+#ifdef HAVE_LIBNSL
+ handle = nwrap_main_global->libc->nsl_handle;
+ if (handle == NULL) {
+ for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
+ char soname[256] = {0};
+
+ snprintf(soname, sizeof(soname), "libnsl.so.%d", i);
+ handle = dlopen(soname, flags);
+ }
+
+ nwrap_main_global->libc->nsl_handle = handle;
+ }
+ break;
+#endif
+ /* FALL TROUGH */
+ case NWRAP_LIBSOCKET:
+#ifdef HAVE_LIBSOCKET
+ handle = nwrap_main_global->libc->sock_handle;
+ if (handle == NULL) {
+ for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
+ char soname[256] = {0};
+
+ snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
+ handle = dlopen(soname, flags);
+ }
+
+ nwrap_main_global->libc->sock_handle = handle;
+ }
+ break;
+#endif
+ /* FALL TROUGH */
+ case NWRAP_LIBC:
+ handle = nwrap_main_global->libc->handle;
+ if (handle == NULL) {
+ for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
+ char soname[256] = {0};
+
+ snprintf(soname, sizeof(soname), "libc.so.%d", i);
+ handle = dlopen(soname, flags);
+ }
+
+ nwrap_main_global->libc->handle = handle;
+ }
+ break;
+ }
+
+ if (handle == NULL) {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Failed to dlopen library: %s\n",
+ dlerror());
+ exit(-1);
+ }
+
+ return handle;
+}
+
+static void *_nwrap_load_lib_function(enum nwrap_lib lib, const char *fn_name)
+{
+ void *handle;
+ void *func;
+
+ nwrap_init();
+
+ handle = nwrap_load_lib_handle(lib);
+
+ func = dlsym(handle, fn_name);
+ if (func == NULL) {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Failed to find %s: %s\n",
+ fn_name, dlerror());
+ exit(-1);
+ }
+
+ NWRAP_LOG(NWRAP_LOG_TRACE,
+ "Loaded %s from %s",
+ fn_name, nwrap_str_lib(lib));
+ return func;
+}
+
+#define nwrap_load_lib_function(lib, fn_name) \
+ if (nwrap_main_global->libc->fns->_libc_##fn_name == NULL) { \
+ *(void **) (&nwrap_main_global->libc->fns->_libc_##fn_name) = \
+ _nwrap_load_lib_function(lib, #fn_name); \
+ }
+
+/*
+ * IMPORTANT
+ *
+ * Functions expeciall from libc need to be loaded individually, you can't load
+ * all at once or gdb will segfault at startup. The same applies to valgrind and
+ * has probably something todo with with the linker.
+ * So we need load each function at the point it is called the first time.
+ */
+static struct passwd *libc_getpwnam(const char *name)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getpwnam);
+
+ return nwrap_main_global->libc->fns->_libc_getpwnam(name);
+}
+
+#ifdef HAVE_GETPWNAM_R
+static int libc_getpwnam_r(const char *name,
+ struct passwd *pwd,
+ char *buf,
+ size_t buflen,
+ struct passwd **result)
+{
+#ifdef HAVE___POSIX_GETPWNAM_R
+ if (nwrap_main_global->libc->fns->_libc_getpwnam_r == NULL) {
+ *(void **) (&nwrap_main_global->libc->fns->_libc_getpwnam_r) =
+ _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getpwnam_r");
+ }
+#else
+ nwrap_load_lib_function(NWRAP_LIBC, getpwnam_r);
+#endif
+
+ return nwrap_main_global->libc->fns->_libc_getpwnam_r(name,
+ pwd,
+ buf,
+ buflen,
+ result);
+}
+#endif
+
+static struct passwd *libc_getpwuid(uid_t uid)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getpwuid);
+
+ return nwrap_main_global->libc->fns->_libc_getpwuid(uid);
+}
+
+#ifdef HAVE_GETPWUID_R
+static int libc_getpwuid_r(uid_t uid,
+ struct passwd *pwd,
+ char *buf,
+ size_t buflen,
+ struct passwd **result)
+{
+#ifdef HAVE___POSIX_GETPWUID_R
+ if (nwrap_main_global->libc->fns->_libc_getpwuid_r == NULL) {
+ *(void **) (&nwrap_main_global->libc->fns->_libc_getpwuid_r) =
+ _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getpwuid_r");
+ }
+#else
+ nwrap_load_lib_function(NWRAP_LIBC, getpwuid_r);
+#endif
+
+ return nwrap_main_global->libc->fns->_libc_getpwuid_r(uid,
+ pwd,
+ buf,
+ buflen,
+ result);
+}
+#endif
+
+static void libc_setpwent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, setpwent);
+
+ nwrap_main_global->libc->fns->_libc_setpwent();
+}
+
+static struct passwd *libc_getpwent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getpwent);
+
+ return nwrap_main_global->libc->fns->_libc_getpwent();
+}
+
+#ifdef HAVE_SOLARIS_GETPWENT_R
+static struct passwd *libc_getpwent_r(struct passwd *pwdst,
+ char *buf,
+ int buflen)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getpwent_r);
+
+ return nwrap_main_global->libc->fns->_libc_getpwent_r(pwdst,
+ buf,
+ buflen);
+}
+#else /* HAVE_SOLARIS_GETPWENT_R */
+static int libc_getpwent_r(struct passwd *pwdst,
+ char *buf,
+ size_t buflen,
+ struct passwd **pwdstp)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getpwent_r);
+
+ return nwrap_main_global->libc->fns->_libc_getpwent_r(pwdst,
+ buf,
+ buflen,
+ pwdstp);
+}
+#endif /* HAVE_SOLARIS_GETPWENT_R */
+
+static void libc_endpwent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, endpwent);
+
+ nwrap_main_global->libc->fns->_libc_endpwent();
+}
+
+static int libc_initgroups(const char *user, gid_t gid)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, initgroups);
+
+ return nwrap_main_global->libc->fns->_libc_initgroups(user, gid);
+}
+
+static struct group *libc_getgrnam(const char *name)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrnam);
+
+ return nwrap_main_global->libc->fns->_libc_getgrnam(name);
+}
+
+#ifdef HAVE_GETGRNAM_R
+static int libc_getgrnam_r(const char *name,
+ struct group *grp,
+ char *buf,
+ size_t buflen,
+ struct group **result)
+{
+#ifdef HAVE___POSIX_GETGRNAM_R
+ if (nwrap_main_global->libc->fns->_libc_getgrnam_r == NULL) {
+ *(void **) (&nwrap_main_global->libc->fns->_libc_getgrnam_r) =
+ _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getgrnam_r");
+ }
+#else
+ nwrap_load_lib_function(NWRAP_LIBC, getgrnam_r);
+#endif
+
+ return nwrap_main_global->libc->fns->_libc_getgrnam_r(name,
+ grp,
+ buf,
+ buflen,
+ result);
+}
+#endif
+
+static struct group *libc_getgrgid(gid_t gid)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrgid);
+
+ return nwrap_main_global->libc->fns->_libc_getgrgid(gid);
+}
+
+#ifdef HAVE_GETGRGID_R
+static int libc_getgrgid_r(gid_t gid,
+ struct group *grp,
+ char *buf,
+ size_t buflen,
+ struct group **result)
+{
+#ifdef HAVE___POSIX_GETGRGID_R
+ if (nwrap_main_global->libc->fns->_libc_getgrgid_r == NULL) {
+ *(void **) (&nwrap_main_global->libc->fns->_libc_getgrgid_r) =
+ _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getgrgid_r");
+ }
+#else
+ nwrap_load_lib_function(NWRAP_LIBC, getgrgid_r);
+#endif
+
+ return nwrap_main_global->libc->fns->_libc_getgrgid_r(gid,
+ grp,
+ buf,
+ buflen,
+ result);
+}
+#endif
+
+static void libc_setgrent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, setgrent);
+
+ nwrap_main_global->libc->fns->_libc_setgrent();
+}
+
+static struct group *libc_getgrent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrent);
+
+ return nwrap_main_global->libc->fns->_libc_getgrent();
+}
+
+#ifdef HAVE_GETGRENT_R
+#ifdef HAVE_SOLARIS_GETGRENT_R
+static struct group *libc_getgrent_r(struct group *group,
+ char *buf,
+ size_t buflen)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrent_r);
+
+ return nwrap_main_global->libc->fns->_libc_getgrent_r(group,
+ buf,
+ buflen);
+}
+#else /* !HAVE_SOLARIS_GETGRENT_R */
+static int libc_getgrent_r(struct group *group,
+ char *buf,
+ size_t buflen,
+ struct group **result)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrent_r);
+
+ return nwrap_main_global->libc->fns->_libc_getgrent_r(group,
+ buf,
+ buflen,
+ result);
+}
+#endif /* HAVE_SOLARIS_GETGRENT_R */
+#endif /* HAVE_GETGRENT_R */
+
+static void libc_endgrent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, endgrent);
+
+ nwrap_main_global->libc->fns->_libc_endgrent();
+}
+
+#ifdef HAVE_GETGROUPLIST
+static int libc_getgrouplist(const char *user,
+ gid_t group,
+ gid_t *groups,
+ int *ngroups)
+{
+ nwrap_load_lib_function(NWRAP_LIBC, getgrouplist);
+
+ return nwrap_main_global->libc->fns->_libc_getgrouplist(user,
+ group,
+ groups,
+ ngroups);
+}
+#endif
+
+static void libc_sethostent(int stayopen)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, sethostent);
+
+ nwrap_main_global->libc->fns->_libc_sethostent(stayopen);
+}
+
+static struct hostent *libc_gethostent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostent);
+
+ return nwrap_main_global->libc->fns->_libc_gethostent();
+}
+
+static void libc_endhostent(void)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, endhostent);
+
+ nwrap_main_global->libc->fns->_libc_endhostent();
+}
+
+static struct hostent *libc_gethostbyname(const char *name)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname);
+
+ return nwrap_main_global->libc->fns->_libc_gethostbyname(name);
+}
+
+#ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */
+static struct hostent *libc_gethostbyname2(const char *name, int af)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname2);
+
+ return nwrap_main_global->libc->fns->_libc_gethostbyname2(name, af);
+}
+#endif
+
+static struct hostent *libc_gethostbyaddr(const void *addr,
+ socklen_t len,
+ int type)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyaddr);
+
+ return nwrap_main_global->libc->fns->_libc_gethostbyaddr(addr,
+ len,
+ type);
+}
+
+static int libc_gethostname(char *name, size_t len)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostname);
+
+ return nwrap_main_global->libc->fns->_libc_gethostname(name, len);
+}
+
+#ifdef HAVE_GETHOSTBYNAME_R
+static int libc_gethostbyname_r(const char *name,
+ struct hostent *ret,
+ char *buf,
+ size_t buflen,
+ struct hostent **result,
+ int *h_errnop)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname_r);
+
+ return nwrap_main_global->libc->fns->_libc_gethostbyname_r(name,
+ ret,
+ buf,
+ buflen,
+ result,
+ h_errnop);
+}
+#endif
+
+#ifdef HAVE_GETHOSTBYADDR_R
+static int libc_gethostbyaddr_r(const void *addr,
+ socklen_t len,
+ int type,
+ struct hostent *ret,
+ char *buf,
+ size_t buflen,
+ struct hostent **result,
+ int *h_errnop)
+{
+ nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyaddr_r);
+
+ return nwrap_main_global->libc->fns->_libc_gethostbyaddr_r(addr,
+ len,
+ type,
+ ret,
+ buf,
+ buflen,
+ result,
+ h_errnop);
+}
+#endif
+
+static int libc_getaddrinfo(const char *node,
+ const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ nwrap_load_lib_function(NWRAP_LIBSOCKET, getaddrinfo);
+
+ return nwrap_main_global->libc->fns->_libc_getaddrinfo(node,
+ service,
+ hints,
+ res);
+}
+
+static int libc_getnameinfo(const struct sockaddr *sa,
+ socklen_t salen,
+ char *host,
+ size_t hostlen,
+ char *serv,
+ size_t servlen,
+ int flags)
+{
+ nwrap_load_lib_function(NWRAP_LIBSOCKET, getnameinfo);
+
+ return nwrap_main_global->libc->fns->_libc_getnameinfo(sa,
+ salen,
+ host,
+ hostlen,
+ serv,
+ servlen,
+ flags);
+}
+
+/*********************************************************
+ * NWRAP NSS MODULE LOADER FUNCTIONS
+ *********************************************************/
static void *nwrap_load_module_fn(struct nwrap_backend *b,
const char *fn_name)
@@ -382,21 +1047,20 @@ static void *nwrap_load_module_fn(struct nwrap_backend *b,
char *s;
if (!b->so_handle) {
- NWRAP_ERROR(("%s: no handle\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "No handle");
return NULL;
}
if (asprintf(&s, "_nss_%s_%s", b->name, fn_name) == -1) {
- NWRAP_ERROR(("%s: out of memory\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
return NULL;
}
res = dlsym(b->so_handle, s);
if (!res) {
- NWRAP_ERROR(("%s: cannot find function %s in %s\n",
- __location__, s, b->so_path));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Cannot find function %s in %s",
+ s, b->so_path);
}
free(s);
s = NULL;
@@ -416,28 +1080,28 @@ static struct nwrap_module_nss_fns *nwrap_load_module_fns(struct nwrap_backend *
return NULL;
}
- fns->_nss_getpwnam_r = (NSS_STATUS (*)(const char *, struct passwd *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getpwnam_r");
- fns->_nss_getpwuid_r = (NSS_STATUS (*)(uid_t, struct passwd *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getpwuid_r");
- fns->_nss_setpwent = (NSS_STATUS(*)(void))
- nwrap_load_module_fn(b, "setpwent");
- fns->_nss_getpwent_r = (NSS_STATUS (*)(struct passwd *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getpwent_r");
- fns->_nss_endpwent = (NSS_STATUS(*)(void))
- nwrap_load_module_fn(b, "endpwent");
- fns->_nss_initgroups = (NSS_STATUS (*)(const char *, gid_t, long int *, long int *, gid_t **, long int, int *))
- nwrap_load_module_fn(b, "initgroups_dyn");
- fns->_nss_getgrnam_r = (NSS_STATUS (*)(const char *, struct group *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getgrnam_r");
- fns->_nss_getgrgid_r = (NSS_STATUS (*)(gid_t, struct group *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getgrgid_r");
- fns->_nss_setgrent = (NSS_STATUS(*)(void))
- nwrap_load_module_fn(b, "setgrent");
- fns->_nss_getgrent_r = (NSS_STATUS (*)(struct group *, char *, size_t, int *))
- nwrap_load_module_fn(b, "getgrent_r");
- fns->_nss_endgrent = (NSS_STATUS(*)(void))
- nwrap_load_module_fn(b, "endgrent");
+ *(void **)(&fns->_nss_getpwnam_r) =
+ nwrap_load_module_fn(b, "getpwnam_r");
+ *(void **)(&fns->_nss_getpwuid_r) =
+ nwrap_load_module_fn(b, "getpwuid_r");
+ *(void **)(&fns->_nss_setpwent) =
+ nwrap_load_module_fn(b, "setpwent");
+ *(void **)(&fns->_nss_getpwent_r) =
+ nwrap_load_module_fn(b, "getpwent_r");
+ *(void **)(&fns->_nss_endpwent) =
+ nwrap_load_module_fn(b, "endpwent");
+ *(void **)(&fns->_nss_initgroups) =
+ nwrap_load_module_fn(b, "initgroups_dyn");
+ *(void **)(&fns->_nss_getgrnam_r) =
+ nwrap_load_module_fn(b, "getgrnam_r");
+ *(void **)(&fns->_nss_getgrgid_r)=
+ nwrap_load_module_fn(b, "getgrgid_r");
+ *(void **)(&fns->_nss_setgrent) =
+ nwrap_load_module_fn(b, "setgrent");
+ *(void **)(&fns->_nss_getgrent_r) =
+ nwrap_load_module_fn(b, "getgrent_r");
+ *(void **)(&fns->_nss_endgrent) =
+ nwrap_load_module_fn(b, "endgrent");
return fns;
}
@@ -452,8 +1116,9 @@ static void *nwrap_load_module(const char *so_path)
h = dlopen(so_path, RTLD_LAZY);
if (!h) {
- NWRAP_ERROR(("%s: cannot open shared library %s\n",
- __location__, so_path));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Cannot open shared library %s",
+ so_path);
return NULL;
}
@@ -471,8 +1136,7 @@ static bool nwrap_module_init(const char *name,
*backends = (struct nwrap_backend *)realloc(*backends,
sizeof(struct nwrap_backend) * ((*num_backends) + 1));
if (!*backends) {
- NWRAP_ERROR(("%s: out of memory\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
return false;
}
@@ -498,9 +1162,27 @@ static bool nwrap_module_init(const char *name,
return true;
}
+static void nwrap_libc_init(struct nwrap_main *r)
+{
+ r->libc = malloc(sizeof(struct nwrap_libc));
+ if (r->libc == NULL) {
+ printf("Failed to allocate memory for libc");
+ exit(-1);
+ }
+ ZERO_STRUCTP(r->libc);
+
+ r->libc->fns = malloc(sizeof(struct nwrap_libc_fns));
+ if (r->libc->fns == NULL) {
+ printf("Failed to allocate memory for libc functions");
+ exit(-1);
+ }
+ ZERO_STRUCTP(r->libc->fns);
+}
+
static void nwrap_backend_init(struct nwrap_main *r)
{
- const char *winbind_so_path = getenv("NSS_WRAPPER_WINBIND_SO_PATH");
+ const char *module_so_path = getenv("NSS_WRAPPER_MODULE_SO_PATH");
+ const char *module_fn_name = getenv("NSS_WRAPPER_MODULE_FN_PREFIX");
r->num_backends = 0;
r->backends = NULL;
@@ -508,17 +1190,23 @@ static void nwrap_backend_init(struct nwrap_main *r)
if (!nwrap_module_init("files", &nwrap_files_ops, NULL,
&r->num_backends,
&r->backends)) {
- NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Failed to initialize 'files' backend");
return;
}
- if (winbind_so_path && strlen(winbind_so_path)) {
- if (!nwrap_module_init("winbind", &nwrap_module_ops, winbind_so_path,
+ if (module_so_path != NULL &&
+ module_so_path[0] != '\0' &&
+ module_fn_name != NULL &&
+ module_fn_name[0] != '\0') {
+ if (!nwrap_module_init(module_fn_name,
+ &nwrap_module_ops,
+ module_so_path,
&r->num_backends,
&r->backends)) {
- NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Failed to initialize '%s' backend",
+ module_fn_name);
return;
}
}
@@ -533,6 +1221,8 @@ static void nwrap_init(void)
nwrap_main_global = &__nwrap_main_global;
+ nwrap_libc_init(nwrap_main_global);
+
nwrap_backend_init(nwrap_main_global);
nwrap_pw_global.cache = &__nwrap_cache_pw;
@@ -550,22 +1240,49 @@ static void nwrap_init(void)
nwrap_gr_global.cache->private_data = &nwrap_gr_global;
nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line;
nwrap_gr_global.cache->unload = nwrap_gr_unload;
+
+ nwrap_he_global.cache = &__nwrap_cache_he;
+
+ nwrap_he_global.cache->path = getenv("NSS_WRAPPER_HOSTS");
+ nwrap_he_global.cache->fd = -1;
+ nwrap_he_global.cache->private_data = &nwrap_he_global;
+ nwrap_he_global.cache->parse_line = nwrap_he_parse_line;
+ nwrap_he_global.cache->unload = nwrap_he_unload;
}
-static bool nwrap_enabled(void)
+bool nss_wrapper_enabled(void)
{
nwrap_init();
- if (!nwrap_pw_global.cache->path) {
+ if (nwrap_pw_global.cache->path == NULL ||
+ nwrap_pw_global.cache->path[0] == '\0') {
return false;
}
- if (nwrap_pw_global.cache->path[0] == '\0') {
+ if (nwrap_gr_global.cache->path == NULL ||
+ nwrap_gr_global.cache->path[0] == '\0') {
return false;
}
- if (!nwrap_gr_global.cache->path) {
+
+ return true;
+}
+
+bool nss_wrapper_hosts_enabled(void)
+{
+ nwrap_init();
+
+ if (nwrap_he_global.cache->path == NULL ||
+ nwrap_he_global.cache->path[0] == '\0') {
return false;
}
- if (nwrap_gr_global.cache->path[0] == '\0') {
+
+ return true;
+}
+
+static bool nwrap_hostname_enabled(void)
+{
+ nwrap_init();
+
+ if (getenv("NSS_WRAPPER_HOSTNAME") == NULL) {
return false;
}
@@ -579,40 +1296,41 @@ static bool nwrap_parse_file(struct nwrap_cache *nwrap)
char *nline;
if (nwrap->st.st_size == 0) {
- NWRAP_DEBUG(("%s: size == 0\n",
- __location__));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "size == 0");
goto done;
}
if (nwrap->st.st_size > INT32_MAX) {
- NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
- __location__, (unsigned)nwrap->st.st_size));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Size[%u] larger than INT32_MAX",
+ (unsigned)nwrap->st.st_size);
goto failed;
}
ret = lseek(nwrap->fd, 0, SEEK_SET);
if (ret != 0) {
- NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "lseek - rc=%d\n", ret);
goto failed;
}
buf = (uint8_t *)malloc(nwrap->st.st_size + 1);
if (!buf) {
- NWRAP_ERROR(("%s: malloc failed\n",__location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
goto failed;
}
ret = read(nwrap->fd, buf, nwrap->st.st_size);
if (ret != nwrap->st.st_size) {
- NWRAP_ERROR(("%s: read(%u) gave %d\n",
- __location__, (unsigned)nwrap->st.st_size, ret));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "read(%u) rc=%d\n",
+ (unsigned)nwrap->st.st_size, ret);
goto failed;
}
buf[nwrap->st.st_size] = '\0';
nline = (char *)buf;
- while (nline && nline[0]) {
+ while (nline != NULL && nline[0] != '\0') {
char *line;
char *e;
bool ok;
@@ -631,8 +1349,6 @@ static bool nwrap_parse_file(struct nwrap_cache *nwrap)
nline = e;
}
- NWRAP_VERBOSE(("%s:'%s'\n",__location__, line));
-
if (strlen(line) == 0) {
continue;
}
@@ -672,28 +1388,30 @@ reopen:
if (nwrap->fd < 0) {
nwrap->fd = open(nwrap->path, O_RDONLY);
if (nwrap->fd < 0) {
- NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
- __location__,
- nwrap->path, nwrap->fd,
- strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Unable to open '%s' readonly %d:%s",
+ nwrap->path, nwrap->fd,
+ strerror(errno));
return;
}
- NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "Open '%s'", nwrap->path);
}
ret = fstat(nwrap->fd, &st);
if (ret != 0) {
- NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
- __location__,
- nwrap->path,
- ret, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "fstat(%s) - %d:%s",
+ nwrap->path,
+ ret,
+ strerror(errno));
return;
}
if (retried == false && st.st_nlink == 0) {
/* maybe someone has replaced the file... */
- NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
- __location__, nwrap->path));
+ NWRAP_LOG(NWRAP_LOG_TRACE,
+ "st_nlink == 0, reopen %s",
+ nwrap->path);
retried = true;
memset(&nwrap->st, 0, sizeof(nwrap->st));
close(nwrap->fd);
@@ -702,13 +1420,16 @@ reopen:
}
if (st.st_mtime == nwrap->st.st_mtime) {
- NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
- __location__, (unsigned)st.st_mtime));
+ NWRAP_LOG(NWRAP_LOG_TRACE,
+ "st_mtime[%u] hasn't changed, skip reload",
+ (unsigned)st.st_mtime);
return;
}
- NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
- __location__, (unsigned)st.st_mtime,
- (unsigned)nwrap->st.st_mtime));
+
+ NWRAP_LOG(NWRAP_LOG_TRACE,
+ "st_mtime has changed [%u] => [%u], start reload",
+ (unsigned)st.st_mtime,
+ (unsigned)nwrap->st.st_mtime);
nwrap->st = st;
@@ -716,12 +1437,11 @@ reopen:
ok = nwrap_parse_file(nwrap);
if (!ok) {
- NWRAP_ERROR(("%s: failed to reload %s\n",
- __location__, nwrap->path));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to reload %s", nwrap->path);
nwrap_files_cache_unload(nwrap);
}
- NWRAP_DEBUG(("%s: reloaded %s\n",
- __location__, nwrap->path));
+
+ NWRAP_LOG(NWRAP_LOG_TRACE, "Reloaded %s", nwrap->path);
}
/*
@@ -741,8 +1461,9 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1);
pw = (struct passwd *)realloc(nwrap_pw->list, list_size);
if (!pw) {
- NWRAP_ERROR(("%s:realloc(%u) failed\n",
- __location__, list_size));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "realloc(%u) failed",
+ (unsigned)list_size);
return false;
}
nwrap_pw->list = pw;
@@ -754,8 +1475,10 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
/* name */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s'",
+ line,
+ c);
return false;
}
*p = '\0';
@@ -763,13 +1486,12 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
pw->pw_name = c;
c = p;
- NWRAP_VERBOSE(("name[%s]\n", pw->pw_name));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]\n", pw->pw_name);
/* password */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -777,13 +1499,12 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
pw->pw_passwd = c;
c = p;
- NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]\n", pw->pw_passwd);
/* uid */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -791,29 +1512,31 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
e = NULL;
pw->pw_uid = (uid_t)strtoul(c, &e, 10);
if (c == e) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e == NULL) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e[0] != '\0') {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
c = p;
- NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "uid[%u]", pw->pw_uid);
/* gid */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -821,29 +1544,31 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
e = NULL;
pw->pw_gid = (gid_t)strtoul(c, &e, 10);
if (c == e) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e == NULL) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e[0] != '\0') {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
c = p;
- NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]\n", pw->pw_gid);
/* gecos */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -851,12 +1576,12 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
pw->pw_gecos = c;
c = p;
- NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "gecos[%s]", pw->pw_gecos);
/* dir */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:'%s'\n",__location__,c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "'%s'", c);
return false;
}
*p = '\0';
@@ -864,16 +1589,17 @@ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
pw->pw_dir = c;
c = p;
- NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "dir[%s]", pw->pw_dir);
/* shell */
pw->pw_shell = c;
- NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "shell[%s]", pw->pw_shell);
- NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
- pw->pw_name, pw->pw_passwd,
- pw->pw_uid, pw->pw_gid,
- pw->pw_gecos, pw->pw_dir, pw->pw_shell));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "Added user[%s:%s:%u:%u:%s:%s:%s]",
+ pw->pw_name, pw->pw_passwd,
+ pw->pw_uid, pw->pw_gid,
+ pw->pw_gecos, pw->pw_dir, pw->pw_shell);
nwrap_pw->num++;
return true;
@@ -905,7 +1631,7 @@ static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst,
ofs = PTR_DIFF(last + 1, first);
- if (ofs > buflen) {
+ if (ofs > (off_t) buflen) {
return ERANGE;
}
@@ -949,7 +1675,7 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1);
gr = (struct group *)realloc(nwrap_gr->list, list_size);
if (!gr) {
- NWRAP_ERROR(("%s:realloc failed\n",__location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "realloc failed");
return false;
}
nwrap_gr->list = gr;
@@ -961,8 +1687,7 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
/* name */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -970,13 +1695,12 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
gr->gr_name = c;
c = p;
- NWRAP_VERBOSE(("name[%s]\n", gr->gr_name));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]", gr->gr_name);
/* password */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -984,13 +1708,12 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
gr->gr_passwd = c;
c = p;
- NWRAP_VERBOSE(("password[%s]\n", gr->gr_passwd));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]", gr->gr_passwd);
/* gid */
p = strchr(c, ':');
if (!p) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
- __location__, line, c));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c);
return false;
}
*p = '\0';
@@ -998,28 +1721,31 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
e = NULL;
gr->gr_gid = (gid_t)strtoul(c, &e, 10);
if (c == e) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e == NULL) {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
if (e[0] != '\0') {
- NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
- __location__, line, c, strerror(errno)));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s' - %s",
+ line, c, strerror(errno));
return false;
}
c = p;
- NWRAP_VERBOSE(("gid[%u]\n", gr->gr_gid));
+ NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]", gr->gr_gid);
/* members */
gr->gr_mem = (char **)malloc(sizeof(char *));
if (!gr->gr_mem) {
- NWRAP_ERROR(("%s:calloc failed\n",__location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
return false;
}
gr->gr_mem[0] = NULL;
@@ -1041,19 +1767,23 @@ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
m_size = sizeof(char *) * (nummem+2);
m = (char **)realloc(gr->gr_mem, m_size);
if (!m) {
- NWRAP_ERROR(("%s:realloc(%u) failed\n",
- __location__, m_size));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "realloc(%zd) failed",
+ m_size);
return false;
}
gr->gr_mem = m;
gr->gr_mem[nummem] = c;
gr->gr_mem[nummem+1] = NULL;
- NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem]));
+ NWRAP_LOG(NWRAP_LOG_TRACE,
+ "member[%u]: '%s'",
+ nummem, gr->gr_mem[nummem]);
}
- NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "Added group[%s:%s:%u:] with %u members",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem);
nwrap_gr->num++;
return true;
@@ -1106,7 +1836,7 @@ static int nwrap_gr_copy_r(const struct group *src, struct group *dst,
ofsb = PTR_DIFF(last + 1, first);
ofsm = PTR_DIFF(lastm + 1, src->gr_mem);
- if ((ofsb + ofsm) > buflen) {
+ if ((ofsb + ofsm) > (off_t) buflen) {
return ERANGE;
}
@@ -1132,26 +1862,212 @@ static int nwrap_gr_copy_r(const struct group *src, struct group *dst,
return 0;
}
+static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line)
+{
+ struct nwrap_he *nwrap_he = (struct nwrap_he *)nwrap->private_data;
+ struct nwrap_entdata *ed;
+ size_t list_size;
+ bool do_aliases = true;
+ int aliases_count = 0;
+ char *p;
+ char *i;
+ char *n;
+
+ list_size = sizeof(struct nwrap_entdata) * (nwrap_he->num + 1);
+
+ ed = (struct nwrap_entdata *)realloc(nwrap_he->list, list_size);
+ if (ed == NULL) {
+ NWRAP_LOG(NWRAP_LOG_ERROR, "realloc[%zd] failed", list_size);
+ return false;
+ }
+ nwrap_he->list = ed;
+
+ /* set it to the last element */
+ ed = &(nwrap_he->list[nwrap_he->num]);
+
+ ed->addr = malloc(sizeof(struct nwrap_addrdata));
+ if (ed->addr == NULL) {
+ NWRAP_LOG(NWRAP_LOG_ERROR, "realloc[%zd] failed", list_size);
+ return false;
+ }
+
+ i = line;
+
+ /*
+ * IP
+ */
+
+ /* Walk to first char */
+ for (p = i; *p != '.' && *p != ':' && !isxdigit((int) *p); p++) {
+ if (*p == '\0') {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s'",
+ line, i);
+ return false;
+ }
+ }
+
+ for (i = p; !isspace((int)*p); p++) {
+ if (*p == '\0') {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s'",
+ line, i);
+ return false;
+ }
+ }
+
+ *p = '\0';
+
+ if (inet_pton(AF_INET, i, ed->addr->host_addr)) {
+ ed->ht.h_addrtype = AF_INET;
+ ed->ht.h_length = 4;
+#ifdef HAVE_IPV6
+ } else if (inet_pton(AF_INET6, i, ed->addr->host_addr)) {
+ ed->ht.h_addrtype = AF_INET6;
+ ed->ht.h_length = 16;
+#endif
+ } else {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s'",
+ line, i);
+
+ return false;
+ }
+
+ ed->addr->h_addr_ptrs[0] = (char *)ed->addr->host_addr;
+ ed->addr->h_addr_ptrs[1] = NULL;
+
+ ed->ht.h_addr_list = ed->addr->h_addr_ptrs;
+
+ p++;
+
+ /*
+ * FQDN
+ */
+
+ /* Walk to first char */
+ for (n = p; *p != '_' && !isalnum((int) *p); p++) {
+ if (*p == '\0') {
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Invalid line[%s]: '%s'",
+ line, n);
+
+ return false;
+ }
+ }
+
+ for (n = p; !isspace((int)*p); p++) {
+ if (*p == '\0') {
+ do_aliases = false;
+ break;
+ }
+ }
+
+ *p = '\0';
+
+ ed->ht.h_name = n;
+
+ /* glib's getent always dereferences he->h_aliases */
+ ed->ht.h_aliases = malloc(sizeof(char *));
+ if (ed->ht.h_aliases == NULL) {
+ return false;
+ }
+ ed->ht.h_aliases[0] = NULL;
+
+ /*
+ * Aliases
+ */
+ while (do_aliases) {
+ char **aliases;
+ char *a;
+
+ p++;
+
+ /* Walk to first char */
+ for (a = p; *p != '_' && !isalnum((int) *p); p++) {
+ if (*p == '\0') {
+ do_aliases = false;
+ break;
+ }
+ }
+ /* Only trailing spaces are left */
+ if (!do_aliases) {
+ break;
+ }
+
+ for (a = p; !isspace((int)*p); p++) {
+ if (*p == '\0') {
+ do_aliases = false;
+ break;
+ }
+ }
+
+ *p = '\0';
+
+ aliases = realloc(ed->ht.h_aliases, sizeof(char *) * (aliases_count + 2));
+ if (aliases == NULL) {
+ return false;
+ }
+ ed->ht.h_aliases = aliases;
+
+ aliases[aliases_count] = a;
+ aliases[aliases_count + 1] = NULL;
+
+ aliases_count++;
+ }
+
+ nwrap_he->num++;
+ return true;
+}
+
+static void nwrap_he_unload(struct nwrap_cache *nwrap)
+{
+ struct nwrap_he *nwrap_he =
+ (struct nwrap_he *)nwrap->private_data;
+ int i;
+
+ if (nwrap_he->list != NULL) {
+ for (i = 0; i < nwrap_he->num; i++) {
+ if (nwrap_he->list[i].ht.h_aliases != NULL) {
+ free(nwrap_he->list[i].ht.h_aliases);
+ }
+ if (nwrap_he->list[i].addr != NULL) {
+ free(nwrap_he->list[i].addr);
+ }
+ }
+ free(nwrap_he->list);
+ }
+
+ nwrap_he->list = NULL;
+ nwrap_he->num = 0;
+ nwrap_he->idx = 0;
+}
+
+
/* user functions */
static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b,
const char *name)
{
int i;
+ (void) b; /* unused */
+
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "Lookup user %s in files", name);
+
nwrap_files_cache_reload(nwrap_pw_global.cache);
for (i=0; i<nwrap_pw_global.num; i++) {
if (strcmp(nwrap_pw_global.list[i].pw_name, name) == 0) {
- NWRAP_DEBUG(("%s: user[%s] found\n",
- __location__, name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] found", name);
return &nwrap_pw_global.list[i];
}
- NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
- __location__, name,
- nwrap_pw_global.list[i].pw_name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "user[%s] does not match [%s]",
+ name,
+ nwrap_pw_global.list[i].pw_name);
}
- NWRAP_DEBUG(("%s: user[%s] not found\n", __location__, name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] not found\n", name);
errno = ENOENT;
return NULL;
@@ -1179,20 +2095,22 @@ static struct passwd *nwrap_files_getpwuid(struct nwrap_backend *b,
{
int i;
+ (void) b; /* unused */
+
nwrap_files_cache_reload(nwrap_pw_global.cache);
for (i=0; i<nwrap_pw_global.num; i++) {
if (nwrap_pw_global.list[i].pw_uid == uid) {
- NWRAP_DEBUG(("%s: uid[%u] found\n",
- __location__, uid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "uid[%u] found", uid);
return &nwrap_pw_global.list[i];
}
- NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
- __location__, uid,
- nwrap_pw_global.list[i].pw_uid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "uid[%u] does not match [%u]",
+ uid,
+ nwrap_pw_global.list[i].pw_uid);
}
- NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__, uid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "uid[%u] not found\n", uid);
errno = ENOENT;
return NULL;
@@ -1218,6 +2136,8 @@ static int nwrap_files_getpwuid_r(struct nwrap_backend *b,
/* user enum functions */
static void nwrap_files_setpwent(struct nwrap_backend *b)
{
+ (void) b; /* unused */
+
nwrap_pw_global.idx = 0;
}
@@ -1225,6 +2145,8 @@ static struct passwd *nwrap_files_getpwent(struct nwrap_backend *b)
{
struct passwd *pw;
+ (void) b; /* unused */
+
if (nwrap_pw_global.idx == 0) {
nwrap_files_cache_reload(nwrap_pw_global.cache);
}
@@ -1236,8 +2158,9 @@ static struct passwd *nwrap_files_getpwent(struct nwrap_backend *b)
pw = &nwrap_pw_global.list[nwrap_pw_global.idx++];
- NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
- __location__, pw->pw_name, pw->pw_uid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "return user[%s] uid[%u]",
+ pw->pw_name, pw->pw_uid);
return pw;
}
@@ -1261,6 +2184,8 @@ static int nwrap_files_getpwent_r(struct nwrap_backend *b,
static void nwrap_files_endpwent(struct nwrap_backend *b)
{
+ (void) b; /* unused */
+
nwrap_pw_global.idx = 0;
}
@@ -1268,6 +2193,10 @@ static void nwrap_files_endpwent(struct nwrap_backend *b)
static int nwrap_files_initgroups(struct nwrap_backend *b,
const char *user, gid_t group)
{
+ (void) b; /* unused */
+ (void) user; /* unused */
+ (void) group; /* used */
+
/* TODO: maybe we should also fake this... */
return EPERM;
}
@@ -1278,20 +2207,22 @@ static struct group *nwrap_files_getgrnam(struct nwrap_backend *b,
{
int i;
+ (void) b; /* unused */
+
nwrap_files_cache_reload(nwrap_gr_global.cache);
for (i=0; i<nwrap_gr_global.num; i++) {
if (strcmp(nwrap_gr_global.list[i].gr_name, name) == 0) {
- NWRAP_DEBUG(("%s: group[%s] found\n",
- __location__, name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "group[%s] found", name);
return &nwrap_gr_global.list[i];
}
- NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
- __location__, name,
- nwrap_gr_global.list[i].gr_name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "group[%s] does not match [%s]",
+ name,
+ nwrap_gr_global.list[i].gr_name);
}
- NWRAP_DEBUG(("%s: group[%s] not found\n", __location__, name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "group[%s] not found", name);
errno = ENOENT;
return NULL;
@@ -1319,20 +2250,22 @@ static struct group *nwrap_files_getgrgid(struct nwrap_backend *b,
{
int i;
+ (void) b; /* unused */
+
nwrap_files_cache_reload(nwrap_gr_global.cache);
for (i=0; i<nwrap_gr_global.num; i++) {
if (nwrap_gr_global.list[i].gr_gid == gid) {
- NWRAP_DEBUG(("%s: gid[%u] found\n",
- __location__, gid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "gid[%u] found", gid);
return &nwrap_gr_global.list[i];
}
- NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
- __location__, gid,
- nwrap_gr_global.list[i].gr_gid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "gid[%u] does not match [%u]",
+ gid,
+ nwrap_gr_global.list[i].gr_gid);
}
- NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__, gid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "gid[%u] not found", gid);
errno = ENOENT;
return NULL;
@@ -1358,6 +2291,8 @@ static int nwrap_files_getgrgid_r(struct nwrap_backend *b,
/* group enum functions */
static void nwrap_files_setgrent(struct nwrap_backend *b)
{
+ (void) b; /* unused */
+
nwrap_gr_global.idx = 0;
}
@@ -1365,6 +2300,8 @@ static struct group *nwrap_files_getgrent(struct nwrap_backend *b)
{
struct group *gr;
+ (void) b; /* unused */
+
if (nwrap_gr_global.idx == 0) {
nwrap_files_cache_reload(nwrap_gr_global.cache);
}
@@ -1376,8 +2313,9 @@ static struct group *nwrap_files_getgrent(struct nwrap_backend *b)
gr = &nwrap_gr_global.list[nwrap_gr_global.idx++];
- NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
- __location__, gr->gr_name, gr->gr_gid));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "return group[%s] gid[%u]",
+ gr->gr_name, gr->gr_gid);
return gr;
}
@@ -1401,9 +2339,189 @@ static int nwrap_files_getgrent_r(struct nwrap_backend *b,
static void nwrap_files_endgrent(struct nwrap_backend *b)
{
+ (void) b; /* unused */
+
nwrap_gr_global.idx = 0;
}
+/* hosts functions */
+static struct hostent *nwrap_files_gethostbyname(const char *name, int af)
+{
+ struct hostent *he;
+ int i;
+
+ nwrap_files_cache_reload(nwrap_he_global.cache);
+
+ for (i = 0; i < nwrap_he_global.num; i++) {
+ int j;
+
+ he = &nwrap_he_global.list[i].ht;
+
+ /* Filter by address familiy if provided */
+ if (af != AF_UNSPEC && he->h_addrtype != af) {
+ continue;
+ }
+
+ if (strcasecmp(he->h_name, name) == 0) {
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "name[%s] found", name);
+ return he;
+ }
+
+ if (he->h_aliases == NULL) {
+ continue;
+ }
+
+ for (j = 0; he->h_aliases[j] != NULL; j++) {
+ if (strcasecmp(he->h_aliases[j], name) == 0) {
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "name[%s] found",
+ name);
+ return he;
+ }
+ }
+ }
+
+ errno = ENOENT;
+ return NULL;
+}
+
+#ifdef HAVE_GETHOSTBYNAME_R
+static int nwrap_gethostbyname_r(const char *name,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop)
+{
+ *result = nwrap_files_gethostbyname(name, AF_UNSPEC);
+ if (*result != NULL) {
+ memset(buf, '\0', buflen);
+ *ret = **result;
+ return 0;
+ } else {
+ *h_errnop = h_errno;
+ return -1;
+ }
+}
+
+int gethostbyname_r(const char *name,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostbyname_r(name,
+ ret,
+ buf,
+ buflen,
+ result,
+ h_errnop);
+ }
+
+ return nwrap_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
+}
+#endif
+
+static struct hostent *nwrap_files_gethostbyaddr(const void *addr,
+ socklen_t len, int type)
+{
+ struct hostent *he;
+ char ip[INET6_ADDRSTRLEN] = {0};
+ const char *a;
+ int i;
+
+ (void) len; /* unused */
+
+ nwrap_files_cache_reload(nwrap_he_global.cache);
+
+ a = inet_ntop(type, addr, ip, sizeof(ip));
+ if (a == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ for (i = 0; i < nwrap_he_global.num; i++) {
+ he = &nwrap_he_global.list[i].ht;
+
+ if (he->h_addrtype != type) {
+ continue;
+ }
+
+ if (memcmp(addr, he->h_addr_list[0], he->h_length) == 0) {
+ return he;
+ }
+ }
+
+ errno = ENOENT;
+ return NULL;
+}
+
+#ifdef HAVE_GETHOSTBYADDR_R
+static int nwrap_gethostbyaddr_r(const void *addr, socklen_t len, int type,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop)
+{
+ *result = nwrap_files_gethostbyaddr(addr, len, type);
+ if (*result != NULL) {
+ memset(buf, '\0', buflen);
+ *ret = **result;
+ return 0;
+ } else {
+ *h_errnop = h_errno;
+ return -1;
+ }
+}
+
+int gethostbyaddr_r(const void *addr, socklen_t len, int type,
+ struct hostent *ret,
+ char *buf, size_t buflen,
+ struct hostent **result, int *h_errnop)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostbyaddr_r(addr,
+ len,
+ type,
+ ret,
+ buf,
+ buflen,
+ result,
+ h_errnop);
+ }
+
+ return nwrap_gethostbyaddr_r(addr, len, type, ret, buf, buflen, result, h_errnop);
+}
+#endif
+
+/* hosts enum functions */
+static void nwrap_files_sethostent(void)
+{
+ nwrap_he_global.idx = 0;
+}
+
+static struct hostent *nwrap_files_gethostent(void)
+{
+ struct hostent *he;
+
+ if (nwrap_he_global.idx == 0) {
+ nwrap_files_cache_reload(nwrap_he_global.cache);
+ }
+
+ if (nwrap_he_global.idx >= nwrap_he_global.num) {
+ errno = ENOENT;
+ return NULL;
+ }
+
+ he = &nwrap_he_global.list[nwrap_he_global.idx++].ht;
+
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "return hosts[%s]", he->h_name);
+
+ return he;
+}
+
+static void nwrap_files_endhostent(void)
+{
+ nwrap_he_global.idx = 0;
+}
+
/*
* module backend
*/
@@ -1430,6 +2548,7 @@ static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b,
if (status != NSS_STATUS_SUCCESS) {
return NULL;
}
+
return &pwd;
}
@@ -1439,6 +2558,10 @@ static int nwrap_module_getpwnam_r(struct nwrap_backend *b,
{
int ret;
+ (void) b; /* unused */
+ (void) pwdst; /* unused */
+ (void) pwdstp; /* unused */
+
if (!b->fns->_nss_getpwnam_r) {
return NSS_STATUS_NOTFOUND;
}
@@ -1492,6 +2615,8 @@ static int nwrap_module_getpwuid_r(struct nwrap_backend *b,
{
int ret;
+ (void) pwdstp; /* unused */
+
if (!b->fns->_nss_getpwuid_r) {
return ENOENT;
}
@@ -1553,6 +2678,8 @@ static int nwrap_module_getpwent_r(struct nwrap_backend *b,
{
int ret;
+ (void) pwdstp; /* unused */
+
if (!b->fns->_nss_getpwent_r) {
return ENOENT;
}
@@ -1644,6 +2771,8 @@ static int nwrap_module_getgrnam_r(struct nwrap_backend *b,
{
int ret;
+ (void) grdstp; /* unused */
+
if (!b->fns->_nss_getgrnam_r) {
return ENOENT;
}
@@ -1713,6 +2842,8 @@ static int nwrap_module_getgrgid_r(struct nwrap_backend *b,
{
int ret;
+ (void) grdstp; /* unused */
+
if (!b->fns->_nss_getgrgid_r) {
return ENOENT;
}
@@ -1790,6 +2921,8 @@ static int nwrap_module_getgrent_r(struct nwrap_backend *b,
{
int ret;
+ (void) grdstp; /* unused */
+
if (!b->fns->_nss_getgrent_r) {
return ENOENT;
}
@@ -1825,19 +2958,15 @@ static void nwrap_module_endgrent(struct nwrap_backend *b)
b->fns->_nss_endgrent();
}
-/*
- * PUBLIC interface
- */
+/****************************************************************************
+ * GETPWNAM
+ ***************************************************************************/
-_PUBLIC_ struct passwd *nwrap_getpwnam(const char *name)
+static struct passwd *nwrap_getpwnam(const char *name)
{
int i;
struct passwd *pwd;
- if (!nwrap_enabled()) {
- return real_getpwnam(name);
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
pwd = b->ops->nw_getpwnam(b, name);
@@ -1849,15 +2978,24 @@ _PUBLIC_ struct passwd *nwrap_getpwnam(const char *name)
return NULL;
}
-_PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst,
- char *buf, size_t buflen, struct passwd **pwdstp)
+struct passwd *getpwnam(const char *name)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
- return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwnam(name);
}
+ return nwrap_getpwnam(name);
+}
+
+/****************************************************************************
+ * GETPWNAM_R
+ ***************************************************************************/
+
+static int nwrap_getpwnam_r(const char *name, struct passwd *pwdst,
+ char *buf, size_t buflen, struct passwd **pwdstp)
+{
+ int i,ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getpwnam_r(b, name, pwdst, buf, buflen, pwdstp);
@@ -1870,15 +3008,32 @@ _PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst,
return ENOENT;
}
-_PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid)
+#ifdef HAVE_GETPWNAM_R
+# ifdef HAVE_SOLARIS_GETPWNAM_R
+int getpwnam_r(const char *name, struct passwd *pwdst,
+ char *buf, int buflen, struct passwd **pwdstp)
+# else /* HAVE_SOLARIS_GETPWNAM_R */
+int getpwnam_r(const char *name, struct passwd *pwdst,
+ char *buf, size_t buflen, struct passwd **pwdstp)
+# endif /* HAVE_SOLARIS_GETPWNAM_R */
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
+ }
+
+ return nwrap_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
+}
+#endif
+
+/****************************************************************************
+ * GETPWUID
+ ***************************************************************************/
+
+static struct passwd *nwrap_getpwuid(uid_t uid)
{
int i;
struct passwd *pwd;
- if (!nwrap_enabled()) {
- return real_getpwuid(uid);
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
pwd = b->ops->nw_getpwuid(b, uid);
@@ -1890,15 +3045,24 @@ _PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid)
return NULL;
}
-_PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst,
- char *buf, size_t buflen, struct passwd **pwdstp)
+struct passwd *getpwuid(uid_t uid)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
- return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwuid(uid);
}
+ return nwrap_getpwuid(uid);
+}
+
+/****************************************************************************
+ * GETPWUID_R
+ ***************************************************************************/
+
+static int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst,
+ char *buf, size_t buflen, struct passwd **pwdstp)
+{
+ int i,ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getpwuid_r(b, uid, pwdst, buf, buflen, pwdstp);
@@ -1911,30 +3075,54 @@ _PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst,
return ENOENT;
}
-_PUBLIC_ void nwrap_setpwent(void)
+#ifdef HAVE_SOLARIS_GETPWUID_R
+int getpwuid_r(uid_t uid, struct passwd *pwdst,
+ char *buf, int buflen, struct passwd **pwdstp)
+#else
+int getpwuid_r(uid_t uid, struct passwd *pwdst,
+ char *buf, size_t buflen, struct passwd **pwdstp)
+#endif
{
- int i;
-
- if (!nwrap_enabled()) {
- real_setpwent();
- return;
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
}
+ return nwrap_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
+}
+
+/****************************************************************************
+ * SETPWENT
+ ***************************************************************************/
+
+static void nwrap_setpwent(void)
+{
+ int i;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
b->ops->nw_setpwent(b);
}
}
-_PUBLIC_ struct passwd *nwrap_getpwent(void)
+void setpwent(void)
+{
+ if (!nss_wrapper_enabled()) {
+ libc_setpwent();
+ return;
+ }
+
+ nwrap_setpwent();
+}
+
+/****************************************************************************
+ * GETPWENT
+ ***************************************************************************/
+
+static struct passwd *nwrap_getpwent(void)
{
int i;
struct passwd *pwd;
- if (!nwrap_enabled()) {
- return real_getpwent();
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
pwd = b->ops->nw_getpwent(b);
@@ -1946,30 +3134,24 @@ _PUBLIC_ struct passwd *nwrap_getpwent(void)
return NULL;
}
-_PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf,
- size_t buflen, struct passwd **pwdstp)
+struct passwd *getpwent(void)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
-#ifdef SOLARIS_GETPWENT_R
- struct passwd *pw;
- pw = real_getpwent_r(pwdst, buf, buflen);
- if (!pw) {
- if (errno == 0) {
- return ENOENT;
- }
- return errno;
- }
- if (pwdstp) {
- *pwdstp = pw;
- }
- return 0;
-#else
- return real_getpwent_r(pwdst, buf, buflen, pwdstp);
-#endif
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwent();
}
+ return nwrap_getpwent();
+}
+
+/****************************************************************************
+ * GETPWENT_R
+ ***************************************************************************/
+
+static int nwrap_getpwent_r(struct passwd *pwdst, char *buf,
+ size_t buflen, struct passwd **pwdstp)
+{
+ int i,ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getpwent_r(b, pwdst, buf, buflen, pwdstp);
@@ -1982,14 +3164,41 @@ _PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf,
return ENOENT;
}
-_PUBLIC_ void nwrap_endpwent(void)
+#ifdef HAVE_SOLARIS_GETPWENT_R
+struct passwd *getpwent_r(struct passwd *pwdst, char *buf, int buflen)
{
- int i;
+ struct passwd *pwdstp = NULL;
+ int rc;
- if (!nwrap_enabled()) {
- real_endpwent();
- return;
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwent_r(pwdst, buf, buflen);
}
+ rc = nwrap_getpwent_r(pwdst, buf, buflen, &pwdstp);
+ if (rc < 0) {
+ return NULL;
+ }
+
+ return pwdstp;
+}
+#else /* HAVE_SOLARIS_GETPWENT_R */
+int getpwent_r(struct passwd *pwdst, char *buf,
+ size_t buflen, struct passwd **pwdstp)
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_getpwent_r(pwdst, buf, buflen, pwdstp);
+ }
+
+ return nwrap_getpwent_r(pwdst, buf, buflen, pwdstp);
+}
+#endif /* HAVE_SOLARIS_GETPWENT_R */
+
+/****************************************************************************
+ * ENDPWENT
+ ***************************************************************************/
+
+static void nwrap_endpwent(void)
+{
+ int i;
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
@@ -1997,32 +3206,56 @@ _PUBLIC_ void nwrap_endpwent(void)
}
}
-_PUBLIC_ int nwrap_initgroups(const char *user, gid_t group)
+void endpwent(void)
{
- int i;
-
- if (!nwrap_enabled()) {
- return real_initgroups(user, group);
+ if (!nss_wrapper_enabled()) {
+ libc_endpwent();
+ return;
}
+ nwrap_endpwent();
+}
+
+/****************************************************************************
+ * INITGROUPS
+ ***************************************************************************/
+
+static int nwrap_initgroups(const char *user, gid_t group)
+{
+ int i;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
- return b->ops->nw_initgroups(b, user, group);
+ int rc;
+
+ rc = b->ops->nw_initgroups(b, user, group);
+ if (rc == 0) {
+ return 0;
+ }
}
errno = ENOENT;
return -1;
}
-_PUBLIC_ struct group *nwrap_getgrnam(const char *name)
+int initgroups(const char *user, gid_t group)
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_initgroups(user, group);
+ }
+
+ return nwrap_initgroups(user, group);
+}
+
+/****************************************************************************
+ * GETGRNAM
+ ***************************************************************************/
+
+static struct group *nwrap_getgrnam(const char *name)
{
int i;
struct group *grp;
- if (!nwrap_enabled()) {
- return real_getgrnam(name);
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
grp = b->ops->nw_getgrnam(b, name);
@@ -2034,15 +3267,24 @@ _PUBLIC_ struct group *nwrap_getgrnam(const char *name)
return NULL;
}
-_PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst,
- char *buf, size_t buflen, struct group **grdstp)
+struct group *getgrnam(const char *name)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
- return real_getgrnam_r(name, grdst, buf, buflen, grdstp);
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrnam(name);
}
+ return nwrap_getgrnam(name);
+}
+
+/****************************************************************************
+ * GETGRNAM_R
+ ***************************************************************************/
+
+static int nwrap_getgrnam_r(const char *name, struct group *grdst,
+ char *buf, size_t buflen, struct group **grdstp)
+{
+ int i, ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getgrnam_r(b, name, grdst, buf, buflen, grdstp);
@@ -2055,15 +3297,36 @@ _PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst,
return ENOENT;
}
-_PUBLIC_ struct group *nwrap_getgrgid(gid_t gid)
+#ifdef HAVE_GETGRNAM_R
+# ifdef HAVE_SOLARIS_GETGRNAM_R
+int getgrnam_r(const char *name, struct group *grp,
+ char *buf, int buflen, struct group **pgrp)
+# else /* HAVE_SOLARIS_GETGRNAM_R */
+int getgrnam_r(const char *name, struct group *grp,
+ char *buf, size_t buflen, struct group **pgrp)
+# endif /* HAVE_SOLARIS_GETGRNAM_R */
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrnam_r(name,
+ grp,
+ buf,
+ buflen,
+ pgrp);
+ }
+
+ return nwrap_getgrnam_r(name, grp, buf, buflen, pgrp);
+}
+#endif /* HAVE_GETGRNAM_R */
+
+/****************************************************************************
+ * GETGRGID
+ ***************************************************************************/
+
+static struct group *nwrap_getgrgid(gid_t gid)
{
int i;
struct group *grp;
- if (!nwrap_enabled()) {
- return real_getgrgid(gid);
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
grp = b->ops->nw_getgrgid(b, gid);
@@ -2075,15 +3338,24 @@ _PUBLIC_ struct group *nwrap_getgrgid(gid_t gid)
return NULL;
}
-_PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst,
- char *buf, size_t buflen, struct group **grdstp)
+struct group *getgrgid(gid_t gid)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
- return real_getgrgid_r(gid, grdst, buf, buflen, grdstp);
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrgid(gid);
}
+ return nwrap_getgrgid(gid);
+}
+
+/****************************************************************************
+ * GETGRGID_R
+ ***************************************************************************/
+
+static int nwrap_getgrgid_r(gid_t gid, struct group *grdst,
+ char *buf, size_t buflen, struct group **grdstp)
+{
+ int i,ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getgrgid_r(b, gid, grdst, buf, buflen, grdstp);
@@ -2096,30 +3368,67 @@ _PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst,
return ENOENT;
}
-_PUBLIC_ void nwrap_setgrent(void)
+#ifdef HAVE_GETGRGID_R
+# ifdef HAVE_SOLARIS_GETGRGID_R
+int getgrgid_r(gid_t gid, struct group *grdst,
+ char *buf, int buflen, struct group **grdstp)
+# else /* HAVE_SOLARIS_GETGRGID_R */
+int getgrgid_r(gid_t gid, struct group *grdst,
+ char *buf, size_t buflen, struct group **grdstp)
+# endif /* HAVE_SOLARIS_GETGRGID_R */
{
- int i;
-
- if (!nwrap_enabled()) {
- real_setgrent();
- return;
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrgid_r(gid, grdst, buf, buflen, grdstp);
}
+ return nwrap_getgrgid_r(gid, grdst, buf, buflen, grdstp);
+}
+#endif
+
+/****************************************************************************
+ * SETGRENT
+ ***************************************************************************/
+
+static void nwrap_setgrent(void)
+{
+ int i;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
b->ops->nw_setgrent(b);
}
}
-_PUBLIC_ struct group *nwrap_getgrent(void)
+#ifdef HAVE_BSD_SETGRENT
+int setgrent(void)
+#else
+void setgrent(void)
+#endif
+{
+ if (!nss_wrapper_enabled()) {
+ libc_setgrent();
+ goto out;
+ }
+
+ nwrap_setgrent();
+
+out:
+#ifdef HAVE_BSD_SETGRENT
+ return 0;
+#else
+ return;
+#endif
+}
+
+/****************************************************************************
+ * GETGRENT
+ ***************************************************************************/
+
+static struct group *nwrap_getgrent(void)
{
int i;
struct group *grp;
- if (!nwrap_enabled()) {
- return real_getgrent();
- }
-
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
grp = b->ops->nw_getgrent(b);
@@ -2131,30 +3440,24 @@ _PUBLIC_ struct group *nwrap_getgrent(void)
return NULL;
}
-_PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf,
- size_t buflen, struct group **grdstp)
+struct group *getgrent(void)
{
- int i,ret;
-
- if (!nwrap_enabled()) {
-#ifdef SOLARIS_GETGRENT_R
- struct group *gr;
- gr = real_getgrent_r(grdst, buf, buflen);
- if (!gr) {
- if (errno == 0) {
- return ENOENT;
- }
- return errno;
- }
- if (grdstp) {
- *grdstp = gr;
- }
- return 0;
-#else
- return real_getgrent_r(grdst, buf, buflen, grdstp);
-#endif
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrent();
}
+ return nwrap_getgrent();
+}
+
+/****************************************************************************
+ * GETGRENT_R
+ ***************************************************************************/
+
+static int nwrap_getgrent_r(struct group *grdst, char *buf,
+ size_t buflen, struct group **grdstp)
+{
+ int i,ret;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
ret = b->ops->nw_getgrent_r(b, grdst, buf, buflen, grdstp);
@@ -2167,37 +3470,77 @@ _PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf,
return ENOENT;
}
-_PUBLIC_ void nwrap_endgrent(void)
+#ifdef HAVE_SOLARIS_GETGRENT_R
+struct group *getgrent_r(struct group *src, char *buf, int buflen)
{
- int i;
+ struct group *grdstp = NULL;
+ int rc;
- if (!nwrap_enabled()) {
- real_endgrent();
- return;
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrent_r(src, buf, buflen);
+ }
+
+ rc = nwrap_getgrent_r(src, buf, buflen, &grdstp);
+ if (rc < 0) {
+ return NULL;
+ }
+
+ return grdstp;
+}
+#else /* HAVE_SOLARIS_GETGRENT_R */
+int getgrent_r(struct group *src, char *buf,
+ size_t buflen, struct group **grdstp)
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrent_r(src, buf, buflen, grdstp);
}
+ return nwrap_getgrent_r(src, buf, buflen, grdstp);
+}
+#endif /* HAVE_SOLARIS_GETGRENT_R */
+
+/****************************************************************************
+ * ENDGRENT
+ ***************************************************************************/
+
+static void nwrap_endgrent(void)
+{
+ int i;
+
for (i=0; i < nwrap_main_global->num_backends; i++) {
struct nwrap_backend *b = &nwrap_main_global->backends[i];
b->ops->nw_endgrent(b);
}
}
-_PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+void endgrent(void)
+{
+ if (!nss_wrapper_enabled()) {
+ libc_endgrent();
+ return;
+ }
+
+ nwrap_endgrent();
+}
+
+/****************************************************************************
+ * GETGROUPLIST
+ ***************************************************************************/
+
+#ifdef HAVE_GETGROUPLIST
+static int nwrap_getgrouplist(const char *user, gid_t group,
+ gid_t *groups, int *ngroups)
{
struct group *grp;
gid_t *groups_tmp;
int count = 1;
const char *name_of_group = "";
- if (!nwrap_enabled()) {
- return real_getgrouplist(user, group, groups, ngroups);
- }
-
- NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user));
+ NWRAP_LOG(NWRAP_LOG_DEBUG, "getgrouplist called for %s", user);
groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
if (!groups_tmp) {
- NWRAP_ERROR(("%s:calloc failed\n",__location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
errno = ENOMEM;
return -1;
}
@@ -2213,20 +3556,24 @@ _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, in
while ((grp = nwrap_getgrent()) != NULL) {
int i = 0;
- NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
- __location__, grp->gr_name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "Inspecting %s for group membership",
+ grp->gr_name);
for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
if ((strcmp(user, grp->gr_mem[i]) == 0) &&
(strcmp(name_of_group, grp->gr_name) != 0)) {
- NWRAP_DEBUG(("%s: %s is member of %s\n",
- __location__, user, grp->gr_name));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "%s is member of %s",
+ user,
+ grp->gr_name);
groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t));
if (!groups_tmp) {
- NWRAP_ERROR(("%s:calloc failed\n",__location__));
+ NWRAP_LOG(NWRAP_LOG_ERROR,
+ "Out of memory");
errno = ENOMEM;
return -1;
}
@@ -2239,8 +3586,9 @@ _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, in
nwrap_endgrent();
- NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
- __location__, user, *ngroups));
+ NWRAP_LOG(NWRAP_LOG_DEBUG,
+ "%s is member of %d groups",
+ user, *ngroups);
if (*ngroups < count) {
*ngroups = count;
@@ -2254,3 +3602,631 @@ _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, in
return count;
}
+
+int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+ if (!nss_wrapper_enabled()) {
+ return libc_getgrouplist(user, group, groups, ngroups);
+ }
+
+ return nwrap_getgrouplist(user, group, groups, ngroups);
+}
+#endif
+
+/**********************************************************
+ * NETDB
+ **********************************************************/
+
+static void nwrap_sethostent(int stayopen) {
+ (void) stayopen; /* ignored */
+
+ nwrap_files_sethostent();
+}
+
+#ifdef HAVE_SOLARIS_SETHOSTENT
+int sethostent(int stayopen)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ libc_sethostent(stayopen);
+ return 0;
+ }
+
+ nwrap_sethostent(stayopen);
+
+ return 0;
+}
+#else /* HAVE_SOLARIS_SETHOSTENT */
+void sethostent(int stayopen)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ libc_sethostent(stayopen);
+ return;
+ }
+
+ nwrap_sethostent(stayopen);
+}
+#endif /* HAVE_SOLARIS_SETHOSTENT */
+
+static struct hostent *nwrap_gethostent(void)
+{
+ return nwrap_files_gethostent();
+}
+
+struct hostent *gethostent(void) {
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostent();
+ }
+
+ return nwrap_gethostent();
+}
+
+static void nwrap_endhostent(void) {
+ nwrap_files_endhostent();
+}
+
+#ifdef HAVE_SOLARIS_ENDHOSTENT
+int endhostent(void)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ libc_endhostent();
+ return 0;
+ }
+
+ nwrap_endhostent();
+
+ return 0;
+}
+#else /* HAVE_SOLARIS_ENDHOSTENT */
+void endhostent(void)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ libc_endhostent();
+ return;
+ }
+
+ nwrap_endhostent();
+}
+#endif /* HAVE_SOLARIS_ENDHOSTENT */
+
+static struct hostent *nwrap_gethostbyname(const char *name)
+{
+ return nwrap_files_gethostbyname(name, AF_UNSPEC);
+}
+
+struct hostent *gethostbyname(const char *name)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostbyname(name);
+ }
+
+ return nwrap_gethostbyname(name);
+}
+
+/* This is a GNU extension */
+#ifdef HAVE_GETHOSTBYNAME2
+static struct hostent *nwrap_gethostbyname2(const char *name, int af)
+{
+ return nwrap_files_gethostbyname(name, af);
+}
+
+struct hostent *gethostbyname2(const char *name, int af)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostbyname2(name, af);
+ }
+
+ return nwrap_gethostbyname2(name, af);
+}
+#endif
+
+static struct hostent *nwrap_gethostbyaddr(const void *addr,
+ socklen_t len, int type)
+{
+ return nwrap_files_gethostbyaddr(addr, len, type);
+}
+
+struct hostent *gethostbyaddr(const void *addr,
+ socklen_t len, int type)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_gethostbyaddr(addr, len, type);
+ }
+
+ return nwrap_gethostbyaddr(addr, len, type);
+}
+
+static const struct addrinfo default_hints =
+{
+ .ai_flags = AI_ADDRCONFIG|AI_V4MAPPED,
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = 0,
+ .ai_protocol = 0,
+ .ai_addrlen = 0,
+ .ai_addr = NULL,
+ .ai_canonname = NULL,
+ .ai_next = NULL
+};
+
+static int nwrap_convert_he_ai(const struct hostent *he,
+ unsigned short port,
+ const struct addrinfo *hints,
+ struct addrinfo **pai)
+{
+ struct addrinfo *ai;
+ socklen_t socklen;
+
+ switch (he->h_addrtype) {
+ case AF_INET:
+ socklen = sizeof(struct sockaddr_in);
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ socklen = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ return EAI_FAMILY;
+ }
+
+ ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + socklen);
+ if (ai == NULL) {
+ return EAI_MEMORY;
+ }
+
+ ai->ai_flags = 0;
+ ai->ai_family = he->h_addrtype;
+ ai->ai_socktype = hints->ai_socktype;
+ ai->ai_protocol = hints->ai_protocol;
+
+ ai->ai_addrlen = socklen;
+ ai->ai_addr = (void *)(ai + 1);
+
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ ai->ai_addr->sa_len = socklen;
+#endif
+ ai->ai_addr->sa_family = he->h_addrtype;
+
+ switch (he->h_addrtype) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sinp =
+ (struct sockaddr_in *) ai->ai_addr;
+
+ memset(sinp, 0, sizeof(struct sockaddr_in));
+
+ sinp->sin_port = htons(port);
+ sinp->sin_family = AF_INET;
+
+ memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
+ memcpy(&sinp->sin_addr, he->h_addr_list[0], he->h_length);
+
+ }
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6p =
+ (struct sockaddr_in6 *) ai->ai_addr;
+
+ memset(sin6p, 0, sizeof(struct sockaddr_in6));
+
+ sin6p->sin6_port = htons(port);
+ sin6p->sin6_family = AF_INET6;
+
+ memcpy(&sin6p->sin6_addr, he->h_addr_list[0], he->h_length);
+ }
+ break;
+#endif
+ }
+
+ ai->ai_next = NULL;
+
+ if (he->h_name) {
+ ai->ai_canonname = strdup(he->h_name);
+ if (ai->ai_canonname == NULL) {
+ freeaddrinfo(ai);
+ return EAI_MEMORY;
+ }
+ }
+
+ *pai = ai;
+ return 0;
+}
+
+static int nwrap_getaddrinfo(const char *node,
+ const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ struct addrinfo *ai = NULL;
+ struct addrinfo *p = NULL;
+ unsigned short port = 0;
+ struct hostent *he;
+ struct in_addr in;
+ bool is_addr_ipv4 = false;
+ bool is_addr_ipv6 = false;
+ int eai = EAI_SYSTEM;
+ int ret;
+ int rc;
+ int af;
+
+ if (node == NULL && service == NULL) {
+ return EAI_NONAME;
+ }
+
+ ret = libc_getaddrinfo(node, service, hints, &p);
+ if (ret == 0) {
+ *res = p;
+ }
+
+ /* If no node has been specified, let glibc deal with it */
+ if (node == NULL) {
+ return ret;
+ }
+
+ if (hints == NULL) {
+ hints = &default_hints;
+ }
+
+ if ((hints->ai_flags & AI_CANONNAME) && node == NULL) {
+ return EAI_BADFLAGS;
+ }
+
+ if (service != NULL && service[0] != '\0') {
+ if (isdigit((int)service[0])) {
+ port = (unsigned short)atoi(service);
+ } else {
+ const char *proto = NULL;
+ struct servent *s;
+
+ if (hints->ai_protocol != 0) {
+ struct protoent *pent;
+
+ pent = getprotobynumber(hints->ai_protocol);
+ if (pent != NULL) {
+ proto = pent->p_name;
+ }
+ }
+
+ s = getservbyname(service, proto);
+ if (s != NULL) {
+ port = ntohs(s->s_port);
+ } else {
+ if (p != NULL) {
+ freeaddrinfo(p);
+ }
+ return EAI_SERVICE;
+ }
+ }
+ }
+
+ af = hints->ai_family;
+ if (af == AF_UNSPEC) {
+ af = AF_INET;
+ }
+
+ rc = inet_pton(af, node, &in);
+ if (rc == 1) {
+ is_addr_ipv4 = true;
+ if (af == AF_UNSPEC) {
+ af = AF_INET;
+ }
+#ifdef HAVE_IPV6
+ } else {
+ struct in6_addr in6;
+
+ af = AF_INET6;
+
+ rc = inet_pton(af, node, &in6);
+ if (rc == 1) {
+ is_addr_ipv6 = true;
+ }
+#endif
+ }
+
+ if (is_addr_ipv4) {
+ he = nwrap_files_gethostbyaddr(&in, sizeof(struct in_addr), af);
+ if (he != NULL) {
+ rc = nwrap_convert_he_ai(he, port, hints, &ai);
+ } else {
+ eai = EAI_NODATA;
+ rc = -1;
+ }
+#ifdef HAVE_IPV6
+ } else if (is_addr_ipv6) {
+ struct in6_addr in6;
+
+ rc = inet_pton(af, node, &in6);
+ if (rc <= 0) {
+ eai = EAI_ADDRFAMILY;
+ return ret == 0 ? 0 : eai;
+ }
+
+ he = nwrap_files_gethostbyaddr(&in6,
+ sizeof(struct in6_addr),
+ af);
+ if (he != NULL) {
+ rc = nwrap_convert_he_ai(he, port, hints, &ai);
+ eai = rc;
+ } else {
+ eai = EAI_NODATA;
+ rc = -1;
+ }
+#endif
+ } else {
+ he = nwrap_files_gethostbyname(node, hints->ai_family);
+ if (he != NULL) {
+ rc = nwrap_convert_he_ai(he, port, hints, &ai);
+ eai = rc;
+ } else {
+ eai = EAI_NODATA;
+ rc = -1;
+ }
+ }
+
+ if (rc < 0) {
+ return ret == 0 ? 0 : eai;
+ }
+
+ if (ret == 0) {
+ freeaddrinfo(p);
+ }
+
+ if (ai->ai_flags == 0) {
+ ai->ai_flags = hints->ai_flags;
+ }
+ if (ai->ai_socktype == 0) {
+ ai->ai_socktype = SOCK_DGRAM;
+ }
+ if (ai->ai_protocol == 0 && ai->ai_socktype == SOCK_DGRAM) {
+ ai->ai_protocol = 17; /* UDP */
+ } else if (ai->ai_protocol == 0 && ai->ai_socktype == SOCK_STREAM) {
+ ai->ai_protocol = 6; /* TCP */
+ }
+
+ if (hints->ai_socktype == 0) {
+ /* Add second ai */
+ rc = nwrap_convert_he_ai(he, port, hints, &ai->ai_next);
+ if (rc < 0) {
+ freeaddrinfo(ai);
+ return rc;
+ }
+
+ if (ai->ai_next->ai_flags == 0) {
+ ai->ai_next->ai_flags = hints->ai_flags;
+ }
+ if (ai->ai_socktype == SOCK_DGRAM) {
+ ai->ai_next->ai_socktype = SOCK_STREAM;
+ } else if (ai->ai_socktype == SOCK_STREAM) {
+ ai->ai_next->ai_socktype = SOCK_DGRAM;
+ }
+ if (ai->ai_next->ai_socktype == SOCK_DGRAM) {
+ ai->ai_next->ai_protocol = 17; /* UDP */
+ } else if (ai->ai_next->ai_socktype == SOCK_STREAM) {
+ ai->ai_next->ai_protocol = 6; /* TCP */
+ }
+ }
+
+ *res = ai;
+
+ return 0;
+}
+
+int getaddrinfo(const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_getaddrinfo(node, service, hints, res);
+ }
+
+ return nwrap_getaddrinfo(node, service, hints, res);
+}
+
+static int nwrap_getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
+{
+ struct hostent *he;
+ struct servent *service;
+ const char *proto;
+ const void *addr;
+ socklen_t addrlen;
+ uint16_t port;
+ sa_family_t type;
+
+ if (sa == NULL || salen < sizeof(sa_family_t)) {
+ return EAI_FAMILY;
+ }
+
+ if ((flags & NI_NAMEREQD) && host == NULL && serv == NULL) {
+ return EAI_NONAME;
+ }
+
+ type = sa->sa_family;
+ switch (type) {
+ case AF_INET:
+ if (salen < sizeof(struct sockaddr_in))
+ return EAI_FAMILY;
+ addr = &((struct sockaddr_in *)sa)->sin_addr;
+ addrlen = sizeof(((struct sockaddr_in *)sa)->sin_addr);
+ port = ntohs(((struct sockaddr_in *)sa)->sin_port);
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ if (salen < sizeof(struct sockaddr_in6))
+ return EAI_FAMILY;
+ addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+ addrlen = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr);
+ port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
+ break;
+#endif
+ default:
+ return EAI_FAMILY;
+ }
+
+ if (host != NULL) {
+ he = NULL;
+ if ((flags & NI_NUMERICHOST) == 0) {
+ he = nwrap_files_gethostbyaddr(addr, addrlen, type);
+ if ((flags & NI_NAMEREQD) && (he == NULL || he->h_name == NULL))
+ return EAI_NONAME;
+ }
+ if (he != NULL && he->h_name != NULL) {
+ if (strlen(he->h_name) >= hostlen)
+ return EAI_OVERFLOW;
+ strcpy(host, he->h_name);
+ if (flags & NI_NOFQDN)
+ host[strcspn(host, ".")] = '\0';
+ } else {
+ if (inet_ntop(type, addr, host, hostlen) == NULL)
+ return (errno == ENOSPC) ? EAI_OVERFLOW : EAI_FAIL;
+ }
+ }
+
+ if (serv != NULL) {
+ service = NULL;
+ if ((flags & NI_NUMERICSERV) == 0) {
+ proto = (flags & NI_DGRAM) ? "udp" : "tcp";
+ service = getservbyport(htons(port), proto);
+ }
+ if (service != NULL) {
+ if (strlen(service->s_name) >= servlen)
+ return EAI_OVERFLOW;
+ strcpy(serv, service->s_name);
+ } else {
+ if (snprintf(serv, servlen, "%u", port) >= (int) servlen)
+ return EAI_OVERFLOW;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef HAVE_LINUX_GETNAMEINFO
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, socklen_t hostlen,
+ char *serv, socklen_t servlen,
+ int flags)
+#elif defined(HAVE_LINUX_GETNAMEINFO_UNSIGNED)
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, socklen_t hostlen,
+ char *serv, socklen_t servlen,
+ unsigned int flags)
+#else
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
+#endif
+{
+ if (!nss_wrapper_hosts_enabled()) {
+ return libc_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+ }
+
+ return nwrap_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+}
+
+static int nwrap_gethostname(char *name, size_t len)
+{
+ const char *hostname = getenv("NSS_WRAPPER_HOSTNAME");
+
+ if (strlen(hostname) >= len) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ snprintf(name, len, "%s", hostname);
+
+ return 0;
+}
+
+#ifdef HAVE_SOLARIS_GETHOSTNAME
+int gethostname(char *name, int len)
+#else /* HAVE_SOLARIS_GETHOSTNAME */
+int gethostname(char *name, size_t len)
+#endif /* HAVE_SOLARIS_GETHOSTNAME */
+{
+ if (!nwrap_hostname_enabled()) {
+ return libc_gethostname(name, len);
+ }
+
+ return nwrap_gethostname(name, len);
+}
+
+/****************************
+ * DESTRUCTOR
+ ***************************/
+
+/*
+ * This function is called when the library is unloaded and makes sure that
+ * sockets get closed and the unix file for the socket are unlinked.
+ */
+void nwrap_destructor(void)
+{
+ int i;
+
+ if (nwrap_main_global != NULL) {
+ struct nwrap_main *m = nwrap_main_global;
+
+ /* libc */
+ SAFE_FREE(m->libc->fns);
+ if (m->libc->handle != NULL) {
+ dlclose(m->libc->handle);
+ }
+ if (m->libc->nsl_handle != NULL) {
+ dlclose(m->libc->nsl_handle);
+ }
+ if (m->libc->sock_handle != NULL) {
+ dlclose(m->libc->sock_handle);
+ }
+ SAFE_FREE(m->libc);
+
+ /* backends */
+ for (i = 0; i < m->num_backends; i++) {
+ struct nwrap_backend *b = &(m->backends[i]);
+
+ if (b->so_handle != NULL) {
+ dlclose(b->so_handle);
+ }
+ SAFE_FREE(b->fns);
+ }
+ SAFE_FREE(m->backends);
+ }
+
+ if (nwrap_pw_global.cache != NULL) {
+ struct nwrap_cache *c = nwrap_pw_global.cache;
+
+ nwrap_files_cache_unload(c);
+ if (c->fd >= 0) {
+ close(c->fd);
+ }
+
+ SAFE_FREE(nwrap_pw_global.list);
+ nwrap_pw_global.num = 0;
+ }
+
+ if (nwrap_gr_global.cache != NULL) {
+ struct nwrap_cache *c = nwrap_gr_global.cache;
+
+ nwrap_files_cache_unload(c);
+ if (c->fd >= 0) {
+ close(c->fd);
+ }
+
+ SAFE_FREE(nwrap_gr_global.list);
+ nwrap_pw_global.num = 0;
+ }
+
+ if (nwrap_he_global.cache != NULL) {
+ struct nwrap_cache *c = nwrap_he_global.cache;
+
+ nwrap_files_cache_unload(c);
+ if (c->fd >= 0) {
+ close(c->fd);
+ }
+
+ SAFE_FREE(nwrap_he_global.list);
+ nwrap_he_global.num = 0;
+ }
+}
diff --git a/lib/nss_wrapper/nss_wrapper.h b/lib/nss_wrapper/nss_wrapper.h
deleted file mode 100644
index 5bcd42ead40..00000000000
--- a/lib/nss_wrapper/nss_wrapper.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __NSS_WRAPPER_H__
-#define __NSS_WRAPPER_H__
-
-struct passwd *nwrap_getpwnam(const char *name);
-int nwrap_getpwnam_r(const char *name, struct passwd *pwbuf,
- char *buf, size_t buflen, struct passwd **pwbufp);
-struct passwd *nwrap_getpwuid(uid_t uid);
-int nwrap_getpwuid_r(uid_t uid, struct passwd *pwbuf,
- char *buf, size_t buflen, struct passwd **pwbufp);
-void nwrap_setpwent(void);
-struct passwd *nwrap_getpwent(void);
-int nwrap_getpwent_r(struct passwd *pwbuf, char *buf,
- size_t buflen, struct passwd **pwbufp);
-void nwrap_endpwent(void);
-int nwrap_initgroups(const char *user, gid_t group);
-int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
-struct group *nwrap_getgrnam(const char *name);
-int nwrap_getgrnam_r(const char *name, struct group *gbuf,
- char *buf, size_t buflen, struct group **gbufp);
-struct group *nwrap_getgrgid(gid_t gid);
-int nwrap_getgrgid_r(gid_t gid, struct group *gbuf,
- char *buf, size_t buflen, struct group **gbufp);
-void nwrap_setgrent(void);
-struct group *nwrap_getgrent(void);
-int nwrap_getgrent_r(struct group *gbuf, char *buf,
- size_t buflen, struct group **gbufp);
-void nwrap_endgrent(void);
-
-#ifdef NSS_WRAPPER_REPLACE
-
-#ifdef getpwnam
-#undef getpwnam
-#endif
-#define getpwnam nwrap_getpwnam
-
-#ifdef getpwnam_r
-#undef getpwnam_r
-#endif
-#define getpwnam_r nwrap_getpwnam_r
-
-#ifdef getpwuid
-#undef getpwuid
-#endif
-#define getpwuid nwrap_getpwuid
-
-#ifdef getpwuid_r
-#undef getpwuid_r
-#endif
-#define getpwuid_r nwrap_getpwuid_r
-
-#ifdef setpwent
-#undef setpwent
-#endif
-#define setpwent nwrap_setpwent
-
-#ifdef getpwent
-#undef getpwent
-#endif
-#define getpwent nwrap_getpwent
-
-#ifdef getpwent_r
-#undef getpwent_r
-#endif
-#define getpwent_r nwrap_getpwent_r
-
-#ifdef endpwent
-#undef endpwent
-#endif
-#define endpwent nwrap_endpwent
-
-#ifdef getgrlst
-#undef getgrlst
-#endif
-#define getgrlst __none_nwrap_getgrlst
-
-#ifdef getgrlst_r
-#undef getgrlst_r
-#endif
-#define getgrlst_r __none_nwrap_getgrlst_r
-
-#ifdef initgroups_dyn
-#undef initgroups_dyn
-#endif
-#define initgroups_dyn __none_nwrap_initgroups_dyn
-
-#ifdef initgroups
-#undef initgroups
-#endif
-#define initgroups nwrap_initgroups
-
-#ifdef getgrouplist
-#undef getgrouplist
-#endif
-#define getgrouplist nwrap_getgrouplist
-
-#ifdef getgrnam
-#undef getgrnam
-#endif
-#define getgrnam nwrap_getgrnam
-
-#ifdef getgrnam_r
-#undef getgrnam_r
-#endif
-#define getgrnam_r nwrap_getgrnam_r
-
-#ifdef getgrgid
-#undef getgrgid
-#endif
-#define getgrgid nwrap_getgrgid
-
-#ifdef getgrgid_r
-#undef getgrgid_r
-#endif
-#define getgrgid_r nwrap_getgrgid_r
-
-#ifdef setgrent
-#undef setgrent
-#endif
-#define setgrent nwrap_setgrent
-
-#ifdef getgrent
-#undef getgrent
-#endif
-#define getgrent nwrap_getgrent
-
-#ifdef getgrent_r
-#undef getgrent_r
-#endif
-#define getgrent_r nwrap_getgrent_r
-
-#ifdef endgrent
-#undef endgrent
-#endif
-#define endgrent nwrap_endgrent
-
-#endif /* NSS_WRAPPER_REPLACE */
-
-#endif /* __NSS_WRAPPER_H__ */
diff --git a/lib/nss_wrapper/testsuite.c b/lib/nss_wrapper/testsuite.c
deleted file mode 100644
index 6fae1244f08..00000000000
--- a/lib/nss_wrapper/testsuite.c
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- local testing of the nss wrapper
-
- Copyright (C) Guenther Deschner 2009-2010
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-#ifndef NSS_WRAPPER
-#define NSS_WRAPPER
-#endif
-
-#include "torture/torture.h"
-#include "torture/local/proto.h"
-#include "lib/replace/system/passwd.h"
-
-static bool copy_passwd(struct torture_context *tctx,
- const struct passwd *pwd,
- struct passwd *p)
-{
- p->pw_name = talloc_strdup(tctx, pwd->pw_name);
- p->pw_passwd = talloc_strdup(tctx, pwd->pw_passwd);
- p->pw_uid = pwd->pw_uid;
- p->pw_gid = pwd->pw_gid;
- p->pw_gecos = talloc_strdup(tctx, pwd->pw_gecos);
- p->pw_dir = talloc_strdup(tctx, pwd->pw_dir);
- p->pw_shell = talloc_strdup(tctx, pwd->pw_shell);
-
- return true;
-}
-
-static void print_passwd(struct passwd *pwd)
-{
- printf("%s:%s:%lu:%lu:%s:%s:%s\n",
- pwd->pw_name,
- pwd->pw_passwd,
- (unsigned long)pwd->pw_uid,
- (unsigned long)pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- pwd->pw_shell);
-}
-
-
-static bool test_nwrap_getpwnam(struct torture_context *tctx,
- const char *name,
- struct passwd *pwd_p)
-{
- struct passwd *pwd;
-
- torture_comment(tctx, "Testing getpwnam: %s\n", name);
-
- pwd = getpwnam(name);
- if (pwd) {
- print_passwd(pwd);
- }
-
- if (pwd_p) {
- copy_passwd(tctx, pwd, pwd_p);
- }
-
- return pwd ? true : false;
-}
-
-static bool test_nwrap_getpwnam_r(struct torture_context *tctx,
- const char *name,
- struct passwd *pwd_p)
-{
- struct passwd pwd, *pwdp;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing getpwnam_r: %s\n", name);
-
- ret = getpwnam_r(name, &pwd, buffer, sizeof(buffer), &pwdp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- return false;
- }
-
- print_passwd(&pwd);
-
- if (pwd_p) {
- copy_passwd(tctx, &pwd, pwd_p);
- }
-
- return true;
-}
-
-static bool test_nwrap_getpwuid(struct torture_context *tctx,
- uid_t uid,
- struct passwd *pwd_p)
-{
- struct passwd *pwd;
-
- torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid);
-
- pwd = getpwuid(uid);
- if (pwd) {
- print_passwd(pwd);
- }
-
- if (pwd_p) {
- copy_passwd(tctx, pwd, pwd_p);
- }
-
- return pwd ? true : false;
-}
-
-static bool test_nwrap_getpwuid_r(struct torture_context *tctx,
- uid_t uid,
- struct passwd *pwd_p)
-{
- struct passwd pwd, *pwdp;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing getpwuid_r: %lu\n", (unsigned long)uid);
-
- ret = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &pwdp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- return false;
- }
-
- print_passwd(&pwd);
-
- if (pwd_p) {
- copy_passwd(tctx, &pwd, pwd_p);
- }
-
- return true;
-}
-
-
-static bool copy_group(struct torture_context *tctx,
- const struct group *grp,
- struct group *g)
-{
- int i;
-
- g->gr_name = talloc_strdup(tctx, grp->gr_name);
- g->gr_passwd = talloc_strdup(tctx, grp->gr_passwd);
- g->gr_gid = grp->gr_gid;
- g->gr_mem = NULL;
-
- for (i=0; grp->gr_mem && grp->gr_mem[i]; i++) {
- g->gr_mem = talloc_realloc(tctx, g->gr_mem, char *, i + 2);
- g->gr_mem[i] = talloc_strdup(g->gr_mem, grp->gr_mem[i]);
- g->gr_mem[i+1] = NULL;
- }
-
- return true;
-}
-
-static void print_group(struct group *grp)
-{
- int i;
- printf("%s:%s:%lu:",
- grp->gr_name,
- grp->gr_passwd,
- (unsigned long)grp->gr_gid);
-
- if ((grp->gr_mem == NULL) || !grp->gr_mem[0]) {
- printf("\n");
- return;
- }
-
- for (i=0; grp->gr_mem[i+1]; i++) {
- printf("%s,", grp->gr_mem[i]);
- }
- printf("%s\n", grp->gr_mem[i]);
-}
-
-static bool test_nwrap_getgrnam(struct torture_context *tctx,
- const char *name,
- struct group *grp_p)
-{
- struct group *grp;
-
- torture_comment(tctx, "Testing getgrnam: %s\n", name);
-
- grp = getgrnam(name);
- if (grp) {
- print_group(grp);
- }
-
- if (grp_p) {
- copy_group(tctx, grp, grp_p);
- }
-
- return grp ? true : false;
-}
-
-static bool test_nwrap_getgrnam_r(struct torture_context *tctx,
- const char *name,
- struct group *grp_p)
-{
- struct group grp, *grpp;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing getgrnam_r: %s\n", name);
-
- ret = getgrnam_r(name, &grp, buffer, sizeof(buffer), &grpp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- return false;
- }
-
- print_group(&grp);
-
- if (grp_p) {
- copy_group(tctx, &grp, grp_p);
- }
-
- return true;
-}
-
-
-static bool test_nwrap_getgrgid(struct torture_context *tctx,
- gid_t gid,
- struct group *grp_p)
-{
- struct group *grp;
-
- torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid);
-
- grp = getgrgid(gid);
- if (grp) {
- print_group(grp);
- }
-
- if (grp_p) {
- copy_group(tctx, grp, grp_p);
- }
-
- return grp ? true : false;
-}
-
-static bool test_nwrap_getgrgid_r(struct torture_context *tctx,
- gid_t gid,
- struct group *grp_p)
-{
- struct group grp, *grpp;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing getgrgid_r: %lu\n", (unsigned long)gid);
-
- ret = getgrgid_r(gid, &grp, buffer, sizeof(buffer), &grpp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- return false;
- }
-
- print_group(&grp);
-
- if (grp_p) {
- copy_group(tctx, &grp, grp_p);
- }
-
- return true;
-}
-
-static bool test_nwrap_enum_passwd(struct torture_context *tctx,
- struct passwd **pwd_array_p,
- size_t *num_pwd_p)
-{
- struct passwd *pwd;
- struct passwd *pwd_array = NULL;
- size_t num_pwd = 0;
-
- torture_comment(tctx, "Testing setpwent\n");
- setpwent();
-
- while ((pwd = getpwent()) != NULL) {
- torture_comment(tctx, "Testing getpwent\n");
-
- print_passwd(pwd);
- if (pwd_array_p && num_pwd_p) {
- pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
- torture_assert(tctx, pwd_array, "out of memory");
- copy_passwd(tctx, pwd, &pwd_array[num_pwd]);
- num_pwd++;
- }
- }
-
- torture_comment(tctx, "Testing endpwent\n");
- endpwent();
-
- if (pwd_array_p) {
- *pwd_array_p = pwd_array;
- }
- if (num_pwd_p) {
- *num_pwd_p = num_pwd;
- }
-
- return true;
-}
-
-static bool test_nwrap_enum_r_passwd(struct torture_context *tctx,
- struct passwd **pwd_array_p,
- size_t *num_pwd_p)
-{
- struct passwd pwd, *pwdp;
- struct passwd *pwd_array = NULL;
- size_t num_pwd = 0;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing setpwent\n");
- setpwent();
-
- while (1) {
- torture_comment(tctx, "Testing getpwent_r\n");
-
- ret = getpwent_r(&pwd, buffer, sizeof(buffer), &pwdp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- break;
- }
- print_passwd(&pwd);
- if (pwd_array_p && num_pwd_p) {
- pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
- torture_assert(tctx, pwd_array, "out of memory");
- copy_passwd(tctx, &pwd, &pwd_array[num_pwd]);
- num_pwd++;
- }
- }
-
- torture_comment(tctx, "Testing endpwent\n");
- endpwent();
-
- if (pwd_array_p) {
- *pwd_array_p = pwd_array;
- }
- if (num_pwd_p) {
- *num_pwd_p = num_pwd;
- }
-
- return true;
-}
-
-static bool torture_assert_passwd_equal(struct torture_context *tctx,
- const struct passwd *p1,
- const struct passwd *p2,
- const char *comment)
-{
- torture_assert_str_equal(tctx, p1->pw_name, p2->pw_name, comment);
- torture_assert_str_equal(tctx, p1->pw_passwd, p2->pw_passwd, comment);
- torture_assert_int_equal(tctx, p1->pw_uid, p2->pw_uid, comment);
- torture_assert_int_equal(tctx, p1->pw_gid, p2->pw_gid, comment);
- torture_assert_str_equal(tctx, p1->pw_gecos, p2->pw_gecos, comment);
- torture_assert_str_equal(tctx, p1->pw_dir, p2->pw_dir, comment);
- torture_assert_str_equal(tctx, p1->pw_shell, p2->pw_shell, comment);
-
- return true;
-}
-
-static bool test_nwrap_passwd(struct torture_context *tctx)
-{
- int i;
- struct passwd *pwd, pwd1, pwd2;
- size_t num_pwd;
-
- torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
- "failed to enumerate passwd");
-
- for (i=0; i < num_pwd; i++) {
- torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name, &pwd1),
- "failed to call getpwnam for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd1,
- "getpwent and getpwnam gave different results");
- torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid, &pwd2),
- "failed to call getpwuid for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd2,
- "getpwent and getpwuid gave different results");
- torture_assert_passwd_equal(tctx, &pwd1, &pwd2,
- "getpwnam and getpwuid gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_passwd_r(struct torture_context *tctx)
-{
- int i;
- struct passwd *pwd, pwd1, pwd2;
- size_t num_pwd;
-
- torture_assert(tctx, test_nwrap_enum_r_passwd(tctx, &pwd, &num_pwd),
- "failed to enumerate passwd");
-
- for (i=0; i < num_pwd; i++) {
- torture_assert(tctx, test_nwrap_getpwnam_r(tctx, pwd[i].pw_name, &pwd1),
- "failed to call getpwnam_r for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd1,
- "getpwent_r and getpwnam_r gave different results");
- torture_assert(tctx, test_nwrap_getpwuid_r(tctx, pwd[i].pw_uid, &pwd2),
- "failed to call getpwuid_r for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd2,
- "getpwent_r and getpwuid_r gave different results");
- torture_assert_passwd_equal(tctx, &pwd1, &pwd2,
- "getpwnam_r and getpwuid_r gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_passwd_r_cross(struct torture_context *tctx)
-{
- int i;
- struct passwd *pwd, pwd1, pwd2, pwd3, pwd4;
- size_t num_pwd;
-
- torture_assert(tctx, test_nwrap_enum_r_passwd(tctx, &pwd, &num_pwd),
- "failed to enumerate passwd");
-
- for (i=0; i < num_pwd; i++) {
- torture_assert(tctx, test_nwrap_getpwnam_r(tctx, pwd[i].pw_name, &pwd1),
- "failed to call getpwnam_r for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd1,
- "getpwent_r and getpwnam_r gave different results");
- torture_assert(tctx, test_nwrap_getpwuid_r(tctx, pwd[i].pw_uid, &pwd2),
- "failed to call getpwuid_r for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd2,
- "getpwent_r and getpwuid_r gave different results");
- torture_assert_passwd_equal(tctx, &pwd1, &pwd2,
- "getpwnam_r and getpwuid_r gave different results");
- torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name, &pwd3),
- "failed to call getpwnam for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd3,
- "getpwent_r and getpwnam gave different results");
- torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid, &pwd4),
- "failed to call getpwuid for enumerated user");
- torture_assert_passwd_equal(tctx, &pwd[i], &pwd4,
- "getpwent_r and getpwuid gave different results");
- torture_assert_passwd_equal(tctx, &pwd3, &pwd4,
- "getpwnam and getpwuid gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_enum_group(struct torture_context *tctx,
- struct group **grp_array_p,
- size_t *num_grp_p)
-{
- struct group *grp;
- struct group *grp_array = NULL;
- size_t num_grp = 0;
-
- torture_comment(tctx, "Testing setgrent\n");
- setgrent();
-
- while ((grp = getgrent()) != NULL) {
- torture_comment(tctx, "Testing getgrent\n");
-
- print_group(grp);
- if (grp_array_p && num_grp_p) {
- grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
- torture_assert(tctx, grp_array, "out of memory");
- copy_group(tctx, grp, &grp_array[num_grp]);
- num_grp++;
- }
- }
-
- torture_comment(tctx, "Testing endgrent\n");
- endgrent();
-
- if (grp_array_p) {
- *grp_array_p = grp_array;
- }
- if (num_grp_p) {
- *num_grp_p = num_grp;
- }
-
- return true;
-}
-
-static bool test_nwrap_enum_r_group(struct torture_context *tctx,
- struct group **grp_array_p,
- size_t *num_grp_p)
-{
- struct group grp, *grpp;
- struct group *grp_array = NULL;
- size_t num_grp = 0;
- char buffer[4096];
- int ret;
-
- torture_comment(tctx, "Testing setgrent\n");
- setgrent();
-
- while (1) {
- torture_comment(tctx, "Testing getgrent_r\n");
-
- ret = getgrent_r(&grp, buffer, sizeof(buffer), &grpp);
- if (ret != 0) {
- if (ret != ENOENT) {
- torture_comment(tctx, "got %d return code\n", ret);
- }
- break;
- }
- print_group(&grp);
- if (grp_array_p && num_grp_p) {
- grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
- torture_assert(tctx, grp_array, "out of memory");
- copy_group(tctx, &grp, &grp_array[num_grp]);
- num_grp++;
- }
- }
-
- torture_comment(tctx, "Testing endgrent\n");
- endgrent();
-
- if (grp_array_p) {
- *grp_array_p = grp_array;
- }
- if (num_grp_p) {
- *num_grp_p = num_grp;
- }
-
- return true;
-}
-
-static bool torture_assert_group_equal(struct torture_context *tctx,
- const struct group *g1,
- const struct group *g2,
- const char *comment)
-{
- int i;
- torture_assert_str_equal(tctx, g1->gr_name, g2->gr_name, comment);
- torture_assert_str_equal(tctx, g1->gr_passwd, g2->gr_passwd, comment);
- torture_assert_int_equal(tctx, g1->gr_gid, g2->gr_gid, comment);
- if (g1->gr_mem && !g2->gr_mem) {
- return false;
- }
- if (!g1->gr_mem && g2->gr_mem) {
- return false;
- }
- if (!g1->gr_mem && !g2->gr_mem) {
- return true;
- }
- for (i=0; g1->gr_mem[i] && g2->gr_mem[i]; i++) {
- torture_assert_str_equal(tctx, g1->gr_mem[i], g2->gr_mem[i], comment);
- }
-
- return true;
-}
-
-static bool test_nwrap_group(struct torture_context *tctx)
-{
- int i;
- struct group *grp, grp1, grp2;
- size_t num_grp;
-
- torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
- "failed to enumerate group");
-
- for (i=0; i < num_grp; i++) {
- torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name, &grp1),
- "failed to call getgrnam for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp1,
- "getgrent and getgrnam gave different results");
- torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid, &grp2),
- "failed to call getgrgid for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp2,
- "getgrent and getgrgid gave different results");
- torture_assert_group_equal(tctx, &grp1, &grp2,
- "getgrnam and getgrgid gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_group_r(struct torture_context *tctx)
-{
- int i;
- struct group *grp, grp1, grp2;
- size_t num_grp;
-
- torture_assert(tctx, test_nwrap_enum_r_group(tctx, &grp, &num_grp),
- "failed to enumerate group");
-
- for (i=0; i < num_grp; i++) {
- torture_assert(tctx, test_nwrap_getgrnam_r(tctx, grp[i].gr_name, &grp1),
- "failed to call getgrnam_r for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp1,
- "getgrent_r and getgrnam_r gave different results");
- torture_assert(tctx, test_nwrap_getgrgid_r(tctx, grp[i].gr_gid, &grp2),
- "failed to call getgrgid_r for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp2,
- "getgrent_r and getgrgid_r gave different results");
- torture_assert_group_equal(tctx, &grp1, &grp2,
- "getgrnam_r and getgrgid_r gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_group_r_cross(struct torture_context *tctx)
-{
- int i;
- struct group *grp, grp1, grp2, grp3, grp4;
- size_t num_grp;
-
- torture_assert(tctx, test_nwrap_enum_r_group(tctx, &grp, &num_grp),
- "failed to enumerate group");
-
- for (i=0; i < num_grp; i++) {
- torture_assert(tctx, test_nwrap_getgrnam_r(tctx, grp[i].gr_name, &grp1),
- "failed to call getgrnam_r for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp1,
- "getgrent_r and getgrnam_r gave different results");
- torture_assert(tctx, test_nwrap_getgrgid_r(tctx, grp[i].gr_gid, &grp2),
- "failed to call getgrgid_r for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp2,
- "getgrent_r and getgrgid_r gave different results");
- torture_assert_group_equal(tctx, &grp1, &grp2,
- "getgrnam_r and getgrgid_r gave different results");
- torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name, &grp3),
- "failed to call getgrnam for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp3,
- "getgrent_r and getgrnam gave different results");
- torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid, &grp4),
- "failed to call getgrgid for enumerated user");
- torture_assert_group_equal(tctx, &grp[i], &grp4,
- "getgrent_r and getgrgid gave different results");
- torture_assert_group_equal(tctx, &grp3, &grp4,
- "getgrnam and getgrgid gave different results");
- }
-
- return true;
-}
-
-static bool test_nwrap_getgrouplist(struct torture_context *tctx,
- const char *user,
- gid_t gid,
- gid_t **gids_p,
- int *num_gids_p)
-{
- int ret;
- int num_groups = 0;
- gid_t *groups = NULL;
-
- torture_comment(tctx, "Testing getgrouplist: %s\n", user);
-
- ret = getgrouplist(user, gid, NULL, &num_groups);
- if (ret == -1 || num_groups != 0) {
-
- groups = talloc_array(tctx, gid_t, num_groups);
- torture_assert(tctx, groups, "out of memory\n");
-
- ret = getgrouplist(user, gid, groups, &num_groups);
- }
-
- torture_assert(tctx, (ret != -1), "failed to call getgrouplist");
-
- torture_comment(tctx, "%s is member in %d groups\n", user, num_groups);
-
- if (gids_p) {
- *gids_p = groups;
- }
- if (num_gids_p) {
- *num_gids_p = num_groups;
- }
-
- return true;
-}
-
-static bool test_nwrap_user_in_group(struct torture_context *tctx,
- const struct passwd *pwd,
- const struct group *grp)
-{
- int i;
-
- for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
- if (strequal(grp->gr_mem[i], pwd->pw_name)) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool test_nwrap_membership_user(struct torture_context *tctx,
- const struct passwd *pwd,
- struct group *grp_array,
- size_t num_grp)
-{
- int num_user_groups = 0;
- int num_user_groups_from_enum = 0;
- gid_t *user_groups = NULL;
- int g, i;
- bool primary_group_had_user_member = false;
-
- torture_assert(tctx, test_nwrap_getgrouplist(tctx,
- pwd->pw_name,
- pwd->pw_gid,
- &user_groups,
- &num_user_groups),
- "failed to test getgrouplist");
-
- for (g=0; g < num_user_groups; g++) {
- torture_assert(tctx, test_nwrap_getgrgid(tctx, user_groups[g], NULL),
- "failed to find the group the user is a member of");
- }
-
-
- for (i=0; i < num_grp; i++) {
-
- struct group grp = grp_array[i];
-
- if (test_nwrap_user_in_group(tctx, pwd, &grp)) {
-
- struct group current_grp;
- num_user_groups_from_enum++;
-
- torture_assert(tctx, test_nwrap_getgrnam(tctx, grp.gr_name, &current_grp),
- "failed to find the group the user is a member of");
-
- if (current_grp.gr_gid == pwd->pw_gid) {
- torture_comment(tctx, "primary group %s of user %s lists user as member\n",
- current_grp.gr_name,
- pwd->pw_name);
- primary_group_had_user_member = true;
- }
-
- continue;
- }
- }
-
- if (!primary_group_had_user_member) {
- num_user_groups_from_enum++;
- }
-
- torture_assert_int_equal(tctx, num_user_groups, num_user_groups_from_enum,
- "getgrouplist and real inspection of grouplist gave different results\n");
-
- return true;
-}
-
-static bool test_nwrap_membership(struct torture_context *tctx)
-{
- const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
- const char *old_group = getenv("NSS_WRAPPER_GROUP");
- struct passwd *pwd;
- size_t num_pwd;
- struct group *grp;
- size_t num_grp;
- int i;
-
- if (!old_pwd || !old_group) {
- torture_comment(tctx, "ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n");
- torture_skip(tctx, "nothing to test\n");
- }
-
- torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
- "failed to enumerate passwd");
- torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
- "failed to enumerate group");
-
- for (i=0; i < num_pwd; i++) {
-
- torture_assert(tctx, test_nwrap_membership_user(tctx, &pwd[i], grp, num_grp),
- "failed to test membership for user");
-
- }
-
- return true;
-}
-
-static bool test_nwrap_enumeration(struct torture_context *tctx)
-{
- const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
- const char *old_group = getenv("NSS_WRAPPER_GROUP");
-
- if (!old_pwd || !old_group) {
- torture_comment(tctx, "ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n");
- torture_skip(tctx, "nothing to test\n");
- }
-
- torture_assert(tctx, test_nwrap_passwd(tctx),
- "failed to test users");
- torture_assert(tctx, test_nwrap_group(tctx),
- "failed to test groups");
-
- return true;
-}
-
-static bool test_nwrap_reentrant_enumeration(struct torture_context *tctx)
-{
- const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
- const char *old_group = getenv("NSS_WRAPPER_GROUP");
-
- if (!old_pwd || !old_group) {
- torture_comment(tctx, "ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n");
- torture_skip(tctx, "nothing to test\n");
- }
-
- torture_comment(tctx, "Testing re-entrant calls\n");
-
- torture_assert(tctx, test_nwrap_passwd_r(tctx),
- "failed to test users");
- torture_assert(tctx, test_nwrap_group_r(tctx),
- "failed to test groups");
-
- return true;
-}
-
-static bool test_nwrap_reentrant_enumeration_crosschecks(struct torture_context *tctx)
-{
- const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
- const char *old_group = getenv("NSS_WRAPPER_GROUP");
-
- if (!old_pwd || !old_group) {
- torture_comment(tctx, "ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n");
- torture_skip(tctx, "nothing to test\n");
- }
-
- torture_comment(tctx, "Testing re-entrant calls with cross checks\n");
-
- torture_assert(tctx, test_nwrap_passwd_r_cross(tctx),
- "failed to test users");
- torture_assert(tctx, test_nwrap_group_r_cross(tctx),
- "failed to test groups");
-
- return true;
-}
-
-static bool test_nwrap_passwd_duplicates(struct torture_context *tctx)
-{
- int i, d;
- struct passwd *pwd;
- size_t num_pwd;
- int duplicates = 0;
-
- torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
- "failed to enumerate passwd");
-
- for (i=0; i < num_pwd; i++) {
- const char *current_name = pwd[i].pw_name;
- for (d=0; d < num_pwd; d++) {
- const char *dup_name = pwd[d].pw_name;
- if (d == i) {
- continue;
- }
- if (!strequal(current_name, dup_name)) {
- continue;
- }
-
- torture_warning(tctx, "found duplicate names:");
- print_passwd(&pwd[d]);
- print_passwd(&pwd[i]);
- duplicates++;
- }
- }
-
- if (duplicates) {
- torture_fail(tctx, talloc_asprintf(tctx, "found %d duplicate names", duplicates));
- }
-
- return true;
-}
-
-static bool test_nwrap_group_duplicates(struct torture_context *tctx)
-{
- int i, d;
- struct group *grp;
- size_t num_grp;
- int duplicates = 0;
-
- torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
- "failed to enumerate group");
-
- for (i=0; i < num_grp; i++) {
- const char *current_name = grp[i].gr_name;
- for (d=0; d < num_grp; d++) {
- const char *dup_name = grp[d].gr_name;
- if (d == i) {
- continue;
- }
- if (!strequal(current_name, dup_name)) {
- continue;
- }
-
- torture_warning(tctx, "found duplicate names:");
- print_group(&grp[d]);
- print_group(&grp[i]);
- duplicates++;
- }
- }
-
- if (duplicates) {
- torture_fail(tctx, talloc_asprintf(tctx, "found %d duplicate names", duplicates));
- }
-
- return true;
-}
-
-
-static bool test_nwrap_duplicates(struct torture_context *tctx)
-{
- const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
- const char *old_group = getenv("NSS_WRAPPER_GROUP");
-
- if (!old_pwd || !old_group) {
- torture_comment(tctx, "ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n");
- torture_skip(tctx, "nothing to test\n");
- }
-
- torture_assert(tctx, test_nwrap_passwd_duplicates(tctx),
- "failed to test users");
- torture_assert(tctx, test_nwrap_group_duplicates(tctx),
- "failed to test groups");
-
- return true;
-}
-
-
-struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx)
-{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "nss-wrapper");
-
- torture_suite_add_simple_test(suite, "enumeration", test_nwrap_enumeration);
- torture_suite_add_simple_test(suite, "reentrant enumeration", test_nwrap_reentrant_enumeration);
- torture_suite_add_simple_test(suite, "reentrant enumeration crosschecks", test_nwrap_reentrant_enumeration_crosschecks);
- torture_suite_add_simple_test(suite, "membership", test_nwrap_membership);
- torture_suite_add_simple_test(suite, "duplicates", test_nwrap_duplicates);
-
- return suite;
-}
diff --git a/lib/nss_wrapper/wscript b/lib/nss_wrapper/wscript
index 5cfff1f76cb..34026c06ed7 100644
--- a/lib/nss_wrapper/wscript
+++ b/lib/nss_wrapper/wscript
@@ -1,17 +1,106 @@
#!/usr/bin/env python
-import Options
+import os
-def set_options(opt):
- gr = opt.option_group('developer options')
- gr.add_option('--enable-nss-wrapper',
- help=("Turn on nss wrapper library (default=no)"),
- action="store_true", dest='enable_nss_wrapper', default=False)
+VERSION="1.0.2"
def configure(conf):
- if (Options.options.enable_nss_wrapper or
- Options.options.developer or
- Options.options.enable_selftest):
- conf.DEFINE('NSS_WRAPPER', 1)
- conf.ADD_GLOBAL_DEPENDENCY('nss_wrapper')
+ if conf.CHECK_BUNDLED_SYSTEM('nss_wrapper', minversion=VERSION, set_target=False):
+ conf.DEFINE('USING_SYSTEM_NSS_WRAPPER', 1)
+ libnss_wrapper_so_path = 'libnss_wrapper.so'
+ else:
+ # check HAVE_GCC_THREAD_LOCAL_STORAGE
+ conf.CHECK_CODE('''
+ __thread int tls;
+ int main(void) {
+ return 0;
+ }
+ ''',
+ 'HAVE_GCC_THREAD_LOCAL_STORAGE',
+ addmain=False,
+ msg='Checking for thread local storage')
+
+ # check HAVE_DESTRUCTOR_ATTRIBUTE
+ conf.CHECK_CODE('''
+ void test_destructor_attribute(void) __attribute__ ((destructor));
+
+ void test_destructor_attribute(void)
+ {
+ return;
+ }
+
+ int main(void) {
+ return 0;
+ }
+ ''',
+ 'HAVE_DESTRUCTOR_ATTRIBUTE',
+ addmain=False,
+ msg='Checking for library destructor support')
+
+ conf.CHECK_FUNCS('gethostbyaddr_r gethostbyname_r')
+ # Solaris
+ conf.CHECK_FUNCS('__posix_getpwnam_r __posix_getpwuid_r')
+ conf.CHECK_FUNCS('__posix_getgrgid_r __posix_getgrnam_r')
+
+ conf.CHECK_FUNCS_IN('nsl',
+ 'gethostname',
+ checklibc=True,
+ headers='unistd.h')
+
+ # Prototype checks
+ conf.CHECK_C_PROTOTYPE('getpwent_r',
+ 'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)',
+ define='HAVE_SOLARIS_GETPWENT_R', headers='unistd.h pwd.h')
+ conf.CHECK_C_PROTOTYPE('getpwnam_r',
+ 'int getpwnam_r(const char *name, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)',
+ define='HAVE_SOLARIS_GETPWNAM_R', headers='unistd.h pwd.h')
+ conf.CHECK_C_PROTOTYPE('getpwuid_r',
+ 'int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)',
+ define='HAVE_SOLARIS_GETPWUID_R', headers='unistd.h pwd.h')
+ conf.CHECK_C_PROTOTYPE('getgrent_r',
+ 'struct group *getgrent_r(struct group *src, char *buf, int buflen)',
+ define='SOLARIS_GETGRENT_R', headers='unistd.h grp.h')
+ conf.CHECK_C_PROTOTYPE('getgrnam_r',
+ 'int getgrnam_r(const char *name, struct group *grp, char *buf, int buflen, struct group **pgrp)',
+ define='HAVE_SOLARIS_GETGRNAM_R', headers='unistd.h grp.h')
+ conf.CHECK_C_PROTOTYPE('getgrgid_r',
+ 'int getgrgid_r(gid_t gid, struct group *grp, char *buf, int buflen, struct group **pgrp)',
+ define='HAVE_SOLARIS_GETGRGID_R', headers='unistd.h grp.h')
+ conf.CHECK_C_PROTOTYPE('sethostent',
+ 'int sethostent(int stayopen)',
+ define='HAVE_SOLARIS_SETHOSTENT', headers='unistd.h netdb.h')
+ conf.CHECK_C_PROTOTYPE('endhostent',
+ 'int endhostent(void)',
+ define='HAVE_SOLARIS_ENDHOSTENT', headers='unistd.h netdb.h')
+ conf.CHECK_C_PROTOTYPE('gethostname',
+ 'int gethostname(char *name, int len)',
+ define='HAVE_SOLARIS_GETHOSTNAME', headers='unistd.h netdb.h')
+ conf.CHECK_C_PROTOTYPE('setgrent',
+ 'int setgrent(void)',
+ define='HAVE_BSD_SETGRENT', headers='unistd.h grp.h')
+ conf.CHECK_C_PROTOTYPE('getnameinfo',
+ 'int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, int flags)',
+ define='HAVE_LINUX_GETNAMEINFO', headers='unistd.h netdb.h')
+ conf.CHECK_C_PROTOTYPE('getnameinfo',
+ 'int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, unsigned int flags)',
+ define='HAVE_LINUX_GETNAMEINFO_UNSIGNED', headers='unistd.h netdb.h')
+
+ # Create full path to nss_wrapper
+ srcdir = os.path.realpath(conf.srcdir)
+ libnss_wrapper_so_path = srcdir + '/bin/default/lib/nss_wrapper/libnss-wrapper.so'
+
+ conf.DEFINE('LIBNSS_WRAPPER_SO_PATH', libnss_wrapper_so_path)
+ conf.DEFINE('NSS_WRAPPER', 1)
+
+def build(bld):
+ if not bld.CONFIG_SET("USING_SYSTEM_NSS_WRAPPER"):
+ # We need to do it this way or the library wont work.
+ # Using private_library=True will add symbol version which
+ # breaks preloading!
+ bld.SAMBA_LIBRARY('nss_wrapper',
+ source='nss_wrapper.c',
+ cflags='-DNDEBUG',
+ deps='dl',
+ install=False,
+ realname='libnss-wrapper.so')
diff --git a/lib/nss_wrapper/wscript_build b/lib/nss_wrapper/wscript_build
deleted file mode 100644
index 5f9df3a600c..00000000000
--- a/lib/nss_wrapper/wscript_build
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python
-
-
-bld.SAMBA_LIBRARY('nss_wrapper',
- source='nss_wrapper.c',
- deps='replace',
- private_library=True,
- enabled=bld.CONFIG_SET("NSS_WRAPPER"),
- )
-
diff --git a/wscript b/wscript
index 49f0460ab64..fe1e1d457b5 100644
--- a/wscript
+++ b/wscript
@@ -40,7 +40,6 @@ def set_options(opt):
opt.RECURSE('lib/ntdb')
opt.RECURSE('selftest')
opt.RECURSE('source4/lib/tls')
- opt.RECURSE('lib/nss_wrapper')
opt.RECURSE('lib/socket_wrapper')
opt.RECURSE('pidl')
opt.RECURSE('source3')