URL: https://github.com/SSSD/sssd/pull/610
Author: jhrozek
 Title: #610: AD: consult the Partial Attribute Set instead of searching the GC 
for POSIX attributes
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/610/head:pr610
git checkout pr610
From ae2d31dd97553255cc927fb0e3ea4e09c134da3a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Sun, 8 Jul 2018 22:17:41 +0200
Subject: [PATCH 1/5] SDAP: Detect schemaNamingContext from the rootDSE

Whether an attribute is replicated to the Global Catalog or not can be
detected by checking the value of the isMemberOfPartialAttributeSet
attribute:
https://docs.microsoft.com/en-us/windows/desktop/ADSchema/a-ismemberofpartialattributeset

This attribute is present in all objects with the objectClass
attributeSchema in AD:
https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes

And finally, the attributeSchema objects in AD are present in a schema
naming context. The schema naming context is replicated to all DCs in the
forest even though their own naming context might be different:
https://docs.microsoft.com/en-us/windows/desktop/ad/naming-contexts-and-partitions

Where the schema naming context is located is given by the
schemaNamingContext attribute of the rootDSE.

This patch is trivial on its own and just reads schemaNamingContext from
the rootDSE and stores it in the sdap_options structure for later use.
---
 src/providers/ldap/sdap.c | 10 ++++++++++
 src/providers/ldap/sdap.h |  3 +++
 2 files changed, 13 insertions(+)

diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 0241a99e4..5c9d0a45d 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1284,6 +1284,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
     const char *last_usn_name;
     const char *last_usn_value;
     const char *entry_usn_name;
+    const char *schema_nc = NULL;
     char *endptr = NULL;
     int ret;
     int i;
@@ -1400,6 +1401,15 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
                    "(%s). Continuing without AD performance enhancements\n",
                    strerror(ret));
         }
