Blame SOURCES/0027-AD-cross-domain-membership-fix.patch

2fc102
From 402af69c0bb7ea8b84e36f3567de6086042cb152 Mon Sep 17 00:00:00 2001
2fc102
From: Sumit Bose <sbose@redhat.com>
2fc102
Date: Wed, 18 Dec 2013 13:47:31 +0100
2fc102
Subject: [PATCH 27/31] AD: cross-domain membership fix
2fc102
2fc102
A recent patch directed all call related to group membership lookups to
2fc102
the AD LDAP port to fix an issue related to missing group memberships in
2fc102
the Global Catalog. As a side-effect it broke cross-domain
2fc102
group-memberships because those cannot be resolved by the connection to
2fc102
the LDAP port.
2fc102
2fc102
The patch tires to fix this by restoring the original behaviour in the
2fc102
top-level lookup calls in the AD provider and switching to the LDAP port
2fc102
only for the LDAP request which is expected to return the full group
2fc102
membership.
2fc102
2fc102
Additionally this patch contains a related fix for the tokenGroups with
2fc102
Posix attributes patch. The original connection, typically a Global
2fc102
Catalog connection in the AD case is passed down the stack so that the
2fc102
group lookup after the tokenGroups request can run over the same
2fc102
connection.
2fc102
---
2fc102
 src/providers/ad/ad_id.c                      |  19 +--
2fc102
 src/providers/ad/ad_init.c                    |   2 +
2fc102
 src/providers/ldap/sdap_async.h               |   1 +
2fc102
 src/providers/ldap/sdap_async_groups.c        |  62 +++++++-
2fc102
 src/providers/ldap/sdap_async_initgroups.c    |  50 ++++++-
2fc102
 src/providers/ldap/sdap_async_initgroups_ad.c | 197 ++++++++++++++++++++++----
2fc102
 6 files changed, 281 insertions(+), 50 deletions(-)
2fc102
2fc102
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
2fc102
index 19bc65825be21c6419db1e92db642be0a14b97a8..cf71b172dd7c241a9280a7ea72ef2518f66a7435 100644
2fc102
--- a/src/providers/ad/ad_id.c
2fc102
+++ b/src/providers/ad/ad_id.c
2fc102
@@ -199,6 +199,8 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
2fc102
     case BE_REQ_USER: /* user */
2fc102
     case BE_REQ_BY_SECID:   /* by SID */
2fc102
     case BE_REQ_USER_AND_GROUP: /* get SID */
2fc102
+    case BE_REQ_GROUP: /* group */
2fc102
+    case BE_REQ_INITGROUPS: /* init groups for user */
2fc102
         /* Always try GC first */
2fc102
         clist[0] = ad_ctx->gc_ctx;
2fc102
         if (IS_SUBDOMAIN(dom) == true) {
2fc102
@@ -215,23 +217,6 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
2fc102
          */
2fc102
         clist[1] = ad_ctx->ldap_ctx;
2fc102
         break;
2fc102
-
2fc102
-    case BE_REQ_GROUP: /* group */
2fc102
-    case BE_REQ_INITGROUPS: /* init groups for user */
2fc102
-        if (IS_SUBDOMAIN(dom)) {
2fc102
-            sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom);
2fc102
-            if (sdom == NULL || sdom->pvt == NULL) {
2fc102
-                DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
2fc102
-                                            dom->name));
2fc102
-                return NULL;
2fc102
-            }
2fc102
-            subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
2fc102
-            clist[0] = subdom_id_ctx->ldap_ctx;
2fc102
-        } else {
2fc102
-            clist[0] = ad_ctx->ldap_ctx;
2fc102
-        }
2fc102
-        break;
2fc102
-
2fc102
     default:
2fc102
         clist[0] = ad_ctx->ldap_ctx;
2fc102
         break;
