|
|
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 |
|