+
+        ret = sysdb_attrs_get_string(rootdse,
+                                     SDAP_ROOTDSE_ATTR_AD_SCHEMA_NC,
+                                     &schema_nc);
+        if (ret == EOK) {
+            DEBUG(SSSDBG_CONF_SETTINGS,
+                  "Will look for schema at [%s]\n", schema_nc);
+            opts->schema_basedn = talloc_strdup(opts, schema_nc);
+        }
     }
 
     if (!last_usn_name) {
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index e892c4071..331db6637 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -130,6 +130,7 @@ struct sdap_ppolicy_data {
 #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts"
 #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext"
 #define SDAP_ROOTDSE_ATTR_AD_VERSION "domainControllerFunctionality"
+#define SDAP_ROOTDSE_ATTR_AD_SCHEMA_NC "schemaNamingContext"
 
 #define SDAP_IPA_USN "entryUSN"
 #define SDAP_IPA_LAST_USN "lastUSN"
@@ -496,8 +497,10 @@ struct sdap_options {
     /* The search bases for the domain or its subdomain */
     struct sdap_domain *sdom;
 
+    /* The options below are normally only used with AD */
     bool support_matching_rule;
     enum dc_functional_level dc_functional_level;
+    const char *schema_basedn;
 
     /* Certificate mapping support */
     struct sdap_certmap_ctx *sdap_certmap_ctx;

From 45dfef4bd889b497278a029788aeb0178fda1a41 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Wed, 4 Jul 2018 13:14:40 +0200
Subject: [PATCH 2/5] AD: Add Global Catalog usability check in subdomain code
 by looking at the schema

Addsa a new tevent request which checks for the presence of uidNumber
and gidNumber under the schema naming context, which is typically
cn=schema,cn=configuration,$BASEDN. For both objects representing each of
the attributes, the isMemberOfPartialAttributeSet attribute is requested. If
this attribute is set to TRUE, then the attribute corresponding to this
schema object had been replicated to the Global Catalog.

Because the isMemberOfPartialAttributeSet is not replicated to the GC
itself, we use the LDAP connection for the search.

Related:
https://pagure.io/SSSD/sssd/issue/3755
---
 src/providers/ad/ad_subdomains.c | 308 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 288 insertions(+), 20 deletions(-)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 84886e920..549c2c1f7 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -54,9 +54,39 @@
 #define SLAVE_DOMAIN_FILTER      "(&"SLAVE_DOMAIN_FILTER_BASE")"
 #define FOREST_ROOT_FILTER_FMT   "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))"
 
+/* Attributes of schema objects. See e.g.
+ * https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes
+ * for more details
+ */
+#define AD_SCHEMA_AT_OC         "attributeSchema"
+#define AD_AT_SCHEMA_NAME       "cn"
+#define AD_AT_SCHEMA_IS_REPL    "isMemberOfPartialAttributeSet"
+
 /* do not refresh more often than every 5 seconds for now */
 #define AD_SUBDOMAIN_REFRESH_LIMIT 5
 
+static void
+ad_disable_gc(struct ad_options *ad_options)
+{
+    errno_t ret;
+
+    if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
+        return;
+    }
+
+    DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested "
+          "but are not present on the server side. Global Catalog "
+          "lookups will be disabled\n");
+
+    ret = dp_opt_set_bool(ad_options->basic,
+                          AD_ENABLE_GC, false);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_MINOR_FAILURE,
+                "Could not turn off GC support\n");
+        /* Not fatal */
+    }
+}
+
 static struct sss_domain_info *
 ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs)
 {
@@ -1261,6 +1291,212 @@ static errno_t ad_get_root_domain_recv(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
+static void ad_check_gc_usability_search_done(struct tevent_req *subreq);
+
+struct ad_check_gc_usability_state {
+    struct sdap_options *sdap_opts;
+
+    const char *attrs[3];
+
+    bool is_gc_usable;
+};
+
+static struct tevent_req *
+ad_check_gc_usability_send(TALLOC_CTX *mem_ctx,
+                           struct tevent_context *ev,
+                           struct ad_options *ad_options,
+                           struct sdap_options *sdap_opts,
+                           struct sdap_id_op *op,
+                           const char *domain_name,
+                           const char *domain_sid)
+{
+    struct ad_check_gc_usability_state *state = NULL;
+    struct tevent_req *req = NULL;
+    struct tevent_req *subreq = NULL;
+    const char *filter = NULL;
+    errno_t ret;
+    bool uses_id_mapping;
+
+    req = tevent_req_create(mem_ctx, &state,
+                            struct ad_check_gc_usability_state);
+    if (req == NULL) {
+        return NULL;
+    }
+    state->sdap_opts = sdap_opts;
+    state->is_gc_usable = false;
+
+    if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
+        DEBUG(SSSDBG_TRACE_FUNC, "GC explicitly disabled\n");
+        state->is_gc_usable = false;
+        ret = EOK;
+        goto immediately;
+    }
+
+    uses_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+                                                        sdap_opts->idmap_ctx,
+                                                        domain_name,
+                                                        domain_sid);
+    if (uses_id_mapping == true) {
+        DEBUG(SSSDBG_TRACE_FUNC, "GC always usable while ID mapping\n");
+        state->is_gc_usable = true;
+        ret = EOK;
+        goto immediately;
+    }
+
+    /* The schema partition is replicated across all DCs in the forest, so
+     * it's safe to use the baseDN even if e.g. joined to a child domain
+     * even though the base DN "looks" like a part of the forest root
+     * tree. On the other hand, it doesn't make sense to guess the value
+     * if we can't detect it from the rootDSE.
+     */
+    if (state->sdap_opts->schema_basedn == NULL) {
+        DEBUG(SSSDBG_TRACE_FUNC,
+              "No idea where to look for the schema, disabling GC\n");
+        state->is_gc_usable = false;
+        ret = EOK;
+        goto immediately;
+    }
+
+    state->attrs[0] = AD_AT_SCHEMA_NAME;
+    state->attrs[1] = AD_AT_SCHEMA_IS_REPL;
+    state->attrs[2] = NULL;
+
+    DEBUG(SSSDBG_TRACE_FUNC, "Checking for POSIX attributes in GC\n");
+
+    filter = talloc_asprintf(
+                        state,
+                        "(&(objectclass=%s)(|(%s=%s)(%s=%s)))",
+                        AD_SCHEMA_AT_OC,
+                        AD_AT_SCHEMA_NAME,
+                        state->sdap_opts->user_map[SDAP_AT_USER_UID].name,
+                        AD_AT_SCHEMA_NAME,
+                        state->sdap_opts->group_map[SDAP_AT_GROUP_GID].name);
+    if (filter == NULL) {
+        ret = ENOMEM;
+        goto immediately;
+    }
+
+    subreq = sdap_get_generic_send(state,
+                                   ev,
+                                   state->sdap_opts,
+                                   sdap_id_op_handle(op),
+                                   state->sdap_opts->schema_basedn,
+                                   LDAP_SCOPE_SUBTREE,
+                                   filter,
+                                   state->attrs,
+                                   NULL, 0,
+                                   dp_opt_get_int(state->sdap_opts->basic,
+                                                  SDAP_SEARCH_TIMEOUT),
+                                   false);
+    if (subreq == NULL) {
+        ret = ENOMEM;
+        goto immediately;
+    }
+    tevent_req_set_callback(subreq, ad_check_gc_usability_search_done, req);
+
+    return req;
+
+immediately:
+    if (ret == EOK) {
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
+    tevent_req_post(req, ev);
+
+    return req;
+}
+
+static void ad_check_gc_usability_search_done(struct tevent_req *subreq)
+{
+    struct tevent_req *req = tevent_req_callback_data(subreq,
+                                                      struct tevent_req);
+    struct ad_check_gc_usability_state *state = tevent_req_data(req,
+                                          struct ad_check_gc_usability_state);
+    errno_t ret;
+    size_t reply_count;
+    struct sysdb_attrs **reply = NULL;
+    bool uid = false;
+    bool gid = false;
+
+    ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "sdap_get_generic_recv failed [%d]: %s\n",
+              ret, strerror(ret));
+        /* We continue to finish sdap_id_op. */
+    }
+
+    if (reply_count == 0) {
+        DEBUG(SSSDBG_TRACE_LIBS,
+              "Nothing found, so no POSIX attrs can exist\n");
+        state->is_gc_usable = false;
+        tevent_req_done(req);
+        return;
+    }
+
+    for (size_t i = 0; i < reply_count; i++) {
+        const char *name = NULL;
+        const char *is_in_partial_set = NULL;
+        bool *val = NULL;
+
+        ret = sysdb_attrs_get_string(reply[i], AD_AT_SCHEMA_NAME, &name);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_NAME);
+            continue;
+        }
+
+        if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_UID].name) == 0) {
+            val = &uid;
+        } else if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_GID].name) == 0) {
+            val = &gid;
+        } else {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected attribute\n");
+            continue;
+        }
+
+        ret = sysdb_attrs_get_string(reply[i],
+                                     AD_AT_SCHEMA_IS_REPL,
+                                     &is_in_partial_set);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_IS_REPL);
+            continue;
+        }
+
+        if (strcasecmp(is_in_partial_set, "true") == 0) {
+            *val = true;
+        }
+    }
+
+    if (uid == true && gid == true) {
+        state->is_gc_usable = true;
+    }
+
+    if (state->is_gc_usable == true) {
+        DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes. Global Catalog will "
+                                "be used for user and group lookups. Note that if "
+                                "only a subset of POSIX attributes is present "
+                                "in GC, the non-replicated attributes are "
+                                "currently not read from the LDAP port\n");
+    }
+
+    tevent_req_done(req);
+}
+
+static errno_t ad_check_gc_usability_recv(struct tevent_req *req,
+                                          bool *_is_gc_usable)
+{
+    struct ad_check_gc_usability_state *state = NULL;
+
+    state = tevent_req_data(req, struct ad_check_gc_usability_state);
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    *_is_gc_usable = state->is_gc_usable;
+    return EOK;
+}
+
 struct ad_subdomains_refresh_state {
     struct tevent_context *ev;
     struct be_ctx *be_ctx;
@@ -1268,11 +1504,14 @@ struct ad_subdomains_refresh_state {
     struct sdap_id_op *sdap_op;
     struct sdap_id_ctx *id_ctx;
     struct ad_options *ad_options;
+
+    char *forest;
 };
 
 static errno_t ad_subdomains_refresh_retry(struct tevent_req *req);
 static void ad_subdomains_refresh_connect_done(struct tevent_req *subreq);
 static void ad_subdomains_refresh_master_done(struct tevent_req *subreq);
+static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq);
 static void ad_subdomains_refresh_root_done(struct tevent_req *subreq);
 static void ad_subdomains_refresh_done(struct tevent_req *subreq);
 