2fc102
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
2fc102
index d06efbd082bd6bba74fb6616c7dd722c99244988..332bfda3801db3824ce1896d37e65e2c3a6b8b8b 100644
2fc102
--- a/src/providers/ad/ad_init.c
2fc102
+++ b/src/providers/ad/ad_init.c
2fc102
@@ -214,6 +214,8 @@ sssm_ad_id_init(struct be_ctx *bectx,
2fc102
         goto done;
2fc102
     }
2fc102
 
2fc102
+    ad_ctx->sdap_id_ctx->opts->sdom->pvt = ad_ctx;
2fc102
+
2fc102
     /* Set up the ID mapping object */
2fc102
     ret = sdap_idmap_init(ad_ctx->sdap_id_ctx, ad_ctx->sdap_id_ctx,
2fc102
                           &ad_ctx->sdap_id_ctx->opts->idmap_ctx);
2fc102
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
2fc102
index f47437553a2d35dac90d86209848e840a237c3fb..33e8708ab7e80ab4280df300fdc300d4ecd18305 100644
2fc102
--- a/src/providers/ldap/sdap_async.h
2fc102
+++ b/src/providers/ldap/sdap_async.h
2fc102
@@ -297,6 +297,7 @@ struct tevent_req *
2fc102
 sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
                                     struct tevent_context *ev,
2fc102
                                     struct sdap_id_ctx *id_ctx,
2fc102
+                                    struct sdap_id_conn_ctx *conn,
2fc102
                                     struct sdap_options *opts,
2fc102
                                     struct sysdb_ctx *sysdb,
2fc102
                                     struct sss_domain_info *domain,
2fc102
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
2fc102
index 33648c5da367c908d085a71a9a9017cb294bb300..9eece9a6e4baaf302a28b57a63dae45a0741136c 100644
2fc102
--- a/src/providers/ldap/sdap_async_groups.c
2fc102
+++ b/src/providers/ldap/sdap_async_groups.c
2fc102
@@ -26,6 +26,7 @@
2fc102
 #include "providers/ldap/sdap_async_private.h"
2fc102
 #include "providers/ldap/ldap_common.h"
2fc102
 #include "providers/ldap/sdap_idmap.h"
2fc102
+#include "providers/ad/ad_common.h"
2fc102
 
2fc102
 /* ==Group-Parsing Routines=============================================== */
2fc102
 
2fc102
@@ -1540,9 +1541,13 @@ struct sdap_get_groups_state {
2fc102
 
2fc102
     size_t base_iter;
2fc102
     struct sdap_search_base **search_bases;
2fc102
+
2fc102
+    struct sdap_handle *ldap_sh;
2fc102
+    struct sdap_id_op *op;
2fc102
 };
2fc102
 
2fc102
 static errno_t sdap_get_groups_next_base(struct tevent_req *req);
2fc102
+static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq);
2fc102
 static void sdap_get_groups_process(struct tevent_req *subreq);
2fc102
 static void sdap_get_groups_done(struct tevent_req *subreq);
2fc102
 
2fc102
@@ -1558,7 +1563,9 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
2fc102
 {
2fc102
     errno_t ret;
2fc102
     struct tevent_req *req;
2fc102
+    struct tevent_req *subreq;
2fc102
     struct sdap_get_groups_state *state;
2fc102
+    struct ad_id_ctx *subdom_id_ctx;
2fc102
 
2fc102
     req = tevent_req_create(memctx, &state, struct sdap_get_groups_state);
2fc102
     if (!req) return NULL;
2fc102
@@ -1586,6 +1593,30 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
2fc102
         goto done;
2fc102
     }
2fc102
 
