Add plugin for cifs-utils

- Resolves: rhbz#998544
This commit is contained in:
Sumit Bose 2013-10-15 12:35:12 +02:00
parent f99cfe2513
commit df4dbc81ab
3 changed files with 570 additions and 2 deletions

View File

@ -0,0 +1,41 @@
From f244195582ec804f1022341e2e3394754e31b36a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 9 Oct 2013 18:19:08 +0200
Subject: [PATCH] LDAP: handle SID requests if noexist_delete is set
Fixes https://fedorahosted.org/sssd/ticket/2116
---
src/providers/ldap/ldap_id.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 162d987..59dfd0a 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -365,6 +365,11 @@ static void users_get_done(struct tevent_req *subreq)
}
break;
+ case BE_FILTER_SECID:
+ /* Since it is not clear if the SID belongs to a user or a group
+ * we have nothing to do here. */
+ break;
+
default:
tevent_req_error(req, EINVAL);
return;
@@ -694,6 +699,11 @@ static void groups_get_done(struct tevent_req *subreq)
}
break;
+ case BE_FILTER_SECID:
+ /* Since it is not clear if the SID belongs to a user or a group
+ * we have nothing to do here. */
+ break;
+
default:
tevent_req_error(req, EINVAL);
return;
--
1.8.3.1

View File

