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

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