Blob Blame History Raw
From 9ae62c07c579fa9b3f0804c12cc0715f5f2524d4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 15 May 2018 11:55:35 +0200
Subject: [PATCH] winbind idmap plugin: support inferface version 6
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With Samba 4.7 the interface version of the idmap plugin was updated to
6. The patch adds support for this new version but can be complied with
the older version as well.

A configure option is added to select the version, if no version is
given configure tries to detect the version with the help of an internal
Samba library libidmap-samba4.so.

To make sure that always the right version is used configure will fail
if Samba is used (--with-samba, default) and no version can be
determined.

Resolves https://pagure.io/SSSD/sssd/issue/3741

Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
(cherry picked from commit c6b99b070268c3807833e9f894d9a36304014417)

DOWNSTREAM:
Resolves: rhbz#1580281 - Samba can not register sss idmap module because it's using an outdated SMB_IDMAP_INTERFACE_VERSION [rhel-7.5.z]
---
 contrib/ci/configure.sh                       |  9 ++
 contrib/sssd.spec.in                          | 12 +++
 src/external/samba.m4                         | 82 +++++++++++++++++++
 src/lib/winbind_idmap_sss/winbind_idmap_sss.c |  6 ++
 src/lib/winbind_idmap_sss/winbind_idmap_sss.h |  6 +-
 5 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/contrib/ci/configure.sh b/contrib/ci/configure.sh
index 9d18d0c187561a2dc3bc47d3e8913626e7ff3046..09da5b4e7b0b4a7859bcf81db987394ac91f4fa2 100644
--- a/contrib/ci/configure.sh
+++ b/contrib/ci/configure.sh
@@ -35,6 +35,7 @@ declare -a CONFIGURE_ARG_LIST=(
 if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-6.*- ||
       "$DISTRO_BRANCH" == -redhat-centos-6.*- ]]; then
     CONFIGURE_ARG_LIST+=(
+        "--with-smb-idmap-interface-version=5"
         "--disable-cifs-idmap-plugin"
         "--with-syslog=syslog"
         "--without-python3-bindings"
@@ -56,6 +57,14 @@ if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-7.*- ||
     )
 fi
 
+# Different versions of Debian might need different versions here but this is
+# sufficient to make the CI work
+if [[ "$DISTRO_BRANCH" == -debian-* ]]; then
+    CONFIGURE_ARG_LIST+=(
+        "--with-smb-idmap-interface-version=5"
+    )
+fi
+
 declare -r -a CONFIGURE_ARG_LIST
 
 fi # _CONFIGURE_SH
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index d9323bf1a2d84f4219f8ab11886e5ce87b401c15..3ddd054dea8a4b5dd46457acf9aaabed29ab754e 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -127,6 +127,14 @@
     %global with_gdm_pam_extensions 0
 %endif
 
+# Do not try to detect the idmap version on RHEL6 to avoid conflicts between
+# samba and samba4 package
+%if (0%{?fedora} || 0%{?rhel} >= 7)
+    %global detect_idmap_version 1
+%else
+    %global with_idmap_version --with-smb-idmap-interface-version=5
+%endif
+
 Name: @PACKAGE_NAME@
 Version: @PACKAGE_VERSION@
 Release: 0@PRERELEASE_VERSION@%{?dist}
@@ -225,6 +233,9 @@ BuildRequires: nfs-utils-lib-devel
 
 BuildRequires: samba4-devel
 BuildRequires: libsmbclient-devel
+%if (0%{?detect_idmap_version} == 1)
+BuildRequires: samba-winbind
+%endif
 
 %if (0%{?enable_systemtap} == 1)
 BuildRequires: systemtap-sdt-devel
@@ -747,6 +758,7 @@ autoreconf -ivf
     %{?enable_systemtap_opt} \
     %{?with_secret_responder} \
     %{?with_kcm_option} \
+    %{?with_idmap_version} \
     %{?experimental}
 
 make %{?_smp_mflags} all
diff --git a/src/external/samba.m4 b/src/external/samba.m4
index 91a583a0d0f514dab40d4f65cc32b17d0368f540..610831bf054e3687eb13025e954acf345fca1a00 100644
--- a/src/external/samba.m4
+++ b/src/external/samba.m4
@@ -39,4 +39,86 @@ them. In this case, you will need to execute configure script with argument
 --without-samba
         ]])
     fi
