dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0011-Util-added-facility-to-load-nss-lib-syms.patch

841ac7
From ac1c193a3d8d2e0be39fc647e9a4b616b7513a45 Mon Sep 17 00:00:00 2001
841ac7
From: Alexey Tikhonov <atikhono@redhat.com>
841ac7
Date: Fri, 22 Mar 2019 15:33:22 +0100
841ac7
Subject: [PATCH 11/15] Util: added facility to load nss lib syms
841ac7
841ac7
Factored out (from proxy provider code) utility to load NSS symbols
841ac7
from shared library.
841ac7
841ac7
Related: https://pagure.io/SSSD/sssd/issue/3964
841ac7
841ac7
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
841ac7
(cherry picked from commit 6a6aad282e56a5f0bf52f20b98c1764d43abbbaf)
841ac7
841ac7
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
841ac7
---
841ac7
 Makefile.am                      |   2 +
841ac7
 src/providers/proxy/proxy.h      |  54 +---------
841ac7
 src/providers/proxy/proxy_init.c | 163 ++++++++++++-------------------
841ac7
 src/util/nss_dl_load.c           | 106 ++++++++++++++++++++
841ac7
 src/util/nss_dl_load.h           |  81 +++++++++++++++
841ac7
 5 files changed, 255 insertions(+), 151 deletions(-)
841ac7
 create mode 100644 src/util/nss_dl_load.c
841ac7
 create mode 100644 src/util/nss_dl_load.h
841ac7
841ac7
diff --git a/Makefile.am b/Makefile.am
841ac7
index 4475b3d12..05f5f4e26 100644
841ac7
--- a/Makefile.am
841ac7
+++ b/Makefile.am
841ac7
@@ -677,6 +677,7 @@ dist_noinst_HEADERS = \
841ac7
     src/util/inotify.h \
841ac7
     src/util/sss_iobuf.h \
841ac7
     src/util/tev_curl.h \
841ac7
+    src/util/nss_dl_load.h \
841ac7
     src/monitor/monitor.h \
841ac7
     src/monitor/monitor_interfaces.h \
841ac7
     src/monitor/monitor_iface_generated.h \
841ac7
@@ -3996,6 +3997,7 @@ libsss_proxy_la_SOURCES = \
841ac7
     src/providers/proxy/proxy_services.c \
841ac7
     src/providers/proxy/proxy_auth.c \
841ac7
     src/providers/proxy/proxy_iface_generated.c \
841ac7
+    src//util/nss_dl_load.c \
841ac7
     $(NULL)
841ac7
 libsss_proxy_la_CFLAGS = \
841ac7
     $(AM_CFLAGS)
841ac7
diff --git a/src/providers/proxy/proxy.h b/src/providers/proxy/proxy.h
841ac7
index 3b0475d08..6debd4953 100644
841ac7
--- a/src/providers/proxy/proxy.h
841ac7
+++ b/src/providers/proxy/proxy.h
841ac7
@@ -25,11 +25,7 @@
841ac7
 #ifndef __PROXY_H__
841ac7
 #define __PROXY_H__
841ac7
 
841ac7
-#include <nss.h>
841ac7
 #include <errno.h>
841ac7
-#include <pwd.h>
841ac7
-#include <grp.h>
841ac7
-#include <dlfcn.h>
841ac7
 #include <sys/types.h>
841ac7
 #include <sys/wait.h>
841ac7
 
841ac7
@@ -37,58 +33,13 @@
841ac7
 #include <security/pam_modules.h>
841ac7
 
841ac7
 #include "util/util.h"
841ac7
+#include "util/nss_dl_load.h"
841ac7
 #include "providers/backend.h"
841ac7
 #include "db/sysdb.h"
841ac7
-#include "sss_client/nss_compat.h"
841ac7
 #include <dhash.h>
841ac7
 
841ac7
 #define PROXY_CHILD_PATH "/org/freedesktop/sssd/proxychild"