2fc102
+    /* With AD by default the Global Catalog is used for lookup. But the GC
2fc102
+     * group object might not have full group membership data. To make sure we
2fc102
+     * connect to an LDAP server of the group's domain. */
2fc102
+    if (state->opts->schema_type == SDAP_SCHEMA_AD && sdom->pvt != NULL) {
2fc102
+        subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
2fc102
+        state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
2fc102
+        if (!state->op) {
2fc102
+            DEBUG(2, ("sdap_id_op_create failed\n"));
2fc102
+            ret = ENOMEM;
2fc102
+            goto done;
2fc102
+        }
2fc102
+
2fc102
+        subreq = sdap_id_op_connect_send(state->op, state, &ret;;
2fc102
+        if (subreq == NULL) {
2fc102
+            ret = ENOMEM;
2fc102
+            goto done;
2fc102
+        }
2fc102
+
2fc102
+        tevent_req_set_callback(subreq,
2fc102
+                                sdap_get_groups_ldap_connect_done,
2fc102
+                                req);
2fc102
+        return req;
2fc102
+    }
2fc102
+
2fc102
     ret = sdap_get_groups_next_base(req);
2fc102
 
2fc102
 done:
2fc102
@@ -1597,6 +1628,34 @@ done:
2fc102
     return req;
2fc102
 }
2fc102
 
2fc102
+static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct tevent_req *req;
2fc102
+    struct sdap_get_groups_state *state;
2fc102
+    int ret;
2fc102
+    int dp_error;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+    state = tevent_req_data(req, struct sdap_get_groups_state);
2fc102
+
2fc102
+    ret = sdap_id_op_connect_recv(subreq, &dp_error);
2fc102
+    talloc_zfree(subreq);
2fc102
+
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    state->ldap_sh = sdap_id_op_handle(state->op);
2fc102
+
2fc102
+    ret = sdap_get_groups_next_base(req);
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+    }
2fc102
+
2fc102
+    return;
2fc102
+}
2fc102
+
2fc102
 static errno_t sdap_get_groups_next_base(struct tevent_req *req)
2fc102
 {
2fc102
     struct tevent_req *subreq;
2fc102
@@ -1617,7 +1676,8 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
2fc102
            state->search_bases[state->base_iter]->basedn));
2fc102
 
2fc102
     subreq = sdap_get_generic_send(
2fc102
-            state, state->ev, state->opts, state->sh,
2fc102
+            state, state->ev, state->opts,
2fc102
+            state->ldap_sh != NULL ? state->ldap_sh : state->sh,
2fc102
             state->search_bases[state->base_iter]->basedn,
2fc102
             state->search_bases[state->base_iter]->scope,
2fc102
             state->filter, state->attrs,
2fc102
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
2fc102
index 1b865af0a113222b3c9c11e9401718abad577fd7..aba7ba42dade8923ae91f5bc8962e03d038c15a1 100644
2fc102
--- a/src/providers/ldap/sdap_async_initgroups.c
2fc102
+++ b/src/providers/ldap/sdap_async_initgroups.c
2fc102
@@ -2749,6 +2749,10 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
2fc102
     const char *orig_dn;
2fc102
     const char *cname;
2fc102
     bool in_transaction = false;
2fc102
+    char *expected_basedn;
2fc102
+    size_t expected_basedn_len;
2fc102
+    size_t dn_len;
2fc102
+    size_t c = 0;
2fc102
 
2fc102
     DEBUG(9, ("Receiving info for the user\n"));
2fc102
 
2fc102
@@ -2788,11 +2792,50 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
2fc102
     } else if (count != 1) {
2fc102
         DEBUG(SSSDBG_OP_FAILURE,
2fc102
               ("Expected one user entry and got %zu\n", count));
2fc102
-        tevent_req_error(req, EINVAL);
2fc102
-        return;
2fc102
+
2fc102
+        ret = domain_to_basedn(state, state->dom->name, &expected_basedn);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("domain_to_basedn failed.\n"));
2fc102
+            tevent_req_error(req, ret);
2fc102
+            return;
2fc102
+        }
2fc102
+        expected_basedn = talloc_asprintf(state, "%s%s",
2fc102
+                                                 "cn=users,", expected_basedn);
2fc102
+        if (expected_basedn == NULL) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("talloc_append failed.\n"));
2fc102
+            tevent_req_error(req, ENOMEM);
2fc102
+            return;
2fc102
+        }
2fc102
+
2fc102
+        DEBUG(SSSDBG_TRACE_ALL, ("Expected BaseDN is [%s].\n", expected_basedn));
2fc102
+        expected_basedn_len = strlen(expected_basedn);
2fc102
+
2fc102
+        for (c = 0; c < count; c++) {
2fc102
+            ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
+                tevent_req_error(req, ret);
2fc102
+                return;
2fc102
+            }
2fc102
+            dn_len = strlen(orig_dn);
2fc102
+
2fc102
+            if (dn_len > expected_basedn_len
2fc102
+                    && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
2fc102
+                                  expected_basedn) == 0) {
2fc102
+                DEBUG(SSSDBG_TRACE_ALL,
2fc102
+                      ("Found matching dn [%s].\n", orig_dn));
2fc102
+                break;
2fc102
+            }
2fc102
+        }
2fc102
+
2fc102
+        if (c == count) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("No matching DN found.\n"));
2fc102
+            tevent_req_error(req, EINVAL);
2fc102
+            return;
2fc102
+        }
2fc102
     }