@@ -1385,37 +1624,73 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
     struct ad_subdomains_refresh_state *state;
     struct tevent_req *req;
     const char *realm;
-    const char *ad_domain;
     char *master_sid;
     char *flat_name;
-    char *forest;
     errno_t ret;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct ad_subdomains_refresh_state);
 
     ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid,
-                                NULL, &forest);
+                                NULL, &state->forest);
     talloc_zfree(subreq);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information "
               "[%d]: %s\n", ret, sss_strerror(ret));
-        goto done;
+        tevent_req_error(req, ret);
+        return;
     }
 
     realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM);
     if (realm == NULL) {
         DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n");
-        ret = EINVAL;
-        goto done;
+        tevent_req_error(req, EINVAL);
+        return;
     }
 
     ret = sysdb_master_domain_add_info(state->be_ctx->domain, realm,
-                                       flat_name, master_sid, forest, NULL);
+                                       flat_name, master_sid, state->forest, NULL);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info [%d]: %s\n",
               ret, sss_strerror(ret));
-        goto done;
+        tevent_req_error(req, ret);
+        return;
+    }
+
+    subreq = ad_check_gc_usability_send(state,
+                                        state->ev,
+                                        state->ad_options,
+                                        state->id_ctx->opts,
+                                        state->sdap_op,
+                                        state->be_ctx->domain->name,
+                                        master_sid);
+    if (subreq == NULL) {
+        tevent_req_error(req, ENOMEM);
+        return;
+    }
+    tevent_req_set_callback(subreq, ad_subdomains_refresh_gc_check_done, req);
+}
+
+static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq)
+{
+    struct ad_subdomains_refresh_state *state;
+    struct tevent_req *req;
+    const char *ad_domain;
+    bool is_gc_usable;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+    state = tevent_req_data(req, struct ad_subdomains_refresh_state);
+
+    ret = ad_check_gc_usability_recv(subreq, &is_gc_usable);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get GC usability status\n");
+        is_gc_usable = false;
+    }
+
+    if (is_gc_usable == false) {
+        ad_disable_gc(state->ad_options);
     }
 
     /*
@@ -1428,7 +1703,8 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
                            state->be_ctx->domain->name) == 0) {
                 DEBUG(SSSDBG_TRACE_FUNC,
                       "No other enabled domain than master.\n");
-                goto done;
+                tevent_req_done(req);
+                return;
             }
         }
     }
@@ -1440,24 +1716,16 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
         ad_domain = state->sd_ctx->be_ctx->domain->name;
     }
 
-    subreq = ad_get_root_domain_send(state, state->ev, ad_domain, forest,
+    subreq = ad_get_root_domain_send(state, state->ev, ad_domain, state->forest,
                                      sdap_id_op_handle(state->sdap_op),
                                      state->sd_ctx);
     if (subreq == NULL) {
-        ret = ENOMEM;
-        goto done;
+        tevent_req_error(req, ENOMEM);
+        return;
     }
 
     tevent_req_set_callback(subreq, ad_subdomains_refresh_root_done, req);
     return;
-
-done:
-    if (ret != EOK) {
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    tevent_req_done(req);
 }
 
 static void ad_subdomains_refresh_root_done(struct tevent_req *subreq)

From b2b685d140207d2da20c1d73d84389af59417e99 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Wed, 4 Jul 2018 20:10:30 +0200
Subject: [PATCH 3/5] AD: Remove the legacy check from
 ad_get_account_domain_posix_check request

Previously, the POSIX attribute presence check was run as part of the ID
request, so it was necessary to also run the check as part of the
get-domain-for-ID request.

Since moving the POSIX check to being a part of the subdomain provider,
this is no longer needed as the subdomain provider disables the GC
support on its own if required. Therefore we can just remove the POSIX
check from the get-domain-for-ID request.

Related:
https://pagure.io/SSSD/sssd/issue/3755
---
 src/providers/ad/ad_id.c | 74 ------------------------------------------------
 1 file changed, 74 deletions(-)

diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 782d9bc40..951799768 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -1080,7 +1080,6 @@ ad_enumeration_recv(struct tevent_req *req)
 static errno_t ad_get_account_domain_prepare_search(struct tevent_req *req);
 static errno_t ad_get_account_domain_connect_retry(struct tevent_req *req);
 static void ad_get_account_domain_connect_done(struct tevent_req *subreq);
-static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq);
 static void ad_get_account_domain_search(struct tevent_req *req);
 static void ad_get_account_domain_search_done(struct tevent_req *subreq);
 static void ad_get_account_domain_evaluate(struct tevent_req *req);
@@ -1303,79 +1302,6 @@ static void ad_get_account_domain_connect_done(struct tevent_req *subreq)
         return;
     }
 
-    /* If POSIX attributes have been requested with an AD server and we
-     * have no idea about POSIX attributes support, run a one-time check
-     */
-    if (state->sdap_id_ctx->srv_opts &&
-        state->sdap_id_ctx->srv_opts->posix_checked == false) {
-        subreq = sdap_gc_posix_check_send(state,
-                                          state->ev,
-                                          state->sdap_id_ctx->opts,
-                                          sdap_id_op_handle(state->op),
-                                          dp_opt_get_int(
-                                              state->sdap_id_ctx->opts->basic,
-                                              SDAP_SEARCH_TIMEOUT));
-        if (subreq == NULL) {
-            tevent_req_error(req, ENOMEM);
-            return;
-        }
-        tevent_req_set_callback(subreq, ad_get_account_domain_posix_check_done, req);
-        return;
-    }
-
-    ad_get_account_domain_search(req);
-}
-
-static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq)
-{
-    struct tevent_req *req = tevent_req_callback_data(subreq,
-                                                      struct tevent_req);
-    struct ad_get_account_domain_state *state = tevent_req_data(req,
-                                          struct ad_get_account_domain_state);
-    int dp_error = DP_ERR_FATAL;
-    bool has_posix;
-    errno_t ret;
-    errno_t ret2;
-
-    ret = sdap_gc_posix_check_recv(subreq, &has_posix);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        /* We can only finish the id_op on error as the connection
-         * is re-used by the real search
-         */
-        ret2 = sdap_id_op_done(state->op, ret, &dp_error);
-        if (dp_error == DP_ERR_OK && ret2 != EOK) {
-            /* retry */
-            ret = ad_get_account_domain_connect_retry(req);
-            if (ret != EOK) {
-                tevent_req_error(req, ret);
-            }
-            return;
-        }
-
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    state->sdap_id_ctx->srv_opts->posix_checked = true;
-
-    /*
-     * If the GC has no POSIX attributes, there is nothing we can do.
-     * Return an error and let the responders disable the functionality
-     * from now on.
-     */
-    if (has_posix == false) {
-        DEBUG(SSSDBG_CONF_SETTINGS,
-              "The Global Catalog has no POSIX attributes\n");
-
-        disable_gc(state->id_ctx->ad_options);
-        dp_reply_std_set(&state->reply,
-                         DP_ERR_DECIDE, ERR_GET_ACCT_DOM_NOT_SUPPORTED,
-                         NULL);
-        tevent_req_done(req);
-        return;
-    }
-
     ad_get_account_domain_search(req);
 }
 