841ac7
 
841ac7
-struct proxy_nss_ops {
841ac7
-    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*setpwent)(void);
841ac7
-    enum nss_status (*getpwent_r)(struct passwd *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*endpwent)(void);
841ac7
-
841ac7
-    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*setgrent)(void);
841ac7
-    enum nss_status (*getgrent_r)(struct group *result,
841ac7
-                                  char *buffer, size_t buflen, int *errnop);
841ac7
-    enum nss_status (*endgrent)(void);
841ac7
-    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
841ac7
-                                      long int *start, long int *size,
841ac7
-                                      gid_t **groups, long int limit,
841ac7
-                                      int *errnop);
841ac7
-    enum nss_status (*setnetgrent)(const char *netgroup,
841ac7
-                                   struct __netgrent *result);
841ac7
-    enum nss_status (*getnetgrent_r)(struct __netgrent *result, char *buffer,
841ac7
-                                     size_t buflen, int *errnop);
841ac7
-    enum nss_status (*endnetgrent)(struct __netgrent *result);
841ac7
-
841ac7
-    /* Services */
841ac7
-    enum nss_status (*getservbyname_r)(const char *name,
841ac7
-                                        const char *protocol,
841ac7
-                                        struct servent *result,
841ac7
-                                        char *buffer, size_t buflen,
841ac7
-                                        int *errnop);
841ac7
-    enum nss_status (*getservbyport_r)(int port, const char *protocol,
841ac7
-                                        struct servent *result,
841ac7
-                                        char *buffer, size_t buflen,
841ac7
-                                        int *errnop);
841ac7
-    enum nss_status (*setservent)(void);
841ac7
-    enum nss_status (*getservent_r)(struct servent *result,
841ac7
-                                    char *buffer, size_t buflen,
841ac7
-                                    int *errnop);
841ac7
-    enum nss_status (*endservent)(void);
841ac7
-};
841ac7
-
841ac7
 struct authtok_conv {
841ac7
     struct sss_auth_token *authtok;
841ac7
     struct sss_auth_token *newauthtok;
841ac7
@@ -99,8 +50,7 @@ struct authtok_conv {
841ac7
 struct proxy_id_ctx {
841ac7
     struct be_ctx *be;
841ac7
     bool fast_alias;
841ac7
-    struct proxy_nss_ops ops;
841ac7
-    void *handle;
841ac7
+    struct sss_nss_ops ops;
841ac7
 };
841ac7
 
841ac7
 struct proxy_auth_ctx {
841ac7
diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c
841ac7
index 7d997cb16..e3273d9a7 100644
841ac7
--- a/src/providers/proxy/proxy_init.c
841ac7
+++ b/src/providers/proxy/proxy_init.c
841ac7
@@ -27,44 +27,15 @@
841ac7
 #include "util/sss_format.h"
841ac7
 #include "providers/proxy/proxy.h"
841ac7
 
841ac7
-#define NSS_FN_NAME "_nss_%s_%s"
841ac7
-
841ac7
 #define OPT_MAX_CHILDREN_DEFAULT 10
841ac7
 
841ac7
-#define ERROR_INITGR "The '%s' library does not provides the " \
841ac7
-                         "_nss_XXX_initgroups_dyn function!\n" \
841ac7
-                         "initgroups will be slow as it will require " \
841ac7
-                         "full groups enumeration!\n"
841ac7
-#define ERROR_NETGR "The '%s' library does not support netgroups.\n"
841ac7
-#define ERROR_SERV "The '%s' library does not support services.\n"
841ac7
-
841ac7
-static void *proxy_dlsym(void *handle,
841ac7
-                         const char *name,
841ac7
-                         const char *libname)
841ac7
-{
841ac7
-    char *funcname;
841ac7
-    void *funcptr;
841ac7
-
841ac7
-    funcname = talloc_asprintf(NULL, NSS_FN_NAME, libname, name);
841ac7
-    if (funcname == NULL) {
841ac7
-        return NULL;
841ac7
-    }
841ac7
-
841ac7
-    funcptr = dlsym(handle, funcname);
841ac7
-    talloc_free(funcname);
841ac7
-
841ac7
-    return funcptr;
841ac7
-}
841ac7
-
841ac7
 static errno_t proxy_id_conf(TALLOC_CTX *mem_ctx,
841ac7
                              struct be_ctx *be_ctx,
841ac7
                              char **_libname,
841ac7
-                             char **_libpath,
841ac7
                              bool *_fast_alias)
841ac7
 {
841ac7
     TALLOC_CTX *tmp_ctx;
841ac7
     char *libname;
841ac7
-    char *libpath;
841ac7
     bool fast_alias;
841ac7
     errno_t ret;
841ac7
 
841ac7
@@ -94,15 +65,7 @@ static errno_t proxy_id_conf(TALLOC_CTX *mem_ctx,
841ac7
         goto done;
841ac7
     }
841ac7
 
841ac7
-    libpath = talloc_asprintf(tmp_ctx, "libnss_%s.so.2", libname);
841ac7
-    if (libpath == NULL) {
841ac7
-        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
841ac7
-        ret = ENOMEM;
841ac7
-        goto done;
841ac7
-    }
841ac7
-
841ac7
     *_libname = talloc_steal(mem_ctx, libname);
841ac7
-    *_libpath = talloc_steal(mem_ctx, libpath);
841ac7
     *_fast_alias = fast_alias;
841ac7
 
841ac7
     ret = EOK;
841ac7
@@ -113,57 +76,6 @@ done:
841ac7
     return ret;
841ac7
 }
841ac7
 
841ac7
-static errno_t proxy_id_load_symbols(struct proxy_nss_ops *ops,
841ac7
-                                     const char *libname,
841ac7
-                                     void *handle)
841ac7
-{
841ac7
-    int i;
841ac7
-    struct {void **dest;
841ac7
-            const char *name;
841ac7
-            const char *custom_error;
841ac7
-            bool is_fatal;
841ac7
-    } symbols[] = {
841ac7
-        {(void**)&ops->getpwnam_r, "getpwnam_r", NULL, true},
841ac7
-        {(void**)&ops->getpwuid_r, "getpwuid_r", NULL, true},
841ac7
-        {(void**)&ops->setpwent, "setpwent", NULL, true},
841ac7
-        {(void**)&ops->getpwent_r, "getpwent_r", NULL, true},
841ac7
-        {(void**)&ops->endpwent, "endpwent", NULL, true},
841ac7
-        {(void**)&ops->getgrnam_r, "getgrnam_r", NULL, true},
841ac7
-        {(void**)&ops->getgrgid_r, "getgrgid_r", NULL, true},
841ac7
-        {(void**)&ops->setgrent, "setgrent", NULL, true},
841ac7
-        {(void**)&ops->getgrent_r, "getgrent_r", NULL, true},
841ac7
-        {(void**)&ops->endgrent, "endgrent", NULL, true},
841ac7
-        {(void**)&ops->initgroups_dyn, "initgroups_dyn", ERROR_INITGR, false},
841ac7
-        {(void**)&ops->setnetgrent, "setnetgrent", ERROR_NETGR, false},
841ac7
-        {(void**)&ops->getnetgrent_r, "getnetgrent_r", ERROR_NETGR, false},
841ac7
-        {(void**)&ops->endnetgrent, "endnetgrent", ERROR_NETGR, false},
841ac7
-        {(void**)&ops->getservbyname_r, "getservbyname_r", ERROR_SERV, false},
841ac7
-        {(void**)&ops->getservbyport_r, "getservbyport_r", ERROR_SERV, false},
841ac7
-        {(void**)&ops->setservent, "setservent", ERROR_SERV, false},
841ac7
-        {(void**)&ops->getservent_r, "getservent_r", ERROR_SERV, false},
841ac7
-        {(void**)&ops->endservent, "endservent", ERROR_SERV, false},
841ac7
-        {NULL, NULL, NULL, false}
841ac7
-    };
841ac7
-
841ac7
-    for (i = 0; symbols[i].dest != NULL; i++) {
841ac7
-        *symbols[i].dest = proxy_dlsym(handle, symbols[i].name, libname);
841ac7
-        if (*symbols[i].dest == NULL) {
841ac7
-            DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_%s, "
841ac7
-                  "error: %s.\n", libname, symbols[i].name, dlerror());
841ac7
-
841ac7
-            if (symbols[i].custom_error != NULL) {
841ac7
-                DEBUG(SSSDBG_CRIT_FAILURE, symbols[i].custom_error, libname);
841ac7
-            }
841ac7
-
841ac7
-            if (symbols[i].is_fatal) {
841ac7
-                return ELIBBAD;
841ac7
-            }
841ac7
-        }
841ac7
-    }
841ac7
-
841ac7
-    return EOK;
841ac7
-}
841ac7
-
841ac7
 static errno_t proxy_setup_sbus(TALLOC_CTX *mem_ctx,
841ac7
                                 struct proxy_auth_ctx *ctx,
841ac7
                                 struct be_ctx *be_ctx)
841ac7
@@ -310,6 +222,68 @@ errno_t sssm_proxy_init(TALLOC_CTX *mem_ctx,
841ac7
     return EOK;
841ac7
 }
841ac7
 
841ac7
+
841ac7
+#define ERROR_INITGR "The '%s' library does not provides the " \
841ac7
+                         "_nss_XXX_initgroups_dyn function!\n" \
841ac7
+                         "initgroups will be slow as it will require " \
841ac7
+                         "full groups enumeration!\n"
841ac7
+#define ERROR_NETGR "The '%s' library does not support netgroups.\n"
841ac7
+#define ERROR_SERV "The '%s' library does not support services.\n"
841ac7
+
841ac7
+static errno_t proxy_load_nss_symbols(struct sss_nss_ops *ops,
841ac7
+                                      const char *libname)
841ac7
+{
841ac7
+    errno_t ret;
841ac7
+    size_t i;
841ac7
+
841ac7
+    ret = sss_load_nss_symbols(ops, libname);
841ac7
+    if (ret != EOK) {
841ac7
+        return ret;
841ac7
+    }
841ac7
+
841ac7
+    struct {
841ac7
+        void *fptr;
841ac7
+        const char* custom_error;
841ac7
+    } optional_syms[] = {
841ac7
+        {(void*)ops->initgroups_dyn,  ERROR_INITGR},
841ac7
+        {(void*)ops->setnetgrent,     ERROR_NETGR},
841ac7
+        {(void*)ops->getnetgrent_r,   ERROR_NETGR},
841ac7
+        {(void*)ops->endnetgrent,     ERROR_NETGR},
841ac7
+        {(void*)ops->getservbyname_r, ERROR_SERV},
841ac7
+        {(void*)ops->getservbyport_r, ERROR_SERV},
841ac7
+        {(void*)ops->setservent,      ERROR_SERV},
841ac7
+        {(void*)ops->getservent_r,    ERROR_SERV},
841ac7
+        {(void*)ops->endservent,      ERROR_SERV},
841ac7
+    };
841ac7
+    for (i = 0; i < sizeof(optional_syms) / sizeof(optional_syms[0]); ++i) {
841ac7
+        if (!optional_syms[i].fptr) {
841ac7
+            DEBUG(SSSDBG_CRIT_FAILURE, optional_syms[i].custom_error, libname);
841ac7
+        }
841ac7
+    }
841ac7
+
841ac7
+    void *mandatory_syms[] = {
841ac7
+        (void*)ops->getpwnam_r,
841ac7
+        (void*)ops->getpwuid_r,
841ac7
+        (void*)ops->setpwent,
841ac7
+        (void*)ops->getpwent_r,
841ac7
+        (void*)ops->endpwent,
841ac7
+        (void*)ops->getgrnam_r,
841ac7
+        (void*)ops->getgrgid_r,
841ac7
+        (void*)ops->setgrent,
841ac7
+        (void*)ops->getgrent_r,
841ac7
+        (void*)ops->endgrent,
841ac7
+    };
841ac7
+    for (i = 0; i < sizeof(mandatory_syms)/sizeof(mandatory_syms[0]); ++i) {
841ac7
+        if (!mandatory_syms[i]) {
841ac7
+            DEBUG(SSSDBG_CRIT_FAILURE, "The '%s' library does not provide mandatory function", libname);
841ac7
+            return ELIBBAD;
841ac7
+        }
841ac7
+    }
841ac7
+
841ac7
+    return EOK;
841ac7
+}
841ac7
+
841ac7
+
841ac7
 errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx,
841ac7
                            struct be_ctx *be_ctx,
841ac7
                            void *module_data,
841ac7
@@ -317,7 +291,6 @@ errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx,
841ac7
 {
841ac7
     struct proxy_id_ctx *ctx;
841ac7
     char *libname;
841ac7
-    char *libpath;
841ac7
     errno_t ret;
841ac7
 
841ac7
     ctx = talloc_zero(mem_ctx, struct proxy_id_ctx);
841ac7
@@ -327,20 +300,12 @@ errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx,
841ac7
 
841ac7
     ctx->be = be_ctx;
841ac7
 
841ac7
-    ret = proxy_id_conf(ctx, be_ctx, &libname, &libpath, &ctx->fast_alias);
841ac7
+    ret = proxy_id_conf(ctx, be_ctx, &libname, &ctx->fast_alias);
841ac7
     if (ret != EOK) {
841ac7
         goto done;
841ac7
     }
841ac7
 
841ac7
-    ctx->handle = dlopen(libpath, RTLD_NOW);
841ac7
-    if (ctx->handle == NULL) {
841ac7
-        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module, "
841ac7
-              "error: %s\n", libpath, dlerror());
841ac7
-        ret = ELIBACC;
841ac7
-        goto done;
841ac7
-    }
841ac7
-
841ac7
-    ret = proxy_id_load_symbols(&ctx->ops, libname, ctx->handle);
841ac7
+    ret = proxy_load_nss_symbols(&ctx->ops, libname);
841ac7
     if (ret != EOK) {
841ac7
         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load NSS symbols [%d]: %s\n",
841ac7
               ret, sss_strerror(ret));
841ac7
diff --git a/src/util/nss_dl_load.c b/src/util/nss_dl_load.c
841ac7
new file mode 100644
841ac7
index 000000000..60df33376
841ac7
--- /dev/null
841ac7
+++ b/src/util/nss_dl_load.c
841ac7
@@ -0,0 +1,106 @@
841ac7
+/*
841ac7
+    Copyright (C) 2019 Red Hat
841ac7
+
841ac7
+    This program is free software; you can redistribute it and/or modify
841ac7
+    it under the terms of the GNU General Public License as published by
841ac7
+    the Free Software Foundation; either version 3 of the License, or
841ac7
+    (at your option) any later version.
841ac7
+
841ac7
+    This program is distributed in the hope that it will be useful,
841ac7
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
841ac7
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
841ac7
+    GNU General Public License for more details.
841ac7
+
841ac7
+    You should have received a copy of the GNU General Public License
841ac7
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
841ac7
+*/
841ac7
+
841ac7
+
841ac7
+#include <dlfcn.h>
841ac7
+#include <talloc.h>
841ac7
+#include <stdbool.h>
841ac7
+#include <errno.h>
841ac7
+
841ac7
+#include "util/util_errors.h"
841ac7
+#include "util/debug.h"
841ac7
+#include "nss_dl_load.h"
841ac7
+
841ac7
+
841ac7
+#define NSS_FN_NAME "_nss_%s_%s"
841ac7
+
841ac7
+
841ac7
+static void *proxy_dlsym(void *handle,
841ac7
+                         const char *name,
841ac7
+                         const char *libname)
841ac7
+{
841ac7
+    char *funcname;
841ac7
+    void *funcptr;
841ac7
+
841ac7
+    funcname = talloc_asprintf(NULL, NSS_FN_NAME, libname, name);
841ac7
+    if (funcname == NULL) {
841ac7
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
841ac7
+        return NULL;
841ac7
+    }
841ac7
+
841ac7
+    funcptr = dlsym(handle, funcname);
841ac7
+    talloc_free(funcname);
841ac7
+
841ac7
+    return funcptr;
841ac7
+}
841ac7
+
841ac7
+
841ac7
+errno_t sss_load_nss_symbols(struct sss_nss_ops *ops, const char *libname)
841ac7
+{
841ac7
+    char *libpath;
841ac7
+    size_t i;
841ac7
+    struct {
841ac7
+        void **dest;
841ac7
+        const char *name;
841ac7
+    } symbols[] = {
841ac7
+        {(void**)&ops->getpwnam_r,      "getpwnam_r"},
841ac7
+        {(void**)&ops->getpwuid_r,      "getpwuid_r"},
841ac7
+        {(void**)&ops->setpwent,        "setpwent"},
841ac7
+        {(void**)&ops->getpwent_r,      "getpwent_r"},
841ac7
+        {(void**)&ops->endpwent,        "endpwent"},
841ac7
+        {(void**)&ops->getgrnam_r,      "getgrnam_r"},
841ac7
+        {(void**)&ops->getgrgid_r,      "getgrgid_r"},
841ac7
+        {(void**)&ops->setgrent,        "setgrent"},
841ac7
+        {(void**)&ops->getgrent_r,      "getgrent_r"},
841ac7
+        {(void**)&ops->endgrent,        "endgrent"},
841ac7
+        {(void**)&ops->initgroups_dyn,  "initgroups_dyn"},
841ac7
+        {(void**)&ops->setnetgrent,     "setnetgrent"},
841ac7
+        {(void**)&ops->getnetgrent_r,   "getnetgrent_r"},
841ac7
+        {(void**)&ops->endnetgrent,     "endnetgrent"},
841ac7
+        {(void**)&ops->getservbyname_r, "getservbyname_r"},
841ac7
+        {(void**)&ops->getservbyport_r, "getservbyport_r"},
841ac7
+        {(void**)&ops->setservent,      "setservent"},
841ac7
+        {(void**)&ops->getservent_r,    "getservent_r"},
841ac7
+        {(void**)&ops->endservent,      "endservent"}
841ac7
+    };
841ac7
+
841ac7
+    libpath = talloc_asprintf(NULL, "libnss_%s.so.2", libname);
841ac7
+    if (libpath == NULL) {
841ac7
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
841ac7
+        return ENOMEM;
841ac7
+    }
841ac7
+
841ac7
+    ops->dl_handle = dlopen(libpath, RTLD_NOW);
841ac7
+    if (ops->dl_handle == NULL) {
841ac7
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module, "
841ac7
+              "error: %s\n", libpath, dlerror());
841ac7
+        talloc_free(libpath);
841ac7
+        return ELIBACC;
841ac7
+    }
841ac7
+    talloc_free(libpath);
841ac7
+
841ac7
+    for (i = 0; i < sizeof(symbols)/sizeof(symbols[0]); ++i) {
841ac7
+        *symbols[i].dest = proxy_dlsym(ops->dl_handle, symbols[i].name,
841ac7
+                                       libname);
841ac7
+        if (*symbols[i].dest == NULL) {
841ac7
+            DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load "NSS_FN_NAME", "
841ac7
+                  "error: %s.\n", libname, symbols[i].name, dlerror());
841ac7
+        }
841ac7
+    }
841ac7
+
841ac7
+    return EOK;
841ac7
+}
841ac7
diff --git a/src/util/nss_dl_load.h b/src/util/nss_dl_load.h
841ac7
new file mode 100644
841ac7
index 000000000..5097acacd
841ac7
--- /dev/null
841ac7
+++ b/src/util/nss_dl_load.h
841ac7
@@ -0,0 +1,81 @@
841ac7
+/*
841ac7
+    Copyright (C) 2019 Red Hat
841ac7
+
841ac7
+    This program is free software; you can redistribute it and/or modify
841ac7
+    it under the terms of the GNU General Public License as published by
841ac7
+    the Free Software Foundation; either version 3 of the License, or
841ac7
+    (at your option) any later version.
841ac7
+
841ac7
+    This program is distributed in the hope that it will be useful,
841ac7
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
841ac7
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
841ac7
+    GNU General Public License for more details.
841ac7
+
841ac7
+    You should have received a copy of the GNU General Public License
841ac7
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
841ac7
+*/
841ac7
+
841ac7
+#ifndef __SSSD_NSS_DL_LOAD_H__
841ac7
+#define __SSSD_NSS_DL_LOAD_H__
841ac7
+
841ac7
+
841ac7
+#include <nss.h>
841ac7
+#include <pwd.h>
841ac7
+#include <grp.h>
841ac7
+#include <netdb.h>
841ac7
+#include "util/util_errors.h"
841ac7
+#include "sss_client/nss_compat.h"
841ac7
+
841ac7
+
841ac7
+struct sss_nss_ops {
841ac7
+    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*setpwent)(void);
841ac7
+    enum nss_status (*getpwent_r)(struct passwd *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*endpwent)(void);
841ac7
+
841ac7
+    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*setgrent)(void);
841ac7
+    enum nss_status (*getgrent_r)(struct group *result,
841ac7
+                                  char *buffer, size_t buflen, int *errnop);
841ac7
+    enum nss_status (*endgrent)(void);
841ac7
+    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
841ac7
+                                      long int *start, long int *size,
841ac7
+                                      gid_t **groups, long int limit,
841ac7
+                                      int *errnop);
841ac7
+    enum nss_status (*setnetgrent)(const char *netgroup,
841ac7
+                                   struct __netgrent *result);
841ac7
+    enum nss_status (*getnetgrent_r)(struct __netgrent *result, char *buffer,
841ac7
+                                     size_t buflen, int *errnop);
841ac7
+    enum nss_status (*endnetgrent)(struct __netgrent *result);
841ac7
+
841ac7
+    /* Services */
841ac7
+    enum nss_status (*getservbyname_r)(const char *name,
841ac7
+                                        const char *protocol,
841ac7
+                                        struct servent *result,
841ac7
+                                        char *buffer, size_t buflen,
841ac7
+                                        int *errnop);
841ac7
+    enum nss_status (*getservbyport_r)(int port, const char *protocol,
841ac7
+                                        struct servent *result,
841ac7
+                                        char *buffer, size_t buflen,
841ac7
+                                        int *errnop);
841ac7
+    enum nss_status (*setservent)(void);
841ac7
+    enum nss_status (*getservent_r)(struct servent *result,
841ac7
+                                    char *buffer, size_t buflen,
841ac7
+                                    int *errnop);
841ac7
+    enum nss_status (*endservent)(void);
841ac7
+
841ac7
+    void *dl_handle;
841ac7
+};
841ac7
+
841ac7
+
841ac7
+errno_t sss_load_nss_symbols(struct sss_nss_ops *ops, const char *libname);
841ac7
+
841ac7
+
841ac7
+#endif /* __SSSD_NSS_DL_LOAD_H__ */
841ac7
-- 
841ac7
2.19.1
841ac7