2fc102
 
2fc102
-    state->orig_user = usr_attrs[0];
2fc102
+    state->orig_user = usr_attrs[c];
2fc102
 
2fc102
     ret = sysdb_transaction_start(state->sysdb);
2fc102
     if (ret) {
2fc102
@@ -2858,6 +2901,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
2fc102
              */
2fc102
             subreq = sdap_ad_tokengroups_initgroups_send(state, state->ev,
2fc102
                                                          state->id_ctx,
2fc102
+                                                         state->conn,
2fc102
                                                          state->opts,
2fc102
                                                          state->sysdb,
2fc102
                                                          state->dom,
2fc102
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
index f1bf77e8614c30b214118140e380c23c40c1195b..8f8f0a4cc635818dcc7f75f9da603ce2f55c820f 100644
2fc102
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
@@ -25,6 +25,7 @@
2fc102
 #include "providers/ldap/ldap_common.h"
2fc102
 #include "providers/ldap/sdap_async_private.h"
2fc102
 #include "providers/ldap/sdap_idmap.h"
2fc102
+#include "providers/ad/ad_common.h"
2fc102
 #include "lib/idmap/sss_idmap.h"
2fc102
 
2fc102
 struct sdap_ad_match_rule_initgr_state {
2fc102
@@ -528,6 +529,7 @@ done:
2fc102
 struct sdap_ad_resolve_sids_state {
2fc102
     struct tevent_context *ev;
2fc102
     struct sdap_id_ctx *id_ctx;
2fc102
+    struct sdap_id_conn_ctx *conn;
2fc102
     struct sdap_options *opts;
2fc102
     struct sss_domain_info *domain;
2fc102
     char **sids;
2fc102
@@ -543,6 +545,7 @@ static struct tevent_req *
2fc102
 sdap_ad_resolve_sids_send(TALLOC_CTX *mem_ctx,
2fc102
                           struct tevent_context *ev,
2fc102
                           struct sdap_id_ctx *id_ctx,
2fc102
+                          struct sdap_id_conn_ctx *conn,
2fc102
                           struct sdap_options *opts,
2fc102
                           struct sss_domain_info *domain,
2fc102
                           char **sids)
2fc102
@@ -560,6 +563,7 @@ sdap_ad_resolve_sids_send(TALLOC_CTX *mem_ctx,
2fc102
 
2fc102
     state->ev = ev;
2fc102
     state->id_ctx = id_ctx;
2fc102
+    state->conn = conn;
2fc102
     state->opts = opts;
2fc102
     state->domain = get_domains_head(domain);
2fc102
     state->sids = sids;
2fc102
@@ -618,7 +622,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
2fc102
     }
2fc102
 
2fc102
     subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
2fc102
-                             state->id_ctx->conn, state->current_sid,
2fc102
+                             state->conn, state->current_sid,
2fc102
                              BE_FILTER_SECID, BE_ATTR_CORE, false);
2fc102
     if (subreq == NULL) {
2fc102
         return ENOMEM;
2fc102
@@ -673,12 +677,21 @@ static errno_t sdap_ad_resolve_sids_recv(struct tevent_req *req)
2fc102
 
2fc102
 
2fc102
 struct sdap_ad_tokengroups_initgr_mapping_state {
2fc102
+    struct tevent_context *ev;
2fc102
+    struct sdap_options *opts;
2fc102
+    struct sdap_handle *sh;
2fc102
     struct sdap_idmap_ctx *idmap_ctx;
2fc102
     struct sysdb_ctx *sysdb;
2fc102
     struct sss_domain_info *domain;
2fc102
+    const char *orig_dn;
2fc102
+    int timeout;
2fc102
     const char *username;
2fc102
+
2fc102
+    struct sdap_id_op *op;
2fc102
 };
2fc102
 
2fc102
+static void
2fc102
+sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq);
2fc102
 static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq);
2fc102
 
2fc102
 static struct tevent_req *
2fc102
@@ -695,6 +708,8 @@ sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
2fc102
     struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
2fc102
     struct tevent_req *req = NULL;
2fc102
     struct tevent_req *subreq = NULL;
2fc102
+    struct sdap_domain *sdom;
2fc102
+    struct ad_id_ctx *subdom_id_ctx;
2fc102
     errno_t ret;
2fc102
 
2fc102
     req = tevent_req_create(mem_ctx, &state,
2fc102
@@ -704,36 +719,92 @@ sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
2fc102
         return NULL;
2fc102
     }
2fc102
 
2fc102
+    state->ev = ev;
2fc102
+    state->opts = opts;
2fc102
+    state->sh = sh;
2fc102
     state->idmap_ctx = opts->idmap_ctx;
2fc102
     state->sysdb = sysdb;
2fc102
     state->domain = domain;
2fc102
+    state->timeout = timeout;
2fc102
+    state->orig_dn = orig_dn;
2fc102
     state->username = talloc_strdup(state, name);
2fc102
     if (state->username == NULL) {
2fc102
         ret = ENOMEM;
2fc102
         goto immediately;
2fc102
     }
2fc102
 
2fc102
-    subreq = sdap_get_ad_tokengroups_send(state, ev, opts, sh, name, orig_dn,
2fc102
-                                          timeout);
2fc102
+    sdom = sdap_domain_get(opts, domain);
2fc102
+    if (sdom == NULL || sdom->pvt == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
2fc102
+                                    domain->name));
2fc102
+        ret = EINVAL;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+    subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
2fc102
+    state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
2fc102
+    if (!state->op) {
2fc102
+        DEBUG(2, ("sdap_id_op_create failed\n"));
2fc102
+        ret = ENOMEM;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+
2fc102
+    subreq = sdap_id_op_connect_send(state->op, state, &ret;;
2fc102
     if (subreq == NULL) {
2fc102
         ret = ENOMEM;
2fc102
         goto immediately;
2fc102
     }
2fc102
 
2fc102
+    tevent_req_set_callback(subreq,
2fc102
+                            sdap_ad_tokengroups_initgr_mapping_connect_done,
2fc102
+                            req);
2fc102
+
2fc102
+    return req;
2fc102
+
2fc102
+immediately:
2fc102
+    if (ret == EOK) {
2fc102
+        tevent_req_done(req);
2fc102
+    } else {
2fc102
+        tevent_req_error(req, ret);
2fc102
+    }
2fc102
+    tevent_req_post(req, ev);
2fc102
+
2fc102
+    return req;
2fc102
+}
2fc102
+
2fc102
+static void
2fc102
+sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    int ret;
2fc102
+    int dp_error = DP_ERR_FATAL;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+    state = tevent_req_data(req,
2fc102
+                            struct sdap_ad_tokengroups_initgr_mapping_state);
2fc102
+
2fc102
+
2fc102
+    ret = sdap_id_op_connect_recv(subreq, &dp_error);
2fc102
+    talloc_zfree(subreq);
2fc102
+
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
2fc102
+                                          sdap_id_op_handle(state->op),
2fc102
+                                          state->username,
2fc102
+                                          state->orig_dn, state->timeout);
2fc102
+    if (subreq == NULL) {
2fc102
+        tevent_req_error(req, ENOMEM);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
     tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done,
2fc102
                             req);
2fc102
 
2fc102
-    return req;
2fc102
-
2fc102
-immediately:
2fc102
-    if (ret == EOK) {
2fc102
-        tevent_req_done(req);
2fc102
-    } else {
2fc102
-        tevent_req_error(req, ret);
2fc102
-    }
2fc102
-    tevent_req_post(req, ev);
2fc102
-
2fc102
-    return req;
2fc102
+    return;
2fc102
 }
