>From 8640ce37711863b57f72f61bfd0bd1bcb34caaa3 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Tue, 17 Jun 2014 17:16:14 +0100
Subject: [PATCH] LDAP: tokengroups do not work with id_provider=ldap

With plain LDAP provider we already have a sdap_handle, so it should be possible
that in the case where sdom->pvt == NULL sdap_id_op_connect_send() can be
skipped and sdap_get_ad_tokengroups_send() can be already send with the
sdap_handle passed to sdap_ad_tokengroups_initgr_mapping_send(). So we should
only fail if sdom->pvt == NULL and sh == NULL.

if find_subdomain_by_sid() failed we can check if there is only one domain in
the domain list (state->domain) and in this case continue with this domain since
the LDAP provider does not know about sub-domains and hence can only have one
configured domain.

Resolves:
https://fedorahosted.org/sssd/ticket/2345
---
 src/providers/ldap/sdap_async_initgroups_ad.c | 68 +++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index 80e4f29ad8556944c42669350339f62cfb28b36e..9908dd45eceae8c4479efaf11843d1d5bff6e83d 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -733,10 +733,28 @@ sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
 
     sdom = sdap_domain_get(opts, domain);
     if (sdom == NULL || sdom->pvt == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
-                                    domain->name);
-        ret = EINVAL;
-        goto immediately;
+        if (sh != NULL) {
+            /*  plain LDAP provider already has a sdap_handle */
+            subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
+                                                  sh,
+                                                  state->username,
+                                                  state->orig_dn, state->timeout);
+            if (subreq == NULL) {
+                tevent_req_error(req, ENOMEM);
+                ret = ENOMEM;
+                goto immediately;
+            }
+
+            tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done,
+                                    req);
+            return req;
+
+        } else {
+            DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
+                  domain->name);
+            ret = EINVAL;
+            goto immediately;
+        }
     }
     subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
     state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
@@ -875,7 +893,13 @@ static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq)
         domain = find_subdomain_by_sid(get_domains_head(state->domain), sid);
         if (domain == NULL) {
             DEBUG(SSSDBG_MINOR_FAILURE, "Domain not found for SID %s\n", sid);
-            continue;
+            if (state->domain->parent == NULL &&
+                state->domain->subdomains == NULL) {
+                domain = state->domain;
+                DEBUG(SSSDBG_TRACE_FUNC, "Using domain %s\n", domain->name);
+            } else {
+                continue;
+            }
         }
 
         DEBUG(SSSDBG_TRACE_LIBS, "SID [%s] maps to GID [%"SPRIgid"]\n",
@@ -1028,10 +1052,28 @@ sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
 
     sdom = sdap_domain_get(opts, domain);
     if (sdom == NULL || sdom->pvt == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
-                                    domain->name);
-        ret = EINVAL;
-        goto immediately;
+        if (sh != NULL) {
+            /*  plain LDAP provider already has a sdap_handle */
+            subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
+                                                  sh,
+                                                  state->username, state->orig_dn,
+                                                  state->timeout);
+            if (subreq == NULL) {
+                tevent_req_error(req, ENOMEM);
+                ret = ENOMEM;
+                goto immediately;
+            }
+
+            tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_tg_done,
+                                    req);
+            return req;
+
+        } else {
+            DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
+                  domain->name);
+            ret = EINVAL;
+            goto immediately;
+        }
     }
     subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
     state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
@@ -1164,7 +1206,13 @@ sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
         domain = find_subdomain_by_sid(get_domains_head(state->domain), sid);
         if (domain == NULL) {
             DEBUG(SSSDBG_MINOR_FAILURE, "Domain not found for SID %s\n", sid);
-            continue;
+            if (state->domain->parent == NULL &&
+                state->domain->subdomains == NULL) {
+                domain = state->domain;
+                DEBUG(SSSDBG_TRACE_FUNC, "Using domain %s\n", domain->name);
+            } else {
+                continue;
+            }
         }
 
         ret = sysdb_search_group_by_sid_str(tmp_ctx, domain, sid, attrs, &msg);
-- 
1.8.4.2