From cc4c9c9066e3678d10446d13bc1f4e39aa45988d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Sat, 30 Jun 2018 12:31:13 +0200
Subject: [PATCH 4/5] LDAP/AD: Remove the legacy POSIX check from user, group
 and enumeration searches

This code is superseded by the POSIX check in the subdomains provider.

Related:
https://pagure.io/SSSD/sssd/issue/3755
---
 src/providers/ad/ad_id.c             |  43 +------------
 src/providers/ldap/ldap_id.c         | 121 -----------------------------------
 src/providers/ldap/sdap_async_enum.c | 105 +-----------------------------
 3 files changed, 4 insertions(+), 265 deletions(-)

diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 951799768..1da48433e 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -29,28 +29,6 @@
 #include "providers/ldap/sdap_idmap.h"
 #include "providers/ldap/sdap_async.h"
 
-static void
-disable_gc(struct ad_options *ad_options)
-{
-    errno_t ret;
-
-    if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
-        return;
-    }
-
-    DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested "
-          "but are not present on the server side. Global Catalog "
-          "lookups will be disabled\n");
-
-    ret = dp_opt_set_bool(ad_options->basic,
-                          AD_ENABLE_GC, false);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_MINOR_FAILURE,
-                "Could not turn off GC support\n");
-        /* Not fatal */
-    }
-}
-
 static bool ad_account_can_shortcut(struct sdap_idmap_ctx *idmap_ctx,
                                     struct sss_domain_info *domain,
                                     int filter_type,
@@ -296,14 +274,12 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
     if (sdap_err == EOK) {
         tevent_req_done(req);
         return;
-    } else if (sdap_err == ERR_NO_POSIX) {
-        disable_gc(state->ad_options);
     } else if (sdap_err != ENOENT) {
         ret = EIO;
         goto fail;
     }
 
-    /* Ret is only ENOENT or ERR_NO_POSIX now. Try the next connection */
+    /* Ret is only ENOENT now. Try the next connection */
     state->cindex++;
     ret = ad_handle_acct_info_step(req);
     if (ret != EAGAIN) {
@@ -710,22 +686,7 @@ ad_enumeration_done(struct tevent_req *subreq)
 
     ret = sdap_dom_enum_ex_recv(subreq);
     talloc_zfree(subreq);
-    if (ret == ERR_NO_POSIX) {
-        /* Retry enumerating the same domain again, this time w/o
-         * connecting to GC
-         */
-        disable_gc(state->id_ctx->ad_options);
-        ret = ad_enum_sdom(req, state->sditer, state->id_ctx);
-        if (ret != EOK) {
-            DEBUG(SSSDBG_OP_FAILURE,
-                "Could not retry domain %s\n", state->sditer->dom->name);
-            tevent_req_error(req, ret);
-            return;
-        }
-
-        /* Execution will resume in ad_enumeration_done */
-        return;
-    } else if (ret != EOK) {
+    if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               "Could not enumerate domain %s\n", state->sditer->dom->name);
         tevent_req_error(req, ret);
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index ebf5d9cb2..9e8289904 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -66,7 +66,6 @@ struct users_get_state {
 
 static int users_get_retry(struct tevent_req *req);
 static void users_get_connect_done(struct tevent_req *subreq);
-static void users_get_posix_check_done(struct tevent_req *subreq);
 static void users_get_search(struct tevent_req *req);
 static void users_get_done(struct tevent_req *subreq);
 
@@ -408,66 +407,6 @@ static void users_get_connect_done(struct tevent_req *subreq)
         return;
     }
 
-    /* If POSIX attributes have been requested with an AD server and we
-     * have no idea about POSIX attributes support, run a one-time check
-     */
-    if (should_run_posix_check(state->ctx,
-                               state->conn,
-                               state->use_id_mapping,
-                               !state->non_posix)) {
-        subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts,
-                                          sdap_id_op_handle(state->op),
-                                          dp_opt_get_int(state->ctx->opts->basic,
-                                                         SDAP_SEARCH_TIMEOUT));
-        if (subreq == NULL) {
-            tevent_req_error(req, ENOMEM);
-            return;
-        }
-        tevent_req_set_callback(subreq, users_get_posix_check_done, req);
-        return;
-    }
-
-    users_get_search(req);
-}
-
-static void users_get_posix_check_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    errno_t ret2;
-    bool has_posix;
-    int dp_error;
-    struct tevent_req *req = tevent_req_callback_data(subreq,
-                                                      struct tevent_req);
-    struct users_get_state *state = tevent_req_data(req,
-                                                    struct users_get_state);
-
-    ret = sdap_gc_posix_check_recv(subreq, &has_posix);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        /* We can only finish the id_op on error as the connection
-         * is re-used by the user search
-         */
-        ret2 = sdap_id_op_done(state->op, ret, &dp_error);
-        if (dp_error == DP_ERR_OK && ret2 != EOK) {
-            /* retry */
-            ret = users_get_retry(req);
-            if (ret != EOK) {
-                tevent_req_error(req, ret);
-            }
-            return;
-        }
-    }
-
-    state->ctx->srv_opts->posix_checked = true;
-
-    /* If the check ran to completion, we know for certain about the attributes
-     */
-    if (ret == EOK && has_posix == false) {
-        state->sdap_ret = ERR_NO_POSIX;
-        tevent_req_done(req);
-        return;
-    }
-
     users_get_search(req);
 }
 