2fc102
 
2fc102
 static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq)
2fc102
@@ -896,22 +967,31 @@ static int sdap_ad_tokengroups_initgr_mapping_recv(struct tevent_req *req)
2fc102
 struct sdap_ad_tokengroups_initgr_posix_state {
2fc102
     struct tevent_context *ev;
2fc102
     struct sdap_id_ctx *id_ctx;
2fc102
+    struct sdap_id_conn_ctx *conn;
2fc102
     struct sdap_options *opts;
2fc102
+    struct sdap_handle *sh;
2fc102
     struct sysdb_ctx *sysdb;
2fc102
     struct sss_domain_info *domain;
2fc102
+    const char *orig_dn;
2fc102
+    int timeout;
2fc102
     const char *username;
2fc102
+
2fc102
+    struct sdap_id_op *op;
2fc102
 };
2fc102
 
2fc102
 static void
2fc102
 sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq);
2fc102
 
2fc102
 static void
2fc102
+sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq);
2fc102
+static void
2fc102
 sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq);
2fc102
 
2fc102
 static struct tevent_req *
2fc102
 sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
2fc102
                                       struct tevent_context *ev,
2fc102
                                       struct sdap_id_ctx *id_ctx,
2fc102
+                                      struct sdap_id_conn_ctx *conn,
2fc102
                                       struct sdap_options *opts,
