From 3ca835b6bd6ceb20e494e846c41668194ac6e1b3 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 f9115c7965..e16495307b 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -2715,7 +2715,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" },
@@ -2728,18 +2730,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 1c2b7f996a..7244f647a0 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -241,7 +241,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 b3981dcae9f8b2ba2974b7a86f6a16384b85094e 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/providers/ipa/ipa_hosts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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;