@@ -691,7 +630,6 @@ struct groups_get_state {
 
 static int groups_get_retry(struct tevent_req *req);
 static void groups_get_connect_done(struct tevent_req *subreq);
-static void groups_get_posix_check_done(struct tevent_req *subreq);
 static void groups_get_mpg_done(struct tevent_req *subreq);
 static errno_t groups_get_handle_no_group(struct tevent_req *req);
 static void groups_get_search(struct tevent_req *req);
@@ -953,65 +891,6 @@ static void groups_get_connect_done(struct tevent_req *subreq)
         return;
     }
 
-    /* If POSIX attributes have been requested with an AD server and we
-     * have no idea about POSIX attributes support, run a one-time check
-     */
-    if (should_run_posix_check(state->ctx,
-                               state->conn,
-                               state->use_id_mapping,
-                               !state->non_posix)) {
-        subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts,
-                                          sdap_id_op_handle(state->op),
-                                          dp_opt_get_int(state->ctx->opts->basic,
-                                                         SDAP_SEARCH_TIMEOUT));
-        if (subreq == NULL) {
-            tevent_req_error(req, ENOMEM);
-            return;
-        }
-        tevent_req_set_callback(subreq, groups_get_posix_check_done, req);
-        return;
-    }
-
-    groups_get_search(req);
-}
-
-static void groups_get_posix_check_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    bool has_posix;
-    int dp_error;
-    struct tevent_req *req = tevent_req_callback_data(subreq,
-                                                      struct tevent_req);
-    struct groups_get_state *state = tevent_req_data(req,
-                                                     struct groups_get_state);
-
-    ret = sdap_gc_posix_check_recv(subreq, &has_posix);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        /* We can only finish the id_op on error as the connection
-         * is re-used by the group search
-         */
-        ret = sdap_id_op_done(state->op, ret, &dp_error);
-        if (dp_error == DP_ERR_OK && ret != EOK) {
-            /* retry */
-            ret = groups_get_retry(req);
-            if (ret != EOK) {
-                tevent_req_error(req, ret);
-            }
-            return;
-        }
-    }
-
-    state->ctx->srv_opts->posix_checked = true;
-
-    /* If the check ran to completion, we know for certain about the attributes
-     */
-    if (has_posix == false) {
-        state->sdap_ret = ERR_NO_POSIX;
-        tevent_req_done(req);
-        return;
-    }
-
     groups_get_search(req);
 }
 
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index ea9d51adc..899d59d38 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -69,8 +69,6 @@ static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req,
                                       tevent_req_fn tcb);
 static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq);
 static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq);