+
+    AC_ARG_WITH([smb-idmap-interface-version],
+                [AC_HELP_STRING([--with-smb-idmap-interface-version=[5|6]],
+                                [Idmap interface version of installed Samba]
+                               )
+                ]
+               )
+
+    if test x"$with_smb_idmap_interface_version" != x; then
+        if test x"$with_smb_idmap_interface_version" = x5 -o x"$with_smb_idmap_interface_version" = x6; then
+            idmap_test_result=$with_smb_idmap_interface_version
+        else
+            AC_MSG_ERROR([Illegal value -$with_smb_idmap_interface_version- for option --with-smb-idmap-interface-version])
+        fi
+    else
+
+        AC_MSG_CHECKING([Samba's idmap plugin interface version])
+        sambalibdir="`$PKG_CONFIG --variable=libdir smbclient`"/samba
+        SAVE_CFLAGS=$CFLAGS
+        SAVE_LIBS=$LIBS
+        CFLAGS="$CFLAGS $SMBCLIENT_CFLAGS -I/usr/include/samba-4.0"
+        LIBS="$LIBS -L${sambalibdir} -lidmap-samba4 -Wl,-rpath ${sambalibdir}"
+        AC_RUN_IFELSE(
+            [AC_LANG_SOURCE([
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <tevent.h>
+#include <core/ntstatus.h>
+
+struct winbindd_domain;
+
+/* overwrite some winbind internal functions */
+struct winbindd_domain *find_domain_from_name(const char *domain_name)
+{
+    return NULL;
+}
+
+bool get_global_winbindd_state_offline(void) {
+    return false;
+}
+
+struct tevent_context *winbind_event_context(void)
+{
+    return NULL;
+}
+
+struct idmap_methods;
+
+NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods);
+
+int main(void)
+{
+    int v;
+    NTSTATUS ret;
+
+    /* Check the versions we know about */
+    for (v = 5; v <= 6; v++) {
+        ret = smb_register_idmap(v, NULL, NULL);
+        if (ret != NT_STATUS_OBJECT_TYPE_MISMATCH) {
+            return v;
+        }
+    }
+
+    return -1;
+}])],
+            [AC_MSG_ERROR([idmap version test program is not expected to return 0])],
+            [idmap_test_result=$?; AC_MSG_RESULT([idmap test result is: $idmap_test_result])]
+        )
+    fi
+
+    CFLAGS=$SAVE_CFLAGS
+    LIBS=$SAVE_LIBS
+
+    if test $idmap_test_result -eq 5 -o $idmap_test_result -eq 6 ; then
+        idmap_version=$idmap_test_result
+    else
+        AC_MSG_ERROR([Cannot determine Samba's idmap interface version, please use --with-smb-idmap-interface-version])
+    fi
+    AC_MSG_NOTICE([Samba's idmap interface version: $idmap_version])
+    AC_DEFINE_UNQUOTED(SMB_IDMAP_INTERFACE_VERSION, $idmap_version,
+                       [Detected version of Samba's idmap plugin interface])
 fi
diff --git a/src/lib/winbind_idmap_sss/winbind_idmap_sss.c b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c
index 26f753708303f513e265de465e4d888f84e22b6a..ea5e727c3461524c3af84ea35c6ee032a5948ddf 100644
--- a/src/lib/winbind_idmap_sss/winbind_idmap_sss.c
+++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c
@@ -190,7 +190,13 @@ static struct idmap_methods sss_methods = {
     .sids_to_unixids = idmap_sss_sids_to_unixids,
 };
 
+#if SMB_IDMAP_INTERFACE_VERSION == 5
 NTSTATUS idmap_sss_init(void)
+#elif SMB_IDMAP_INTERFACE_VERSION == 6
+NTSTATUS idmap_sss_init(TALLOC_CTX *ctx)
+#else
+#error Unexpected Samba idmpa inferface version
+#endif
 {
     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
index 0f27c8561a540b63fb365edb79867eb4eb8d6e21..868049ffff7bd788507bf02d61245ff254aca465 100644
--- a/src/lib/winbind_idmap_sss/winbind_idmap_sss.h
+++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.h
@@ -32,6 +32,8 @@
 #include <ndr.h>
 #include <gen_ndr/security.h>
 
+#include "config.h"
+
 /* The following definitions are taken from the Samba header files
  * - winbindd/idmap_proto.h
  * - idmap.d
@@ -64,7 +66,9 @@ struct id_map {
     enum id_mapping status;
 };
 
-#define SMB_IDMAP_INTERFACE_VERSION 5
+#ifndef SMB_IDMAP_INTERFACE_VERSION
+#error Missing Samba idmap interface version
+#endif
 
 struct idmap_domain {
     const char *name;
-- 
2.17.0