2fc102
                                       struct sysdb_ctx *sysdb,
2fc102
                                       struct sss_domain_info *domain,
2fc102
@@ -923,6 +1003,8 @@ sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
2fc102
     struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
2fc102
     struct tevent_req *req = NULL;
2fc102
     struct tevent_req *subreq = NULL;
2fc102
+    struct sdap_domain *sdom;
2fc102
+    struct ad_id_ctx *subdom_id_ctx;
2fc102
     errno_t ret;
2fc102
 
2fc102
     req = tevent_req_create(mem_ctx, &state,
2fc102
@@ -934,36 +1016,91 @@ sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
2fc102
 
2fc102
     state->ev = ev;
2fc102
     state->id_ctx = id_ctx;
2fc102
+    state->conn = conn;
2fc102
     state->opts = opts;
2fc102
+    state->sh = sh;
2fc102
     state->sysdb = sysdb;
2fc102
     state->domain = domain;
2fc102
+    state->orig_dn = orig_dn;
2fc102
+    state->timeout = timeout;
2fc102
     state->username = talloc_strdup(state, name);
2fc102
     if (state->username == NULL) {
2fc102
         ret = ENOMEM;
2fc102
         goto immediately;
2fc102
     }
2fc102
 
2fc102
-    subreq = sdap_get_ad_tokengroups_send(state, ev, opts, sh, name, orig_dn,
2fc102
-                                          timeout);
2fc102
+    sdom = sdap_domain_get(opts, domain);
2fc102
+    if (sdom == NULL || sdom->pvt == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
2fc102
+                                    domain->name));
2fc102
+        ret = EINVAL;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+    subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
2fc102
+    state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
2fc102
+    if (!state->op) {
2fc102
+        DEBUG(2, ("sdap_id_op_create failed\n"));
2fc102
+        ret = ENOMEM;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+
2fc102
+    subreq = sdap_id_op_connect_send(state->op, state, &ret;;
2fc102
     if (subreq == NULL) {
2fc102
         ret = ENOMEM;
2fc102
         goto immediately;
2fc102
     }
2fc102
 
2fc102
+    tevent_req_set_callback(subreq,
2fc102
+                            sdap_ad_tokengroups_initgr_posix_sids_connect_done,
2fc102
+                            req);
2fc102
+
2fc102
+    return req;
2fc102
+
2fc102
+immediately:
2fc102
+    if (ret == EOK) {
2fc102
+        tevent_req_done(req);
2fc102
+    } else {
2fc102
+        tevent_req_error(req, ret);
2fc102
+    }
2fc102
+    tevent_req_post(req, ev);
2fc102
+
2fc102
+    return req;
2fc102
+}
2fc102
+
2fc102
+static void
2fc102
+sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    int ret;
2fc102
+    int dp_error = DP_ERR_FATAL;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+    state = tevent_req_data(req,
2fc102
+                            struct sdap_ad_tokengroups_initgr_posix_state);
2fc102
+
2fc102
+
2fc102
+    ret = sdap_id_op_connect_recv(subreq, &dp_error);
2fc102
+    talloc_zfree(subreq);
2fc102
+
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
2fc102
+                                          sdap_id_op_handle(state->op),
2fc102
+                                          state->username, state->orig_dn,
2fc102
+                                          state->timeout);
2fc102
+    if (subreq == NULL) {
2fc102
+        tevent_req_error(req, ENOMEM);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
     tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_tg_done,
2fc102
                             req);