-static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq);
-static errno_t sdap_dom_enum_search_users(struct tevent_req *req);
 static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq);
 static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq);
 static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq);
@@ -181,118 +179,19 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq)
                                                       struct tevent_req);
     struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
                                                 struct sdap_dom_enum_ex_state);
-    bool use_id_mapping;
-    errno_t ret;
 
     if (sdap_dom_enum_ex_connected(subreq) == false) {
         return;
     }
 
-    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
-                                            state->ctx->opts->idmap_ctx,
-                                            state->sdom->dom->name,
-                                            state->sdom->dom->domain_id);
-
-    /* If POSIX attributes have been requested with an AD server and we
-     * have no idea about POSIX attributes support, run a one-time check
-     */
-    if (should_run_posix_check(state->ctx,
-                               state->user_conn,
-                               use_id_mapping,
-                               true)) {
-        subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts,
-                                          sdap_id_op_handle(state->user_op),
-                                          dp_opt_get_int(state->ctx->opts->basic,
-                                                         SDAP_SEARCH_TIMEOUT));
-        if (subreq == NULL) {
-            tevent_req_error(req, ENOMEM);
-            return;
-        }
-        tevent_req_set_callback(subreq,
-                                sdap_dom_enum_ex_posix_check_done, req);
-        return;
-    }
-
-
-    ret = sdap_dom_enum_search_users(req);
-    if (ret != EOK) {
-        tevent_req_error(req, ret);
-        return;
-    }
-    /* Execution resumes in sdap_dom_enum_ex_users_done */
-}
-
-static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    bool has_posix;
-    int dp_error;
-
-    struct tevent_req *req = tevent_req_callback_data(subreq,
-                                                      struct tevent_req);
-    struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
-                                                struct sdap_dom_enum_ex_state);
-
-    ret = sdap_gc_posix_check_recv(subreq, &has_posix);
-    talloc_zfree(subreq);
-    if (ret != EOK && ret != ERR_NO_POSIX) {
-        /* We can only finish the id_op on error as the connection
-         * is re-used by the user search
-         */
-        ret = sdap_id_op_done(state->user_op, ret, &dp_error);
-        if (dp_error == DP_ERR_OK && ret != EOK) {
-            /* retry */
-            ret = sdap_dom_enum_ex_retry(req, state->user_op,
-                                         sdap_dom_enum_ex_get_users);
-            if (ret != EOK) {
-                tevent_req_error(req, ret);
-            }
-            return;
-        } else if (dp_error == DP_ERR_OFFLINE) {
-            DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n");
-            tevent_req_done(req);
-            return;
-        } else {
-            /* Non-recoverable error */
-            DEBUG(SSSDBG_OP_FAILURE,
-                "POSIX check failed: %d: %s\n", ret, sss_strerror(ret));
-            tevent_req_error(req, ret);
-            return;
-        }
-    }
-
-    state->ctx->srv_opts->posix_checked = true;
-
-    /* If the check ran to completion, we know for certain about the attributes
-     */
-    if (has_posix == false) {
-        tevent_req_error(req, ERR_NO_POSIX);
-        return;
-    }
-
-
-    ret = sdap_dom_enum_search_users(req);
-    if (ret != EOK) {
-        tevent_req_error(req, ret);
-        return;
-    }
-    /* Execution resumes in sdap_dom_enum_ex_users_done */
-}
-
-static errno_t sdap_dom_enum_search_users(struct tevent_req *req)
-{
-    struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
-                                                struct sdap_dom_enum_ex_state);
-    struct tevent_req *subreq;
-
     subreq = enum_users_send(state, state->ev,
                              state->ctx, state->sdom,
                              state->user_op, state->purge);
     if (subreq == NULL) {
-        return ENOMEM;
+        tevent_req_error(req, ENOMEM);
+        return;
     }
     tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req);
