From a5442a122917088afff240846700e858f45fe1de Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 10 Dec 2008 17:21:03 -0500 Subject: Initial work on a test provider using the gross hack of dlopen()ing nss_ldap :-) --- server/Makefile.in | 5 +- server/providers/data_provider.h | 4 + server/providers/data_provider_be.c | 17 ++-- server/providers/ldap_provider.c | 173 ++++++++++++++++++++++++++++++++++++ server/server.mk | 8 +- 5 files changed, 196 insertions(+), 11 deletions(-) create mode 100644 server/providers/ldap_provider.c diff --git a/server/Makefile.in b/server/Makefile.in index fa57d8030..a1f87eb54 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -60,6 +60,7 @@ OBJS = $(SERVER_OBJ) @LIBREPLACEOBJ@ $(EXTRA_OBJ) headers = .h BINS = sbin/sssd sbin/sssd_nss sbin/sssd_dp sbin/sssd_be +SOLIBS = lib/libsss_ldap.$(SHLIBEXT) DIRS = sbin @@ -67,7 +68,7 @@ default: all include $(srvdir)/rules.mk -all: showflags dirs $(OBJS) $(BINS) +all: showflags dirs $(OBJS) $(BINS) $(SOLIBS) shared-build: all @@ -76,7 +77,7 @@ dirs: clean:: rm -f *.o */*.o */*/*.o - rm -f $(BINS) + rm -f $(BINS) $(SOLIBS) distclean:: clean rm -rf $(DIRS) diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h index cd8098ba0..b04c57d0b 100644 --- a/server/providers/data_provider.h +++ b/server/providers/data_provider.h @@ -49,4 +49,8 @@ #define DP_CLI_METHOD_IDENTITY "getIdentity" #define DP_CLI_METHOD_ONLINE "getOnline" +struct dp_be_mod_ops { + int (*check_online)(void *pvt_data, int *reply); +}; + #endif /* __DATA_PROVIDER_ */ diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c index 83659bee9..cce4446f2 100644 --- a/server/providers/data_provider_be.c +++ b/server/providers/data_provider_be.c @@ -38,13 +38,9 @@ #include "sbus/sssd_dbus.h" #include "sbus_interfaces.h" #include "util/btreemap.h" -#include "data_provider.h" +#include "providers/data_provider.h" #include "util/service_helpers.h" -struct dp_mod_ops { - int (*check_online)(void *pvt_data, int *reply); -}; - struct be_ctx { struct event_context *ev; struct confdb_ctx *cdb; @@ -54,11 +50,11 @@ struct be_ctx { const char *name; const char *domain; const char *identity; - struct dp_mod_ops *ops; + struct dp_be_mod_ops *ops; void *pvt_data; }; -typedef int (*be_init_fn_t)(struct be_ctx *, struct dp_mod_ops **, void **); +typedef int (*be_init_fn_t)(TALLOC_CTX *, struct dp_be_mod_ops **, void **); static int service_identity(DBusMessage *message, void *data, DBusMessage **r); static int service_pong(DBusMessage *message, void *data, DBusMessage **r); @@ -374,6 +370,10 @@ static int load_backend(struct be_ctx *ctx) path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so", DATA_PROVIDER_PLUGINS_PATH, ctx->name); + if (!path) { + ret = ENOMEM; + goto done; + } handle = dlopen(path, RTLD_NOW); if (!handle) { @@ -427,9 +427,10 @@ int be_process_init(TALLOC_CTX *mem_ctx, } ctx->ev = ev; ctx->cdb = cdb; + ctx->name = talloc_strdup(ctx, be_name); ctx->domain = talloc_strdup(ctx, be_domain); ctx->identity = talloc_asprintf(ctx, "%%BE_%s", be_domain); - if (!ctx->domain || !ctx->identity) { + if (!ctx->name || !ctx->domain || !ctx->identity) { DEBUG(0, ("Out of memory!?\n")); return ENOMEM; } diff --git a/server/providers/ldap_provider.c b/server/providers/ldap_provider.c new file mode 100644 index 000000000..a6628f40a --- /dev/null +++ b/server/providers/ldap_provider.c @@ -0,0 +1,173 @@ +/* + SSSD + + Test LDAP Module + + Copyright (C) Simo Sorce 2008 + + 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 . +*/ + +#include +#include +#include +#include +#include "util/util.h" +#include "providers/data_provider.h" + +struct ldap_nss_ops { + enum nss_status (*getpwnam_r)(const char *name, struct passwd *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*setpwent)(void); + enum nss_status (*getpwent_r)(struct passwd *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*endpwent)(void); + + enum nss_status (*getgrnam_r)(const char *name, struct group *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*getgrgid_r)(gid_t gid, struct group *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*setgrent)(void); + enum nss_status (*getgrent_r)(struct group *result, + char *buffer, size_t buflen, int *errnop); + enum nss_status (*endgrent)(void); + enum nss_status (*initgroups_dyn)(const char *user, gid_t group, + long int *start, long int *size, + gid_t **groups, long int limit, + int *errnop); +}; + +struct ldap_ctx { + struct ldap_nss_ops ops; +}; + +static int ldap_check_online(void *pvt_data, int *reply); + +struct dp_be_mod_ops ldap_mod_ops = { + .check_online = ldap_check_online +}; + +static int ldap_check_online(void *pvt_data, int *reply) +{ + *reply = MOD_ONLINE; + return EOK; +} + +int sssm_ldap_init(TALLOC_CTX *bectx, struct dp_be_mod_ops **ops, void **pvt_data) +{ + struct ldap_ctx *ctx; + void *handle; + int ret; + + ctx = talloc(bectx, struct ldap_ctx); + if (!ctx) { + return ENOMEM; + } + + handle = dlopen("/usr/lib64/libnss_ldap.so.2", RTLD_NOW); + if (!handle) { + DEBUG(0, ("Unable to load libnss_ldap module with path, error: %s\n", dlerror())); + ret = ELIBACC; + goto done; + } + + ctx->ops.getpwnam_r = dlsym(handle, "_nss_ldap_getpwnam_r"); + if (!ctx->ops.getpwnam_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.getpwuid_r = dlsym(handle, "_nss_ldap_getpwuid_r"); + if (!ctx->ops.getpwuid_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.setpwent = dlsym(handle, "_nss_ldap_setpwent"); + if (!ctx->ops.setpwent) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.getpwent_r = dlsym(handle, "_nss_ldap_getpwent_r"); + if (!ctx->ops.getpwent_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.endpwent = dlsym(handle, "_nss_ldap_endpwent"); + if (!ctx->ops.endpwent) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.getgrnam_r = dlsym(handle, "_nss_ldap_getgrnam_r"); + if (!ctx->ops.getgrnam_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.getgrgid_r = dlsym(handle, "_nss_ldap_getgrgid_r"); + if (!ctx->ops.getgrgid_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.setgrent = dlsym(handle, "_nss_ldap_setgrent"); + if (!ctx->ops.setgrent) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.getgrent_r = dlsym(handle, "_nss_ldap_getgrent_r"); + if (!ctx->ops.getgrent_r) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.endgrent = dlsym(handle, "_nss_ldap_endgrent"); + if (!ctx->ops.endgrent) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + ctx->ops.initgroups_dyn = dlsym(handle, "_nss_ldap_initgroups_dyn"); + if (!ctx->ops.initgroups_dyn) { + DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror())); + ret = ELIBBAD; + goto done; + } + + *ops = &ldap_mod_ops; + *pvt_data = ctx; + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(ctx); + } + return ret; +} diff --git a/server/server.mk b/server/server.mk index 7f9274d92..f41c247ac 100644 --- a/server/server.mk +++ b/server/server.mk @@ -19,6 +19,9 @@ DP_OBJ = \ DP_BE_OBJ = \ providers/data_provider_be.o +LDAP_BE_OBJ = \ + providers/ldap_provider.o + NSSSRV_OBJ = \ nss/nsssrv.o \ nss/nsssrv_packet.o \ @@ -39,4 +42,7 @@ sbin/sssd_dp: $(DP_OBJ) $(UTIL_OBJ) $(CC) -o sbin/sssd_dp $(DP_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) sbin/sssd_be: $(DP_BE_OBJ) $(UTIL_OBJ) - $(CC) -o sbin/sssd_be $(DP_BE_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) + $(CC) -Wl,-E -o sbin/sssd_be $(DP_BE_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) + +lib/libsss_ldap.$(SHLIBEXT): $(LDAP_BE_OBJ) + $(SHLD) $(SHLD_FLAGS) -o $@ $(LDAP_BE_OBJ) $(LDFLAGS) $(LIBS) -- cgit