From 6c8631b81dcec9c5ef8b1c1b9c3e9f989017ce49 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 19 Apr 2016 13:52:59 +0200 Subject: [PATCH] Add winbind idmap plugin With this plugin winbind can use the same id-mapping as SSSD which makes it possible to run both together in a consistent way. --- Makefile.am | 51 +++++- configure.ac | 1 + contrib/sssd.spec.in | 2 + src/conf_macros.m4 | 14 ++ .../libdlopen-test-winbind-idmap.c | 31 ++++ src/lib/winbind_idmap_sss/winbind_idmap_sss.c | 201 +++++++++++++++++++++ src/lib/winbind_idmap_sss/winbind_idmap_sss.h | 100 ++++++++++ src/tests/dlopen-tests.c | 3 + 8 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 src/lib/winbind_idmap_sss/libdlopen-test-winbind-idmap.c create mode 100644 src/lib/winbind_idmap_sss/winbind_idmap_sss.c create mode 100644 src/lib/winbind_idmap_sss/winbind_idmap_sss.h diff --git a/Makefile.am b/Makefile.am index 390e58938b123a4043edec3bc4dea0230c0fd298..3041d8c844d6a6d2d8af67a2022226291a8498b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,9 @@ endif if BUILD_CIFS_IDMAP_PLUGIN cifsplugindir = @cifspluginpath@ endif +if BUILD_SAMBA +winbindplugindir = @winbindpluginpath@ +endif if BUILD_LIBWBCLIENT libwbclientdir = @appmodpath@ endif @@ -338,6 +341,12 @@ cifsplugin_LTLIBRARIES = \ cifs_idmap_sss.la endif +if BUILD_SAMBA +winbindplugin_LTLIBRARIES = \ + winbind_idmap_sss.la \ + $(NULL) +endif + noinst_LTLIBRARIES = pkglib_LTLIBRARIES = @@ -679,6 +688,7 @@ dist_noinst_HEADERS = \ src/sss_client/nfs/nfsidmap_internal.h \ src/lib/idmap/sss_idmap_private.h \ src/lib/sifp/sss_sifp_private.h \ + src/lib/winbind_idmap_sss/winbind_idmap_sss.h \ src/tests/cmocka/test_utils.h \ src/tools/common/sss_tools.h \ src/tools/common/sss_colondb.h \ @@ -1455,7 +1465,10 @@ check_LTLIBRARIES += \ $(NULL) if BUILD_SAMBA -check_LTLIBRARIES += libsss_ad_tests.la +check_LTLIBRARIES += \ + libsss_ad_tests.la \ + libdlopen_test_winbind_idmap.la \ + $(NULL) endif libdlopen_test_providers_la_SOURCES = \ @@ -3493,6 +3506,40 @@ cifs_idmap_sss_la_LDFLAGS = \ -module endif +if BUILD_SAMBA +winbind_idmap_sss_la_SOURCES = \ + src/lib/winbind_idmap_sss/winbind_idmap_sss.c \ + src/util/util_sss_idmap.c \ + $(NULL) +winbind_idmap_sss_la_LIBADD = \ + libsss_idmap.la \ + libsss_nss_idmap.la \ + $(TALLOC_LIBS) \ + $(NULL) +winbind_idmap_sss_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(NDR_KRB5PAC_CFLAGS) \ + $(NULL) +winbind_idmap_sss_la_LDFLAGS = \ + -avoid-version \ + -module \ + $(NULL) + +libdlopen_test_winbind_idmap_la_SOURCES = \ + src/lib/winbind_idmap_sss/libdlopen-test-winbind-idmap.c \ + $(NULL) +libdlopen_test_winbind_idmap_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(NDR_KRB5PAC_CFLAGS) \ + $(NULL) +libdlopen_test_winbind_idmap_la_LDFLAGS = \ + -shared \ + -avoid-version \ + -rpath $(abs_top_builddir) \ + -export-dynamic + $(NULL) +endif + ################ # TRANSLATIONS # ################ @@ -3722,6 +3769,7 @@ install-data-hook: if [ ! $(krb5rcachedir) = "__LIBKRB5_DEFAULTS__" ]; then \ $(MKDIR_P) $(DESTDIR)/$(krb5rcachedir) ; \ fi + mv $(DESTDIR)/$(winbindplugindir)/winbind_idmap_sss.so $(DESTDIR)/$(winbindplugindir)/sss.so uninstall-hook: if [ -f $(abs_builddir)/src/config/.files2 ]; then \ @@ -3743,6 +3791,7 @@ if BUILD_PYTHON3_BINDINGS cd $(DESTDIR)$(py3execdir) && \ rm -f pysss.so pyhbac.so pysss_murmur.so pysss_nss_idmap.so endif + rm $(DESTDIR)/$(winbindplugindir)/sss.so clean-local: if BUILD_PYTHON2_BINDINGS diff --git a/configure.ac b/configure.ac index b4ba366d7a32a45879e9f2e9b6e84256a3ac7235..11d3f9c7333ba814cef54651cbc8e78c610b64e9 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,7 @@ WITH_KRB5_CONF WITH_PYTHON2_BINDINGS WITH_PYTHON3_BINDINGS WITH_CIFS_PLUGIN_PATH +WITH_WINBIND_PLUGIN_PATH WITH_SELINUX WITH_NSCD WITH_IPA_GETKEYTAB diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 355b9510994b2f5ea470febca670d8982ad4bfce..1f1b73d25ab83b19437e26d4c57f4556137b8a64 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -823,6 +823,8 @@ done %{_libdir}/%{name}/libsss_ad.so %{_libexecdir}/%{servicename}/gpo_child %{_mandir}/man5/sssd-ad.5* +%dir %{_libdir}/samba/idmap +%{_libdir}/samba/idmap/sss.so %files proxy %defattr(-,root,root,-) diff --git a/src/conf_macros.m4 b/src/conf_macros.m4 index c8774b5f5b7d1be09ee74195bc0732984dd551d7..eed6508b1335e761aebae00d4ced373b00029f4c 100644 --- a/src/conf_macros.m4 +++ b/src/conf_macros.m4 @@ -288,6 +288,20 @@ AC_DEFUN([WITH_CIFS_PLUGIN_PATH], AC_SUBST(cifspluginpath) ]) +AC_DEFUN([WITH_WINBIND_PLUGIN_PATH], + [ AC_ARG_WITH([winbind-plugin-path], + [AC_HELP_STRING([--with-winbind-plugin-path=PATH], + [Path to winbind idmap plugin store [/usr/lib/samba/idmap]] + ) + ] + ) + winbindpluginpath="${libdir}/samba/idmap" + if test x"$with_winbind_plugin_path" != x; then + winbindpluginpath=$with_winbind_plugin_path + fi + AC_SUBST(winbindpluginpath) + ]) + AC_DEFUN([WITH_KRB5_RCACHE_DIR], [ AC_ARG_WITH([krb5-rcache-dir], [AC_HELP_STRING([--with-krb5-rcache-dir=PATH], diff --git a/src/lib/winbind_idmap_sss/libdlopen-test-winbind-idmap.c b/src/lib/winbind_idmap_sss/libdlopen-test-winbind-idmap.c new file mode 100644 index 0000000000000000000000000000000000000000..94e8719f81882e94f017cf729bf215e098c9579a --- /dev/null +++ b/src/lib/winbind_idmap_sss/libdlopen-test-winbind-idmap.c @@ -0,0 +1,31 @@ +/* + SSSD + + ID-mapping plugin for winbind - helper library for dlopen test + + Authors: + Sumit Bose + + Copyright (C) 2016 Red Hat + + 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 "lib/winbind_idmap_sss/winbind_idmap_sss.h" + +NTSTATUS smb_register_idmap(int version, const char *name, + struct idmap_methods *methods) +{ + return NT_STATUS_OK; +} diff --git a/src/lib/winbind_idmap_sss/winbind_idmap_sss.c b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c new file mode 100644 index 0000000000000000000000000000000000000000..f7279848cecdb2d7fe7f571813446dcc6f97211a --- /dev/null +++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c @@ -0,0 +1,201 @@ +/* + SSSD + + ID-mapping plugin for winbind + + Authors: + Sumit Bose + + Copyright (C) 2016 Red Hat + + 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 "lib/winbind_idmap_sss/winbind_idmap_sss.h" +#include "sss_client/idmap/sss_nss_idmap.h" +#include "lib/idmap/sss_idmap.h" +#include "util/util_sss_idmap.h" + +struct idmap_sss_ctx { + struct sss_idmap_ctx *idmap_ctx; +}; + +static NTSTATUS idmap_sss_initialize(struct idmap_domain *dom) +{ + struct idmap_sss_ctx *ctx; + enum idmap_error_code err; + + if (dom == NULL) { + return ERROR_INVALID_PARAMETER; + } + + ctx = talloc_zero(dom, struct idmap_sss_ctx); + if (ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + + err = sss_idmap_init(sss_idmap_talloc, ctx, sss_idmap_talloc_free, + &ctx->idmap_ctx); + if (err != IDMAP_SUCCESS) { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + + dom->private_data = ctx; + + return NT_STATUS_OK; +} + +static NTSTATUS idmap_sss_unixids_to_sids(struct idmap_domain *dom, + struct id_map **map) +{ + size_t c; + int ret; + char *sid_str; + enum sss_id_type id_type; + struct dom_sid *sid; + enum idmap_error_code err; + struct idmap_sss_ctx *ctx; + + if (dom == NULL) { + return ERROR_INVALID_PARAMETER; + } + + ctx = talloc_get_type(dom->private_data, struct idmap_sss_ctx); + if (ctx == NULL) { + return ERROR_INVALID_PARAMETER; + } + + for (c = 0; map[c]; c++) { + map[c]->status = ID_UNKNOWN; + } + + for (c = 0; map[c]; c++) { + ret = sss_nss_getsidbyid(map[c]->xid.id, &sid_str, &id_type); + if (ret != 0) { + if (ret == ENOENT) { + map[c]->status = ID_UNMAPPED; + } + continue; + } + + switch(id_type) { + case SSS_ID_TYPE_UID: + map[c]->xid.type = ID_TYPE_UID; + break; + case SSS_ID_TYPE_GID: + map[c]->xid.type = ID_TYPE_GID; + break; + case SSS_ID_TYPE_BOTH: + map[c]->xid.type = ID_TYPE_BOTH; + break; + default: + free(sid_str); + continue; + } + + err = sss_idmap_sid_to_smb_sid(ctx->idmap_ctx, sid_str, &sid); + free(sid_str); + if (err != IDMAP_SUCCESS) { + continue; + } + + memcpy(map[c]->sid, sid, sizeof(struct dom_sid)); + err = sss_idmap_free_smb_sid(ctx->idmap_ctx, sid); + + map[c]->status = ID_MAPPED; + } + + return NT_STATUS_OK; +} + +static NTSTATUS idmap_sss_sids_to_unixids(struct idmap_domain *dom, + struct id_map **map) +{ + size_t c; + int ret; + char *sid_str; + enum sss_id_type id_type; + enum idmap_error_code err; + struct idmap_sss_ctx *ctx; + uint32_t id; + + if (dom == NULL) { + return ERROR_INVALID_PARAMETER; + } + + ctx = talloc_get_type(dom->private_data, struct idmap_sss_ctx); + if (ctx == NULL) { + return ERROR_INVALID_PARAMETER; + } + + for (c = 0; map[c]; c++) { + map[c]->status = ID_UNKNOWN; + } + + for (c = 0; map[c]; c++) { + err = sss_idmap_smb_sid_to_sid(ctx->idmap_ctx, map[c]->sid, &sid_str); + if (err != IDMAP_SUCCESS) { + continue; + } + + ret = sss_nss_getidbysid(sid_str, &id, &id_type); + err = sss_idmap_free_sid(ctx->idmap_ctx, sid_str); + if (ret != 0) { + if (ret == ENOENT) { + map[c]->status = ID_UNMAPPED; + } + continue; + } + + switch(id_type) { + case SSS_ID_TYPE_UID: + map[c]->xid.type = ID_TYPE_UID; + break; + case SSS_ID_TYPE_GID: + map[c]->xid.type = ID_TYPE_GID; + break; + case SSS_ID_TYPE_BOTH: + map[c]->xid.type = ID_TYPE_BOTH; + break; + default: + continue; + } + + map[c]->xid.id = id; + + map[c]->status = ID_MAPPED; + } + + return NT_STATUS_OK; +} + +static struct idmap_methods sss_methods = { + .init = idmap_sss_initialize, + .unixids_to_sids = idmap_sss_unixids_to_sids, + .sids_to_unixids = idmap_sss_sids_to_unixids, +}; + +NTSTATUS idmap_sss_init(void) +{ + return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "sss", &sss_methods); +} + +NTSTATUS samba_init_module(void) +{ + return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "sss", &sss_methods); +} diff --git a/src/lib/winbind_idmap_sss/winbind_idmap_sss.h b/src/lib/winbind_idmap_sss/winbind_idmap_sss.h new file mode 100644 index 0000000000000000000000000000000000000000..92848c5dc3a3476434e7a6fec0dd9493b1b183c1 --- /dev/null +++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.h @@ -0,0 +1,100 @@ +/* + SSSD + + ID-mapping plugin for winbind + + Authors: + Sumit Bose + + Copyright (C) 2016 Red Hat + + 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 . +*/ + +#ifndef _WINBIND_SSS_IDMAP_H_ +#define _WINBIND_SSS_IDMAP_H_ + +#include +#include + +#include +#include +#include + +/* The following definitions are taken from the Samba header files + * - winbindd/idmap_proto.h + * - idmap.d + * - gen_ndr/idmap.h + * and can be removed if the related Samba header files become public headers + * or if this plugin is build inside the Samba source tree. */ + +enum id_type { + ID_TYPE_NOT_SPECIFIED, + ID_TYPE_UID, + ID_TYPE_GID, + ID_TYPE_BOTH +}; + +struct unixid { + uint32_t id; + enum id_type type; +}; + +enum id_mapping { + ID_UNKNOWN, + ID_MAPPED, + ID_UNMAPPED, + ID_EXPIRED +}; + +struct id_map { + struct dom_sid *sid; + struct unixid xid; + enum id_mapping status; +}; + + +#define SMB_IDMAP_INTERFACE_VERSION 5 + +struct idmap_domain { + const char *name; + struct idmap_methods *methods; + uint32_t low_id; + uint32_t high_id; + bool read_only; + void *private_data; +}; + +/* Filled out by IDMAP backends */ +struct idmap_methods { + + /* Called when backend is first loaded */ + NTSTATUS (*init)(struct idmap_domain *dom); + + /* Map an array of uids/gids to SIDs. The caller specifies + the uid/gid and type. Gets back the SID. */ + NTSTATUS (*unixids_to_sids)(struct idmap_domain *dom, struct id_map **ids); + + /* Map an arry of SIDs to uids/gids. The caller sets the SID + and type and gets back a uid or gid. */ + NTSTATUS (*sids_to_unixids)(struct idmap_domain *dom, struct id_map **ids); + + /* Allocate a Unix-ID. */ + NTSTATUS (*allocate_id)(struct idmap_domain *dom, struct unixid *id); +}; + +NTSTATUS smb_register_idmap(int version, const char *name, + struct idmap_methods *methods); +#endif /* _WINBIND_SSS_IDMAP_H_ */ + diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c index e808f23e7560241e3fc158d71da2dbdbe1543dfc..332b268e20d73393293d9c31357406b3756df2fe 100644 --- a/src/tests/dlopen-tests.c +++ b/src/tests/dlopen-tests.c @@ -70,6 +70,9 @@ struct so { #ifdef HAVE_CIFS_IDMAP_PLUGIN { "cifs_idmap_sss.so", { LIBPFX"cifs_idmap_sss.so", NULL } }, #endif + { "winbind_idmap_sss.so", { LIBPFX"libdlopen_test_winbind_idmap.so", + LIBPFX"winbind_idmap_sss.so", + NULL } }, { "memberof.so", { LIBPFX"memberof.so", NULL } }, { "libsss_child.so", { LIBPFX"libsss_util.so", LIBPFX"libsss_child.so", NULL } }, -- 2.1.0