2fc102
 
2fc102
-    return req;
2fc102
-
2fc102
-immediately:
2fc102
-    if (ret == EOK) {
2fc102
-        tevent_req_done(req);
2fc102
-    } else {
2fc102
-        tevent_req_error(req, ret);
2fc102
-    }
2fc102
-    tevent_req_post(req, ev);
2fc102
-
2fc102
-    return req;
2fc102
+    return;
2fc102
 }
2fc102
 
2fc102
 static void
2fc102
@@ -1089,6 +1226,7 @@ sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
2fc102
     /* download missing SIDs */
2fc102
     missing_sids = talloc_steal(state, missing_sids);
2fc102
     subreq = sdap_ad_resolve_sids_send(state, state->ev, state->id_ctx,
2fc102
+                                       state->conn,
2fc102
                                        state->opts, state->domain,
2fc102
                                        missing_sids);
2fc102
     if (subreq == NULL) {
2fc102
@@ -1154,6 +1292,7 @@ struct tevent_req *
2fc102
 sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
                                     struct tevent_context *ev,
2fc102
                                     struct sdap_id_ctx *id_ctx,
2fc102
+                                    struct sdap_id_conn_ctx *conn,
2fc102
                                     struct sdap_options *opts,
2fc102
                                     struct sysdb_ctx *sysdb,
2fc102
                                     struct sss_domain_info *domain,
2fc102
@@ -1184,8 +1323,8 @@ sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
                                                          name, orig_dn,
2fc102
                                                          timeout);
2fc102
     } else {
2fc102
-        subreq = sdap_ad_tokengroups_initgr_posix_send(state, ev, id_ctx, opts,
2fc102
-                                                       sysdb, domain, sh,
2fc102
+        subreq = sdap_ad_tokengroups_initgr_posix_send(state, ev, id_ctx, conn,
2fc102
+                                                       opts, sysdb, domain, sh,
2fc102
                                                        name, orig_dn,
2fc102
                                                        timeout);
2fc102
     }
2fc102
-- 
2fc102
1.8.4.2
2fc102