From 003a107b35dce2bec7a8db04ce0fdbe8eeb1d647 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 12 Mar 2019 12:48:29 +0100
Subject: [PATCH 1/2] SDAP: Add sdap_has_deref_support_ex()

Related:
https://pagure.io/SSSD/sssd/issue/3979

In some cases, it makes sense for performance reasons to disable
dereference when processing user groups. But since processing of HBAC host
groups is not much of a performance sensitive operation, we can get away
with ignoring the client side setting and always using the dereference
branch if the server supports the dereference call.

This patch extends the sdap_has_deref_support call with a flag that
allows the caller to bypass the client side check.
---
 src/providers/ldap/sdap_async.c     | 19 ++++++++++++++-----
 src/providers/ldap/sdap_async.h     |  6 +++++-
 src/tests/cmocka/common_mock_sdap.c | 10 +++++++++-
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 1b7de0c677..ae502745c3 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -2887,7 +2887,9 @@ int sdap_deref_search_recv(struct tevent_req *req,
     return EOK;
 }
 
-bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts)
+bool sdap_has_deref_support_ex(struct sdap_handle *sh,
+                               struct sdap_options *opts,
+                               bool ignore_client)
 {
     const char *deref_oids[][2] = { { LDAP_SERVER_ASQ_OID, "ASQ" },
                                     { LDAP_CONTROL_X_DEREF, "OpenLDAP" },
@@ -2900,18 +2902,25 @@ bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts)
         return false;
     }
 
-    deref_threshold = dp_opt_get_int(opts->basic, SDAP_DEREF_THRESHOLD);
-    if (deref_threshold == 0) {
-        return false;
+    if (ignore_client == false) {
+        deref_threshold = dp_opt_get_int(opts->basic, SDAP_DEREF_THRESHOLD);
+        if (deref_threshold == 0) {
+            return false;
+        }
     }
 
     for (i=0; deref_oids[i][0]; i++) {
         if (sdap_is_control_supported(sh, deref_oids[i][0])) {
             DEBUG(SSSDBG_TRACE_FUNC, "The server supports deref method %s\n",
-                      deref_oids[i][1]);
+                  deref_oids[i][1]);
             return true;
         }
     }
 
     return false;
 }
+
+bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts)
+{
+    return sdap_has_deref_support_ex(sh, opts, false);
+}
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 3915f24d6b..eebb01c118 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -252,7 +252,11 @@ int sdap_get_generic_recv(struct tevent_req *req,
                          TALLOC_CTX *mem_ctx, size_t *reply_count,
                          struct sysdb_attrs ***reply_list);
 
-bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts);
+bool sdap_has_deref_support_ex(struct sdap_handle *sh,
+                               struct sdap_options *opts,
+                               bool ignore_client);
+bool sdap_has_deref_support(struct sdap_handle *sh,
+                            struct sdap_options *opts);
 
 enum sdap_deref_flags {
     SDAP_DEREF_FLG_SILENT = 1 << 0,     /* Do not warn if dereference fails */
diff --git a/src/tests/cmocka/common_mock_sdap.c b/src/tests/cmocka/common_mock_sdap.c
index fa4787c4bb..9bbaaf4fb7 100644
--- a/src/tests/cmocka/common_mock_sdap.c
+++ b/src/tests/cmocka/common_mock_sdap.c
@@ -76,7 +76,15 @@ struct sdap_handle *mock_sdap_handle(TALLOC_CTX *mem_ctx)
  * their mock equivalent shall be used.
  */
 
-bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts)
+bool sdap_has_deref_support_ex(struct sdap_handle *sh,
+                               struct sdap_options *opts,
+                               bool ignore_client)
+{
+    return sss_mock_type(bool);
+}
+
+bool sdap_has_deref_support(struct sdap_handle *sh,
+                            struct sdap_options *opts)
 {
     return sss_mock_type(bool);
 }

From f2348a627ee87ec2edd63d78d0e1d42e7117d8a1 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 12 Mar 2019 12:48:48 +0100
Subject: [PATCH 2/2] IPA: Use dereference for host groups even if the
 configuration disables dereference

Related:
https://pagure.io/SSSD/sssd/issue/3979

In some cases, it makes sense for performance reasons to disable
dereference when processing user groups. But since processing of HBAC host
groups is not much of a performance sensitive operation, we can get away
with ignoring the client side setting and always using the dereference
branch if the server supports the dereference call.
---
 src/man/sssd-ldap.5.xml       | 11 +++++++++--
 src/providers/ipa/ipa_hosts.c |  2 +-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 5df7f2e7d7..b30a54f19e 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -1542,8 +1542,15 @@
                             they are looked up individually.
                         </para>
                         <para>
-                            You can turn off dereference lookups completely by
-                            setting the value to 0.
+                            You can turn off dereference lookups completely
+                            by setting the value to 0. Please note that
+                            there are some codepaths in SSSD, like the IPA
+                            HBAC provider, that are only implemented using
+                            the dereference call, so even with dereference
+                            explicitly disabled, those parts will still
+                            use dereference if the server supports it
+                            and advertises the dereference control in the
+                            rootDSE object.
                         </para>
                         <para>
                             A dereference lookup is a means of fetching all
diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ipa/ipa_hosts.c
index 288bfb8657..e209bca674 100644
--- a/src/providers/ipa/ipa_hosts.c
+++ b/src/providers/ipa/ipa_hosts.c
@@ -157,7 +157,7 @@ ipa_host_info_done(struct tevent_req *subreq)
                 return;
             }
 
-            if (!sdap_has_deref_support(state->sh, state->opts)) {
+            if (!sdap_has_deref_support_ex(state->sh, state->opts, true)) {
                 DEBUG(SSSDBG_CRIT_FAILURE, "Server does not support deref\n");
                 tevent_req_error(req, EIO);
                 return;