-    return EOK;
 }
 
 static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq)

From e6f2b40215fa0e3e49f3efeded77e226f198225b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Sat, 30 Jun 2018 13:21:18 +0200
Subject: [PATCH 5/5] LDAP: Remove the legacy POSIX check itself

This code is no longer needed now.

Related:
https://pagure.io/SSSD/sssd/issue/3755
---
 src/providers/ad/ad_common.c     |   2 -
 src/providers/ldap/ldap_common.c |  17 ----
 src/providers/ldap/ldap_common.h |   7 --
 src/providers/ldap/sdap.h        |   1 -
 src/providers/ldap/sdap_async.c  | 174 ---------------------------------------
 src/providers/ldap/sdap_async.h  |  13 ---
 6 files changed, 214 deletions(-)

diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index eaf0814f1..6d395cfb1 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -1388,7 +1388,6 @@ ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
         clist[cindex] = ad_ctx->gc_ctx;
         clist[cindex]->ignore_mark_offline = true;
         clist[cindex]->no_mpg_user_fallback = true;
-        clist[cindex]->check_posix_attrs = true;
         cindex++;
     }
 
@@ -1435,7 +1434,6 @@ ad_user_conn_list(TALLOC_CTX *mem_ctx,
             && IS_SUBDOMAIN(dom)) {
         clist[cindex] = ad_ctx->gc_ctx;
         clist[cindex]->ignore_mark_offline = true;
-        clist[cindex]->check_posix_attrs = true;
         cindex++;
     }
 
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index a0a9b8523..9cd8ec09c 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -884,20 +884,3 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
 
     return sdap_ctx;
 }
-
-bool should_run_posix_check(struct sdap_id_ctx *ctx,
-                            struct sdap_id_conn_ctx *conn,
-                            bool use_id_mapping,
-                            bool posix_request)
-{
-    if (use_id_mapping == false &&
-            posix_request == true &&
-            ctx->opts->schema_type == SDAP_SCHEMA_AD &&
-            conn->check_posix_attrs == true &&
-            ctx->srv_opts &&
-            ctx->srv_opts->posix_checked == false) {
-        return true;
-    }
-
-    return false;
-}
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 3de3568cb..6c08d789b 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -59,8 +59,6 @@ struct sdap_id_conn_ctx {
     bool ignore_mark_offline;
     /* do not fall back to user lookups for mpg domains on this connection */
     bool no_mpg_user_fallback;
-    /* check if this connection contains POSIX attributes */
-    bool check_posix_attrs;
 };
 
 struct sdap_id_ctx {
@@ -309,11 +307,6 @@ char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx,
                                              const char *princ,
                                              struct dp_option *sdap_basic_opts);
 
-bool should_run_posix_check(struct sdap_id_ctx *ctx,
-                            struct sdap_id_conn_ctx *conn,
-                            bool id_mapping,
-                            bool posix_request);
-
 char *sdap_get_access_filter(TALLOC_CTX *mem_ctx,
                              const char *base_filter);
 
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 331db6637..31c25c32f 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -514,7 +514,6 @@ struct sdap_server_opts {
     char *max_group_value;
     char *max_service_value;
     char *max_sudo_value;
-    bool posix_checked;
 };
 
 struct sdap_id_ctx;
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 1e77b1c3c..8fc832ae5 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -2572,180 +2572,6 @@ int sdap_asq_search_recv(struct tevent_req *req,
     return EOK;
 }
 