@ -0,0 +1,493 @@
From 15b3f9012309ca1c10528139946523bc295a4a9b Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <benjaminfranzke@googlemail.com>
Date: Thu, 26 Sep 2013 10:27:33 +0200
Subject: [PATCH] Add CIFS idmap plugin
https://fedorahosted.org/sssd/ticket/1534
---
Makefile.am | 21 ++
configure.ac | 2 +
src/conf_macros.m4 | 14 ++
src/external/cifsidmap.m4 | 16 ++
src/lib/cifs_idmap_sss/cifs_idmap_sss.c | 340 ++++++++++++++++++++++++++++++++
src/tests/dlopen-tests.c | 3 +
6 files changed, 396 insertions(+)
create mode 100644 src/external/cifsidmap.m4
create mode 100644 src/lib/cifs_idmap_sss/cifs_idmap_sss.c
diff --git a/Makefile.am b/Makefile.am
index 15c92d9..cb24df8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,6 +32,9 @@ endif
if BUILD_PAC_RESPONDER
krb5authdata_plugindir = @krb5authdatapluginpath@
endif
+if BUILD_CIFS_IDMAP_PLUGIN
+cifsplugindir = @cifspluginpath@
+endif
sssdconfdir = $(sysconfdir)/sssd
sssddatadir = $(datadir)/sssd
sssdapiplugindir = $(sssddatadir)/sssd.api.d
@@ -193,6 +196,11 @@ krb5authdata_plugin_LTLIBRARIES = \
sssd_pac_plugin.la
endif
+if BUILD_CIFS_IDMAP_PLUGIN
+cifsplugin_LTLIBRARIES = \
+ cifs_idmap_sss.la
+endif
+
noinst_LTLIBRARIES =
pkglib_LTLIBRARIES = \
@@ -1896,6 +1904,19 @@ pysss_nss_idmap_la_LDFLAGS = \
-module
endif
+if BUILD_CIFS_IDMAP_PLUGIN
+cifs_idmap_sss_la_SOURCES = \
+ src/lib/cifs_idmap_sss/cifs_idmap_sss.c
+cifs_idmap_sss_la_LIBADD = \
+ libsss_idmap.la \
+ libsss_nss_idmap.la
+cifs_idmap_sss_la_CFLAGS = \
+ $(AM_CFLAGS)
+cifs_idmap_sss_la_LDFLAGS = \
+ -avoid-version \
+ -module
+endif
+
################
# TRANSLATIONS #
################
diff --git a/configure.ac b/configure.ac
index d28d55f..9934b50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,7 @@ WITH_KRB5_RCACHE_DIR
WITH_KRB5AUTHDATA_PLUGIN_PATH
WITH_KRB5_CONF
WITH_PYTHON_BINDINGS
+WITH_CIFS_PLUGIN_PATH
WITH_SELINUX
WITH_NSCD
WITH_SEMANAGE
@@ -153,6 +154,7 @@ m4_include([src/external/libkeyutils.m4])
m4_include([src/external/libnl.m4])
m4_include([src/external/systemd.m4])
m4_include([src/external/pac_responder.m4])
+m4_include([src/external/cifsidmap.m4])
m4_include([src/external/signal.m4])
m4_include([src/external/inotify.m4])
m4_include([src/external/libndr_nbt.m4])
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 1aecaea..4be819d 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -265,6 +265,20 @@ AC_DEFUN([WITH_KRB5_PLUGIN_PATH],
AC_SUBST(krb5pluginpath)
])
+AC_DEFUN([WITH_CIFS_PLUGIN_PATH],
+ [ AC_ARG_WITH([cifs-plugin-path],
+ [AC_HELP_STRING([--with-cifs-plugin-path=PATH],
+ [Path to cifs-utils plugin store [/usr/lib/cifs-utils]]
+ )
+ ]
+ )
+ cifspluginpath="${libdir}/cifs-utils"
+ if test x"$with_cifs_plugin_path" != x; then
+ cifspluginpath=$with_cifs_plugin_path
+ fi
+ AC_SUBST(cifspluginpath)
+ ])
+
AC_DEFUN([WITH_KRB5_RCACHE_DIR],
[ AC_ARG_WITH([krb5-rcache-dir],
[AC_HELP_STRING([--with-krb5-rcache-dir=PATH],
diff --git a/src/external/cifsidmap.m4 b/src/external/cifsidmap.m4
new file mode 100644
index 0000000..53cb8b7
--- /dev/null
+++ b/src/external/cifsidmap.m4
@@ -0,0 +1,16 @@
+AC_ARG_ENABLE([cifs-idmap-plugin],
+ [AS_HELP_STRING([--disable-cifs-idmap-plugin],
+ [do not build CIFS idmap plugin])],
+ [build_cifs_idmap_plugin=$enableval],
+ [build_cifs_idmap_plugin=yes])
+
+AS_IF([test x$build_cifs_idmap_plugin = xyes],
+ [AC_CHECK_HEADER([cifsidmap.h], [],
+ [AC_MSG_ERROR([you must have the cifsidmap header installed to build the idmap plugin])])
+ ])
+
+AM_CONDITIONAL([BUILD_CIFS_IDMAP_PLUGIN],
+ [test x$build_cifs_idmap_plugin = xyes])
+
+AM_COND_IF([BUILD_CIFS_IDMAP_PLUGIN],
+ [AC_DEFINE_UNQUOTED(HAVE_CIFS_IDMAP_PLUGIN, 1, [Build with cifs idmap plugin])])
diff --git a/src/lib/cifs_idmap_sss/cifs_idmap_sss.c b/src/lib/cifs_idmap_sss/cifs_idmap_sss.c
new file mode 100644
index 0000000..f914917
--- /dev/null
+++ b/src/lib/cifs_idmap_sss/cifs_idmap_sss.c
@@ -0,0 +1,340 @@
+/*
+ Authors:
+ Benjamin Franzke <benjaminfranzke@googlemail.com>
+
+ Copyright (C) 2013 Benjamin Franzke
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+/* TODO: Support well known SIDs as in samba's
+ * - librpc/idl/security.idl or
+ * - source4/rpc_server/lsa/lsa_lookup.c?
+ */
+
+/* TODO: Support of [all] samba's Unix SIDs:
+ * Users: S-1-22-1-%UID
+ * Groups: S-1-22-2-%GID
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include <cifsidmap.h>
+
+#include "lib/idmap/sss_idmap.h"
+#include "sss_client/idmap/sss_nss_idmap.h"
+
+#define WORLD_SID "S-1-1-0"
+
+#ifdef DEBUG
+#include <syslog.h>
+#define debug(str, ...) \
+ syslog(0, "%s: " str "\n", \
+ __FUNCTION__, ##__VA_ARGS__)
+#else
+#define debug(...) do { } while(0)
+#endif
+
+struct sssd_ctx {
+ struct sss_idmap_ctx *idmap;
+ const char **errmsg;
+};
+
+#define ctx_set_error(ctx, error) \
+ do { \
+ *ctx->errmsg = error; \
+ debug("%s", error ? error : ""); \
+ } while (0);
+
+int cifs_idmap_init_plugin(void **handle, const char **errmsg)
+{
+ struct sssd_ctx *ctx;
+ enum idmap_error_code err;
+
+ if (handle == NULL || errmsg == NULL)
+ return EINVAL;
+
+ ctx = malloc(sizeof *ctx);
+ if (!ctx) {
+ *errmsg = "Failed to allocate context";
+ return -1;
+ }
+ ctx->errmsg = errmsg;
+ ctx_set_error(ctx, NULL);
+
+ err = sss_idmap_init(NULL, NULL, NULL, &ctx->idmap);
+ if (err != IDMAP_SUCCESS) {
+ ctx_set_error(ctx, idmap_error_string(err));
+ free(ctx);
+ return -1;
+ }
+
+ *handle = ctx;
+ return 0;
+}
+
+void cifs_idmap_exit_plugin(void *handle)
+{
+ struct sssd_ctx *ctx = handle;
+
+ debug("exit");
+
+ if (ctx == NULL)
+ return;
+
+ sss_idmap_free(ctx->idmap);
+
+ free(ctx);
+}
+
+
+/* Test with `getcifsacl file` on client. */
+int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *csid,
+ char **name)
+{
+ struct sssd_ctx *ctx = handle;
+ enum idmap_error_code iderr;
+ char *sid;
+ enum sss_id_type id_type;
+ int err;
+
+ iderr = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) csid,
+ sizeof(*csid), &sid);
+ if (iderr != IDMAP_SUCCESS) {
+ ctx_set_error(ctx, idmap_error_string(iderr));
+ *name = NULL;
+ return -1;
+ }
+
+ debug("sid: %s", sid);
+
+ if (strcmp(sid, WORLD_SID) == 0) {
+ *name = strdup("\\Everyone");
+ if (!*name) {
+ ctx_set_error(ctx, strerror(ENOMEM));
+ return ENOMEM;
+ }
+ return 0;
+ }
+
+ err = sss_nss_getnamebysid(sid, name, &id_type);
+ if (err != 0) {
+ ctx_set_error(ctx, strerror(err));
+ *name = NULL;
+ return -err;
+ }
+
+ /* FIXME: Map Samba Unix SIDs? (sid->id and use getpwuid)? */
+
+ debug("name: %s", *name);
+
+ return 0;
+}
+
+static int sid_to_cifs_sid(struct sssd_ctx *ctx, const char *sid,
+ struct cifs_sid *csid)
+{
+ uint8_t *bsid = NULL;
+ enum idmap_error_code err;
+ size_t length;
+
+ err = sss_idmap_sid_to_bin_sid(ctx->idmap,
+ sid, &bsid, &length);
+ if (err != IDMAP_SUCCESS) {
+ ctx_set_error(ctx, idmap_error_string(err));
+ return -1;
+ }
+ if (length > sizeof(struct cifs_sid)) {
+ ctx_set_error(ctx, "too large sid length");
+ free(bsid);
+ return -1;
+ }
+
+ memcpy(csid, bsid, length);
+ free(bsid);
+
+ return 0;
+}
+
+/* Test with setcifsacl -a */
+int cifs_idmap_str_to_sid(void *handle, const char *name,
+ struct cifs_sid *csid)
+{
+ struct sssd_ctx *ctx = handle;
+ int err;
+ enum sss_id_type id_type;
+ char *sid = NULL;
+ int success = 0;
+
+ debug("%s", name);
+
+ err = sss_nss_getsidbyname(name, &sid, &id_type);
+ if (err != 0) {
+ /* Might be a raw string representation of SID,
+ * try converting that before returning an error. */
+ if (sid_to_cifs_sid(ctx, name, csid) == 0)
+ return 0;
+
+ ctx_set_error(ctx, strerror(err));
+ return -err;
+ }
+
+ if (sid_to_cifs_sid(ctx, sid, csid) != 0)
+ success = -1;
+
+ free(sid);
+
+ return success;
+}
+
+static int samba_unix_sid_to_id(const char *sid, struct cifs_uxid *cuxid)
+{
+ id_t id;
+ uint8_t type;
+
+ if (sscanf(sid, "S-1-22-%hhu-%u", &type, &id) != 2)
+ return -1;
+
+ switch (type) {
+ case 1:
+ cuxid->type = CIFS_UXID_TYPE_UID;
+ cuxid->id.uid = id;
+ break;
+ case 2:
+ cuxid->type = CIFS_UXID_TYPE_GID;
+ cuxid->id.gid = id;
+ break;
+ default:
+ cuxid->type = CIFS_UXID_TYPE_UNKNOWN;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int sss_sid_to_id(struct sssd_ctx *ctx, const char *sid,
+ struct cifs_uxid *cuxid)
+{
+ int err;
+ enum sss_id_type id_type;
+
+ err = sss_nss_getidbysid(sid, (uint32_t *)&cuxid->id.uid, &id_type);
+ if (err != 0) {
+ ctx_set_error(ctx, strerror(err));
+ return -1;
+ }
+
+ switch (id_type) {
+ case SSS_ID_TYPE_UID:
+ cuxid->type = CIFS_UXID_TYPE_UID;
+ break;
+ case SSS_ID_TYPE_GID:
+ cuxid->type = CIFS_UXID_TYPE_GID;
+ break;
+ case SSS_ID_TYPE_BOTH:
+ cuxid->type = CIFS_UXID_TYPE_BOTH;
+ break;
+ case SSS_ID_TYPE_NOT_SPECIFIED:
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * cifs_idmap_sids_to_ids - convert struct cifs_sids to struct cifs_uxids
+ * usecase: mount.cifs -o sec=krb5,multiuser,cifsacl,nounix
+ * test: ls -n on mounted share
+ */
+int cifs_idmap_sids_to_ids(void *handle, const struct cifs_sid *csid,
+ const size_t num, struct cifs_uxid *cuxid)
+{
+ struct sssd_ctx *ctx = handle;
+ enum idmap_error_code err;
+ int success = -1;
+ size_t i;
+ char *sid;
+
+ debug("num: %zd", num);
+
+ if (num > UINT_MAX) {
+ ctx_set_error(ctx, "num is too large.");
+ return EINVAL;
+ }
+
+ for (i = 0; i < num; ++i) {
+ err = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) &csid[i],
+ sizeof(csid[i]), &sid);
+ if (err != IDMAP_SUCCESS) {
+ ctx_set_error(ctx, idmap_error_string(err));
+ continue;
+ }
+
+ cuxid[i].type = CIFS_UXID_TYPE_UNKNOWN;
+
+ if (sss_sid_to_id(ctx, sid, &cuxid[i]) == 0 ||
+ samba_unix_sid_to_id(sid, &cuxid[i]) == 0) {
+
+ debug("setting uid of %s to %d", sid, cuxid[i].id.uid);
+ success = 0;
+ }
+
+ free(sid);
+ }
+
+ return success;
+}
+
+
+int cifs_idmap_ids_to_sids(void *handle, const struct cifs_uxid *cuxid,
+ const size_t num, struct cifs_sid *csid)
+{
+ struct sssd_ctx *ctx = handle;
+ int err, success = -1;
+ char *sid;
+ enum sss_id_type id_type;
+ size_t i;
+
+ debug("num ids: %zd", num);
+
+ if (num > UINT_MAX) {
+ ctx_set_error(ctx, "num is too large.");
+ return EINVAL;
+ }
+
+ for (i = 0; i < num; ++i) {
+ err = sss_nss_getsidbyid((uint32_t)cuxid[i].id.uid, &sid, &id_type);
+ if (err != 0) {
+ ctx_set_error(ctx, strerror(err));
+ csid[i].revision = 0;
+ /* FIXME: would it be safe to map *any* uid/gids unknown by sssd to
+ * SAMBA's UNIX SIDs? */
+ continue;
+ }
+
+ if (sid_to_cifs_sid(ctx, sid, csid) == 0)
+ success = 0;
+ else
+ csid[i].revision = 0;
+ free(sid);
+ }
+
+ return success;
+}
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index 67fc41c..40e02da 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -56,6 +56,9 @@ struct so {
#ifdef HAVE_PAC_RESPONDER
{ "sssd_pac_plugin.so", { LIBPFX"sssd_pac_plugin.so", NULL } },
#endif
+#ifdef HAVE_CIFS_IDMAP_PLUGIN
+ { "cifs_idmap_sss.so", { LIBPFX"cifs_idmap_sss.so", NULL } },
+#endif
{ "memberof.so", { LIBPFX"memberof.so", NULL } },
{ "libsss_child.so", { "libtevent.so",
LIBPFX"libsss_debug.so",
--
1.8.3.1

View File

@ -2,13 +2,19 @@
%define __provides_exclude_from %{python_sitearch}/.*\.so$ %define __provides_exclude_from %{python_sitearch}/.*\.so$
%define _hardened_build 1 %define _hardened_build 1
%if (0%{?fedora} >= 17 || 0%{?rhel} >= 7)
%global with_cifs_utils_plugin 1
%else
%global with_cifs_utils_plugin_option --disable-cifs-idmap-plugin
%endif
# Determine the location of the LDB modules directory # Determine the location of the LDB modules directory
%global ldb_modulesdir %(pkg-config --variable=modulesdir ldb) %global ldb_modulesdir %(pkg-config --variable=modulesdir ldb)
%global ldb_version 1.1.16 %global ldb_version 1.1.16
Name: sssd Name: sssd
Version: 1.11.1 Version: 1.11.1
Release: 3%{?dist} Release: 4%{?dist}
Group: Applications/System Group: Applications/System
Summary: System Security Services Daemon Summary: System Security Services Daemon
License: GPLv3+ License: GPLv3+
@ -21,6 +27,9 @@ Patch0001: 0001-krb5-Remove-ability-to-create-public-directories.patch
Patch0002: 0002-krb5-Fix-unit-tests.patch Patch0002: 0002-krb5-Fix-unit-tests.patch
Patch0003: 0003-AD-properly-intitialize-GC-from-ad_server-option.patch Patch0003: 0003-AD-properly-intitialize-GC-from-ad_server-option.patch
Patch0601: 0601-FEDORA-LDAP-handle-SID-requests-if-noexist_delete-is-set.patch
Patch0602: 0602-FEDORA-Add-CIFS-idmap-plugin.patch
### Dependencies ### ### Dependencies ###
Requires: sssd-common = %{version}-%{release} Requires: sssd-common = %{version}-%{release}
Requires: sssd-ldap = %{version}-%{release} Requires: sssd-ldap = %{version}-%{release}
@ -82,6 +91,9 @@ BuildRequires: selinux-policy-targeted
%ifarch %{ix86} x86_64 %{arm} %ifarch %{ix86} x86_64 %{arm}
BuildRequires: libcmocka-devel BuildRequires: libcmocka-devel
%endif %endif
%if (0%{?with_cifs_utils_plugin} == 1)
BuildRequires: cifs-utils-devel
%endif
%description %description
Provides a set of daemons to manage access to remote directories and Provides a set of daemons to manage access to remote directories and
@ -130,6 +142,8 @@ Group: Applications/System
License: LGPLv3+ License: LGPLv3+
Requires(post): /sbin/ldconfig Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig Requires(postun): /sbin/ldconfig
Requires(post): /usr/sbin/alternatives
Requires(preun): /usr/sbin/alternatives
%description client %description client
Provides the libraries needed by the PAM and NSS stacks to connect to the SSSD Provides the libraries needed by the PAM and NSS stacks to connect to the SSSD
@ -370,7 +384,8 @@ autoreconf -ivf
--enable-ldb-version-check \ --enable-ldb-version-check \
--disable-static \ --disable-static \
--disable-rpath \ --disable-rpath \
--with-test-dir=/dev/shm --with-test-dir=/dev/shm \
%{?with_cifs_utils_plugin_option}
make %{?_smp_mflags} all docs make %{?_smp_mflags} all docs
@ -599,6 +614,10 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/security/pam_sss.so %{_libdir}/security/pam_sss.so
%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so %{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so
%{_libdir}/krb5/plugins/authdata/sssd_pac_plugin.so %{_libdir}/krb5/plugins/authdata/sssd_pac_plugin.so
%if (0%{?with_cifs_utils_plugin} == 1)
%{_libdir}/cifs-utils/cifs_idmap_sss.so
%ghost %{_sysconfdir}/cifs-utils/idmap-plugin
%endif
%{_mandir}/man8/pam_sss.8* %{_mandir}/man8/pam_sss.8*
%{_mandir}/man8/sssd_krb5_locator_plugin.8* %{_mandir}/man8/sssd_krb5_locator_plugin.8*
@ -694,7 +713,18 @@ if [ $1 -ge 1 ] ; then
/bin/systemctl try-restart sssd.service >/dev/null 2>&1 || : /bin/systemctl try-restart sssd.service >/dev/null 2>&1 || :
fi fi
%if (0%{?with_cifs_utils_plugin} == 1)
%post client
/sbin/ldconfig
/usr/sbin/alternatives --install /etc/cifs-utils/idmap-plugin cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so 20
%preun client
if [ $1 -eq 0 ]; then
/usr/sbin/alternatives --remove cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so
fi
%else
%post client -p /sbin/ldconfig %post client -p /sbin/ldconfig
%endif
%postun client -p /sbin/ldconfig %postun client -p /sbin/ldconfig
@ -707,6 +737,10 @@ fi
%postun -n libsss_idmap -p /sbin/ldconfig %postun -n libsss_idmap -p /sbin/ldconfig
%changelog %changelog
* Mon Oct 14 2013 Sumit Bose <sbose@redhat.com> - 1.11.1-4
- Add plugin for cifs-utils
- Resolves: rhbz#998544
* Tue Oct 08 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.11.1-3 * Tue Oct 08 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.11.1-3
- Fix failover from Global Catalog to LDAP in case GC is not available - Fix failover from Global Catalog to LDAP in case GC is not available