-/* ==POSIX attribute presence test================================= */
-static void sdap_gc_posix_check_done(struct tevent_req *subreq);
-static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh,
-                                         struct sdap_msg *msg,
-                                         void *pvt);
-
-struct sdap_gc_posix_check_state {
-    struct tevent_context *ev;
-    struct sdap_options *opts;
-    struct sdap_handle *sh;
-    int timeout;
-
-    const char **attrs;
-    const char *filter;
-
-    bool has_posix;
-};
-
-struct tevent_req *
-sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev,
-                         struct sdap_options *opts, struct sdap_handle *sh,
-                         int timeout)
-{
-    struct tevent_req *req = NULL;
-    struct tevent_req *subreq = NULL;
-    struct sdap_gc_posix_check_state *state;
-    errno_t ret;
-
-    req = tevent_req_create(memctx, &state, struct sdap_gc_posix_check_state);
-    if (req == NULL) {
-        return NULL;
-    }
-    state->ev = ev;
-    state->sh = sh;
-    state->opts = opts;
-    state->timeout = timeout;
-
-    state->attrs = talloc_array(state, const char *, 4);
-    if (state->attrs == NULL) {
-        ret = ENOMEM;
-        goto fail;
-    }
-    state->attrs[0] = "objectclass";
-    state->attrs[1] = opts->user_map[SDAP_AT_USER_UID].name;
-    state->attrs[2] = opts->group_map[SDAP_AT_GROUP_GID].name;
-    state->attrs[3] = NULL;
-
-    state->filter = talloc_asprintf(state,
-        "(|(&(%s=*)(objectclass=%s))(&(%s=*)(objectclass=%s)))",
-                                    opts->user_map[SDAP_AT_USER_UID].name,
-                                    opts->user_map[SDAP_OC_USER].name,
-                                    opts->group_map[SDAP_AT_GROUP_GID].name,
-                                    opts->group_map[SDAP_OC_GROUP].name);
-    if (state->filter == NULL) {
-        ret = ENOMEM;
-        goto fail;
-    }
-
-    subreq = sdap_get_generic_ext_send(state, state->ev, state->opts,
-                                 state->sh,
-                                 "",
-                                 LDAP_SCOPE_SUBTREE, state->filter,
-                                 state->attrs,
-                                 NULL, NULL, 1, state->timeout,
-                                 sdap_gc_posix_check_parse, state,
-                                 SDAP_SRCH_FLG_SIZELIMIT_SILENT);
-    if (subreq == NULL) {
-        ret = ENOMEM;
-        goto fail;
-    }
-    tevent_req_set_callback(subreq, sdap_gc_posix_check_done, req);
-
-    return req;
-
-fail:
-    tevent_req_error(req, ret);
-    tevent_req_post(req, ev);
-    return req;
-}
-
-static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh,
-                                         struct sdap_msg *msg,
-                                         void *pvt)
-{
-    struct berval **vals = NULL;
-    struct sdap_gc_posix_check_state *state =
-        talloc_get_type(pvt, struct sdap_gc_posix_check_state);
-    char *dn;
-    char *endptr;
-
-    dn = ldap_get_dn(sh->ldap, msg->msg);
-    if (dn == NULL) {
-        DEBUG(SSSDBG_TRACE_LIBS,
-              "Search did not find any entry with POSIX attributes\n");
-        goto done;
-    }
-    DEBUG(SSSDBG_TRACE_LIBS, "Found [%s] with POSIX attributes\n", dn);
-    ldap_memfree(dn);
-
-    vals = ldap_get_values_len(sh->ldap, msg->msg,
-                               state->opts->user_map[SDAP_AT_USER_UID].name);
-    if (vals == NULL) {
-        vals = ldap_get_values_len(sh->ldap, msg->msg,
-                               state->opts->group_map[SDAP_AT_GROUP_GID].name);
-        if (vals == NULL) {
-            DEBUG(SSSDBG_TRACE_LIBS, "Entry does not have POSIX attrs?\n");
-            goto done;
-        }
-    }
-
-    if (vals[0] == NULL) {
-        DEBUG(SSSDBG_TRACE_LIBS, "No value for POSIX attr\n");
-        goto done;
-    }
-
-    errno = 0;
-    strtouint32(vals[0]->bv_val, &endptr, 10);
-    if (errno || *endptr || (vals[0]->bv_val == endptr)) {
-        DEBUG(SSSDBG_MINOR_FAILURE,
-              "POSIX attribute is not a number: %s\n", vals[0]->bv_val);
-    }
-
-    state->has_posix = true;
-done:
-    ldap_value_free_len(vals);
-    return EOK;
-}
-
-static void sdap_gc_posix_check_done(struct tevent_req *subreq)
-{
-    struct tevent_req *req = tevent_req_callback_data(subreq,
-                                                      struct tevent_req);
-    struct sdap_gc_posix_check_state *state =
-        tevent_req_data(req, struct sdap_gc_posix_check_state);
-    errno_t ret;
-
-    ret = sdap_get_generic_ext_recv(subreq, NULL, NULL, NULL);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE,
-              "sdap_get_generic_ext_recv failed [%d]: %s\n",
-              ret, strerror(ret));
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    /* Positive hit is definitive, no need to search other bases */
-    if (state->has_posix == true) {
-        DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes. Global Catalog will "
-                                "be used for user and group lookups. Note that if "
-                                "only a subset of POSIX attributes is present "
-                                "in GC, the non-replicated attributes are "
-                                "currently not read from the LDAP port\n");
-        tevent_req_done(req);
-        return;
-    }
-
-    /* All bases done! */
-    DEBUG(SSSDBG_TRACE_LIBS, "Cycled through all bases\n");
-    tevent_req_done(req);
-}
-
-int sdap_gc_posix_check_recv(struct tevent_req *req,
-                             bool *_has_posix)
-{
-    struct sdap_gc_posix_check_state *state = tevent_req_data(req,
-                                            struct sdap_gc_posix_check_state);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *_has_posix = state->has_posix;
-    return EOK;
-}
-
 /* ==Generic Deref Search============================================ */
 enum sdap_deref_type {
     SDAP_DEREF_OPENLDAP,
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 6ca3ed8d8..6d09aca7a 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -281,19 +281,6 @@ int sdap_deref_search_recv(struct tevent_req *req,
                            size_t *reply_count,
                            struct sdap_deref_attrs ***reply);
 
-/*
- * This request should only be ran against a Global Catalog connection
- * because it uses a NULL search base to search all domains in the forest,
- * which would return an error with an LDAP port:
- *  https://technet.microsoft.com/en-us/library/cc755809(v=ws.10).aspx
- */
-struct tevent_req *
-sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev,
-                         struct sdap_options *opts, struct sdap_handle *sh,
-                         int timeout);
-
-int sdap_gc_posix_check_recv(struct tevent_req *req,
-                             bool *_has_posix);
 
 struct tevent_req *
 sdap_sd_search_send(TALLOC_CTX *memctx,
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/sssd-devel@lists.fedorahosted.org/message/O5FUUT6JQZTCPLTTU6FNEVNMTT43Q67S/

Reply via email to