Blame SOURCES/0025-ad-use-tokengroups-even-when-id-mapping-is-disabled.patch

2fc102
From 6385798f807d370fe6685653e337f65bf59f21bc Mon Sep 17 00:00:00 2001
2fc102
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
2fc102
Date: Tue, 12 Nov 2013 13:51:34 +0100
2fc102
Subject: [PATCH 25/31] ad: use tokengroups even when id mapping is disabled
2fc102
2fc102
https://fedorahosted.org/sssd/ticket/1568
2fc102
---
2fc102
 src/providers/ldap/sdap_async.h               |   4 +-
2fc102
 src/providers/ldap/sdap_async_initgroups.c    |  10 +-
2fc102
 src/providers/ldap/sdap_async_initgroups_ad.c | 537 +++++++++++++++++++++++++-
2fc102
 3 files changed, 525 insertions(+), 26 deletions(-)
2fc102
2fc102
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
2fc102
index 67623454e675f648259c089acca59258f386ecdb..f47437553a2d35dac90d86209848e840a237c3fb 100644
2fc102
--- a/src/providers/ldap/sdap_async.h
2fc102
+++ b/src/providers/ldap/sdap_async.h
2fc102
@@ -296,13 +296,15 @@ sdap_get_ad_match_rule_initgroups_recv(struct tevent_req *req);
2fc102
 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_options *opts,
2fc102
                                     struct sysdb_ctx *sysdb,
2fc102
                                     struct sss_domain_info *domain,
2fc102
                                     struct sdap_handle *sh,
2fc102
                                     const char *name,
2fc102
                                     const char *orig_dn,
2fc102
-                                    int timeout);
2fc102
+                                    int timeout,
2fc102
+                                    bool use_id_mapping);
2fc102
 
2fc102
 errno_t
2fc102
 sdap_ad_tokengroups_initgroups_recv(struct tevent_req *req);
2fc102
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
2fc102
index 7d5cd2e7cbd86e2eb9774dfee1b8e31edec57b88..1b865af0a113222b3c9c11e9401718abad577fd7 100644
2fc102
--- a/src/providers/ldap/sdap_async_initgroups.c
2fc102
+++ b/src/providers/ldap/sdap_async_initgroups.c
2fc102
@@ -2852,18 +2852,19 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
2fc102
             return;
2fc102
         }
2fc102
 
2fc102
-        if (state->use_id_mapping
2fc102
-                && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
2fc102
+        if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
2fc102
             /* Take advantage of AD's tokenGroups mechanism to look up all
2fc102
              * parent groups in a single request.
2fc102
              */
2fc102
             subreq = sdap_ad_tokengroups_initgroups_send(state, state->ev,
2fc102
+                                                         state->id_ctx,
2fc102
                                                          state->opts,
2fc102
                                                          state->sysdb,
2fc102
                                                          state->dom,
2fc102
                                                          state->sh,
2fc102
                                                          cname, orig_dn,
2fc102
-                                                         state->timeout);
2fc102
+                                                         state->timeout,
2fc102
+                                                         state->use_id_mapping);
2fc102
         } else if (state->opts->support_matching_rule
2fc102
                     && dp_opt_get_bool(state->opts->basic,
2fc102
                                        SDAP_AD_MATCHING_RULE_INITGROUPS)) {
2fc102
@@ -2950,8 +2951,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
2fc102
 
2fc102
     case SDAP_SCHEMA_RFC2307BIS:
2fc102
     case SDAP_SCHEMA_AD:
2fc102
-        if (state->use_id_mapping
2fc102
-                && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
2fc102
+        if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
2fc102
             ret = sdap_ad_tokengroups_initgroups_recv(subreq);
2fc102
         }
2fc102
         else if (state->opts->support_matching_rule
2fc102
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
index 7ba155338a358681c1bd201bee1c75f67afb4650..8e0506831cb189415b62efaa378d3dc7ec350cde 100644
2fc102
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
@@ -525,33 +525,180 @@ done:
2fc102
     return ret;
2fc102
 }
2fc102
 
2fc102
-struct sdap_ad_tokengroups_initgroups_state {
2fc102
+struct sdap_ad_resolve_sids_state {
2fc102
+    struct tevent_context *ev;
2fc102
+    struct sdap_id_ctx *id_ctx;
2fc102
+    struct sdap_options *opts;
2fc102
+    struct sss_domain_info *domain;
2fc102
+    char **sids;
2fc102
+
2fc102
+    const char *current_sid;
2fc102
+    int index;
2fc102
+};
2fc102
+
2fc102
+static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req);
2fc102
+static void sdap_ad_resolve_sids_done(struct tevent_req *subreq);
2fc102
+
2fc102
+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_options *opts,
2fc102
+                          struct sss_domain_info *domain,
2fc102
+                          char **sids)
2fc102
+{
2fc102
+    struct sdap_ad_resolve_sids_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_create(mem_ctx, &state,
2fc102
+                            struct sdap_ad_resolve_sids_state);
2fc102
+    if (req == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    state->ev = ev;
2fc102
+    state->id_ctx = id_ctx;
2fc102
+    state->opts = opts;
2fc102
+    state->domain = get_domains_head(domain);
2fc102
+    state->sids = sids;
2fc102
+    state->index = 0;
2fc102
+
2fc102
+    if (state->sids == NULL) {
2fc102
+        ret = EOK;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+
2fc102
+    ret = sdap_ad_resolve_sids_step(req);
2fc102
+    if (ret != EAGAIN) {
2fc102
+        goto immediately;
2fc102
+    }
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 errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
2fc102
+{
2fc102
+    struct sdap_ad_resolve_sids_state *state = NULL;
2fc102
+    struct tevent_req *subreq = NULL;
2fc102
+    struct sdap_domain *sdap_domain = NULL;
2fc102
+    struct sss_domain_info *domain = NULL;
2fc102
+
2fc102
+    state = tevent_req_data(req, struct sdap_ad_resolve_sids_state);
2fc102
+
2fc102
+    do {
2fc102
+        state->current_sid = state->sids[state->index];
2fc102
+        if (state->current_sid == NULL) {
2fc102
+            return EOK;
2fc102
+        }
2fc102
+        state->index++;
2fc102
+
2fc102
+        domain = find_subdomain_by_sid(state->domain, state->current_sid);
2fc102
+        if (domain == NULL) {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE, ("SID %s does not belong to any known "
2fc102
+                                         "domain\n", state->current_sid));
2fc102
+        }
2fc102
+    } while (domain == NULL);
2fc102
+
2fc102
+    sdap_domain = sdap_domain_get(state->opts, domain);
2fc102
+    if (sdap_domain == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("SDAP domain does not exist?\n"));
2fc102
+        return ERR_INTERNAL;
2fc102
+    }
2fc102
+
2fc102
+    subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
2fc102
+                             state->id_ctx->conn, state->current_sid,
2fc102
+                             BE_FILTER_SECID, BE_ATTR_CORE, false);
2fc102
+    if (subreq == NULL) {
2fc102
+        return ENOMEM;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_set_callback(subreq, sdap_ad_resolve_sids_done, req);
2fc102
+
2fc102
+    return EAGAIN;
2fc102
+}
2fc102
+
2fc102
+static void sdap_ad_resolve_sids_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct sdap_ad_resolve_sids_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    int dp_error;
2fc102
+    int sdap_error;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+    state = tevent_req_data(req, struct sdap_ad_resolve_sids_state);
2fc102
+
2fc102
+    ret = groups_get_recv(subreq, &dp_error, &sdap_error);
2fc102
+    talloc_zfree(subreq);
2fc102
+    if (ret != EOK || sdap_error != EOK || dp_error != DP_ERR_OK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to resolve SID %s [dp_error: %d, "
2fc102
+              "sdap_error: %d, ret: %d]: %s\n", state->current_sid, dp_error,
2fc102
+              sdap_error, ret, strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = sdap_ad_resolve_sids_step(req);
2fc102
+    if (ret == EAGAIN) {
2fc102
+        /* continue with next SID */
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+done:
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_done(req);
2fc102
+}
2fc102
+
2fc102
+static errno_t sdap_ad_resolve_sids_recv(struct tevent_req *req)
2fc102
+{
2fc102
+    TEVENT_REQ_RETURN_ON_ERROR(req);
2fc102
+
2fc102
+    return EOK;
2fc102
+}
2fc102
+
2fc102
+
2fc102
+struct sdap_ad_tokengroups_initgr_mapping_state {
2fc102
     struct sdap_idmap_ctx *idmap_ctx;
2fc102
     struct sysdb_ctx *sysdb;
2fc102
     struct sss_domain_info *domain;
2fc102
     const char *username;
2fc102
 };
2fc102
 
2fc102
-static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq);
2fc102
+static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq);
2fc102
 
2fc102
-struct tevent_req *
2fc102
-sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
-                                    struct tevent_context *ev,
2fc102
-                                    struct sdap_options *opts,
2fc102
-                                    struct sysdb_ctx *sysdb,
2fc102
-                                    struct sss_domain_info *domain,
2fc102
-                                    struct sdap_handle *sh,
2fc102
-                                    const char *name,
2fc102
-                                    const char *orig_dn,
2fc102
-                                    int timeout)
2fc102
+static struct tevent_req *
2fc102
+sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
2fc102
+                                        struct tevent_context *ev,
2fc102
+                                        struct sdap_options *opts,
2fc102
+                                        struct sysdb_ctx *sysdb,
2fc102
+                                        struct sss_domain_info *domain,
2fc102
+                                        struct sdap_handle *sh,
2fc102
+                                        const char *name,
2fc102
+                                        const char *orig_dn,
2fc102
+                                        int timeout)
2fc102
 {
2fc102
-    struct sdap_ad_tokengroups_initgroups_state *state = NULL;
2fc102
+    struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
2fc102
     struct tevent_req *req = NULL;
2fc102
     struct tevent_req *subreq = NULL;
2fc102
     errno_t ret;
2fc102
 
2fc102
     req = tevent_req_create(mem_ctx, &state,
2fc102
-                            struct sdap_ad_tokengroups_initgroups_state);
2fc102
+                            struct sdap_ad_tokengroups_initgr_mapping_state);
2fc102
     if (req == NULL) {
2fc102
         DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
2fc102
         return NULL;
2fc102
@@ -573,7 +720,8 @@ sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
         goto immediately;
2fc102
     }
2fc102
 
2fc102
-    tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgroups_done, req);
2fc102
+    tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done,
2fc102
+                            req);
2fc102
 
2fc102
     return req;
2fc102
 
2fc102
@@ -588,10 +736,10 @@ immediately:
2fc102
     return req;
2fc102
 }
2fc102
 
2fc102
-static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
2fc102
+static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq)
2fc102
 {
2fc102
     TALLOC_CTX *tmp_ctx = NULL;
2fc102
-    struct sdap_ad_tokengroups_initgroups_state *state = NULL;
2fc102
+    struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
2fc102
     struct tevent_req *req = NULL;
2fc102
     struct sss_domain_info *domain = NULL;
2fc102
     struct ldb_message *msg = NULL;
2fc102
@@ -599,14 +747,14 @@ static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
2fc102
     const char *name = NULL;
2fc102
     const char *sid = NULL;
2fc102
     char **sids = NULL;
2fc102
-    size_t num_sids;
2fc102
+    size_t num_sids = 0;
2fc102
     size_t i;
2fc102
     time_t now;
2fc102
     gid_t gid;
2fc102
     char **groups = NULL;
2fc102
     size_t num_groups;
2fc102
     errno_t ret, sret;
2fc102
-    bool in_transaction;
2fc102
+    bool in_transaction = false;
2fc102
 
2fc102
     tmp_ctx = talloc_new(NULL);
2fc102
     if (tmp_ctx == NULL) {
2fc102
@@ -616,7 +764,7 @@ static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
2fc102
     }
2fc102
 
2fc102
     req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
-    state = tevent_req_data(req, struct sdap_ad_tokengroups_initgroups_state);
2fc102
+    state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_mapping_state);
2fc102
 
2fc102
     ret = sdap_get_ad_tokengroups_recv(state, subreq, &num_sids, &sids);
2fc102
     talloc_zfree(subreq);
2fc102
@@ -738,6 +886,355 @@ done:
2fc102
     tevent_req_done(req);
2fc102
 }
2fc102
 
2fc102
+static int sdap_ad_tokengroups_initgr_mapping_recv(struct tevent_req *req)
2fc102
+{
2fc102
+    TEVENT_REQ_RETURN_ON_ERROR(req);
2fc102
+
2fc102
+    return EOK;
2fc102
+}
2fc102
+
2fc102
+struct sdap_ad_tokengroups_initgr_posix_state {
2fc102
+    struct tevent_context *ev;
2fc102
+    struct sdap_id_ctx *id_ctx;
2fc102
+    struct sdap_options *opts;
2fc102
+    struct sysdb_ctx *sysdb;
2fc102
+    struct sss_domain_info *domain;
2fc102
+    const char *username;
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_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_options *opts,
2fc102
+                                      struct sysdb_ctx *sysdb,
2fc102
+                                      struct sss_domain_info *domain,
2fc102
+                                      struct sdap_handle *sh,
2fc102
+                                      const char *name,
2fc102
+                                      const char *orig_dn,
2fc102
+                                      int timeout)
2fc102
+{
2fc102
+    struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    struct tevent_req *subreq = NULL;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_create(mem_ctx, &state,
2fc102
+                            struct sdap_ad_tokengroups_initgr_posix_state);
2fc102
+    if (req == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    state->ev = ev;
2fc102
+    state->id_ctx = id_ctx;
2fc102
+    state->opts = opts;
2fc102
+    state->sysdb = sysdb;
2fc102
+    state->domain = domain;
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
+    if (subreq == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto immediately;
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
+}
2fc102
+
2fc102
+static void
2fc102
+sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    TALLOC_CTX *tmp_ctx = NULL;
2fc102
+    struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    struct sss_domain_info *domain = NULL;
2fc102
+    struct ldb_message *msg = NULL;
2fc102
+    const char *attrs[] = {SYSDB_NAME, SYSDB_POSIX, NULL};
2fc102
+    const char *is_posix = NULL;
2fc102
+    const char *name = NULL;
2fc102
+    char *sid = NULL;
2fc102
+    char **sids = NULL;
2fc102
+    size_t num_sids = 0;
2fc102
+    char **valid_groups = NULL;
2fc102
+    size_t num_valid_groups;
2fc102
+    char **missing_sids = NULL;
2fc102
+    size_t num_missing_sids;
2fc102
+    size_t i;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    tmp_ctx = talloc_new(NULL);
2fc102
+    if (tmp_ctx == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
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
+    ret = sdap_get_ad_tokengroups_recv(state, subreq, &num_sids, &sids);
2fc102
+    talloc_zfree(subreq);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to acquire tokengroups [%d]: %s\n",
2fc102
+                                    ret, strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    num_valid_groups = 0;
2fc102
+    valid_groups = talloc_zero_array(tmp_ctx, char*, num_sids + 1);
2fc102
+    if (valid_groups == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    num_missing_sids = 0;
2fc102
+    missing_sids = talloc_zero_array(tmp_ctx, char*, num_sids + 1);
2fc102
+    if (missing_sids == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    /* For each SID check if it is already present in the cache. If yes, we
2fc102
+     * will get name of the group and update the membership. Otherwise we need
2fc102
+     * to remember the SID and download missing groups one by one. */
2fc102
+    for (i = 0; i < num_sids; i++) {
2fc102
+        sid = sids[i];
2fc102
+        DEBUG(SSSDBG_TRACE_LIBS, ("Processing membership SID [%s]\n", sid));
2fc102
+
2fc102
+        domain = find_subdomain_by_sid(get_domains_head(state->domain), sid);
2fc102
+        if (domain == NULL) {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Domain not found for SID %s\n", sid));
2fc102
+            continue;
2fc102
+        }
2fc102
+
2fc102
+        ret = sysdb_search_group_by_sid_str(tmp_ctx, domain->sysdb, domain,
2fc102
+                                            sid, attrs, &msg;;
2fc102
+        if (ret == EOK) {
2fc102
+            is_posix = ldb_msg_find_attr_as_string(msg, SYSDB_POSIX, NULL);
2fc102
+            if (is_posix != NULL && strcmp(is_posix, "FALSE") == 0) {
2fc102
+                /* skip non-posix group */
2fc102
+                continue;
2fc102
+            }
2fc102
+
2fc102
+            /* we will update membership of this group */
2fc102
+            name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
2fc102
+            if (name == NULL) {
2fc102
+                DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                      ("Could not retrieve group name from sysdb\n"));
2fc102
+                ret = EINVAL;
2fc102
+                goto done;
2fc102
+            }
2fc102
+
2fc102
+            valid_groups[num_valid_groups] = sysdb_group_strdn(tmp_ctx,
2fc102
+                                                               domain->name,
2fc102
+                                                               name);
2fc102
+            if (valid_groups[num_valid_groups] == NULL) {
2fc102
+                ret = ENOMEM;
2fc102
+                goto done;
2fc102
+            }
2fc102
+            num_valid_groups++;
2fc102
+        } else if (ret == ENOENT) {
2fc102
+            /* we need to download this group */
2fc102
+            missing_sids[num_missing_sids] = talloc_steal(missing_sids, sid);
2fc102
+            num_missing_sids++;
2fc102
+
2fc102
+            DEBUG(SSSDBG_TRACE_FUNC, ("Missing SID %s will be downloaded\n",
2fc102
+                                      sid));
2fc102
+        } else {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not look up group in sysdb: "
2fc102
+                                         "[%s]\n", strerror(ret)));
2fc102
+            goto done;
2fc102
+        }
2fc102
+    }
2fc102
+
2fc102
+    valid_groups[num_valid_groups] = NULL;
2fc102
+    missing_sids[num_missing_sids] = NULL;
2fc102
+
2fc102
+    /* update membership of existing groups */
2fc102
+    ret = sdap_ad_tokengroups_update_members(state, state->username,
2fc102
+                                             state->sysdb, state->domain,
2fc102
+                                             valid_groups);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_MINOR_FAILURE, ("Membership update failed [%d]: %s\n",
2fc102
+                                     ret, strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
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->opts, state->domain,
2fc102
+                                       missing_sids);
2fc102
+    if (subreq == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_sids_done,
2fc102
+                            req);
2fc102
+
2fc102
+    return;
2fc102
+
2fc102
+done:
2fc102
+    talloc_free(tmp_ctx);
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_done(req);
2fc102
+}
2fc102
+
2fc102
+static void
2fc102
+sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+
2fc102
+    ret = sdap_ad_resolve_sids_recv(subreq);
2fc102
+    talloc_zfree(subreq);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to resolve missing SIDs "
2fc102
+                                    "[%d]: %s\n", ret, strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+done:
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_done(req);
2fc102
+}
2fc102
+
2fc102
+static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req)
2fc102
+{
2fc102
+    TEVENT_REQ_RETURN_ON_ERROR(req);
2fc102
+
2fc102
+    return EOK;
2fc102
+}
2fc102
+
2fc102
+struct sdap_ad_tokengroups_initgroups_state {
2fc102
+    bool use_id_mapping;
2fc102
+};
2fc102
+
2fc102
+static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq);
2fc102
+
2fc102
+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_options *opts,
2fc102
+                                    struct sysdb_ctx *sysdb,
2fc102
+                                    struct sss_domain_info *domain,
2fc102
+                                    struct sdap_handle *sh,
2fc102
+                                    const char *name,
2fc102
+                                    const char *orig_dn,
2fc102
+                                    int timeout,
2fc102
+                                    bool use_id_mapping)
2fc102
+{
2fc102
+    struct sdap_ad_tokengroups_initgroups_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    struct tevent_req *subreq = NULL;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_create(mem_ctx, &state,
2fc102
+                            struct sdap_ad_tokengroups_initgroups_state);
2fc102
+    if (req == NULL) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    state->use_id_mapping = use_id_mapping;
2fc102
+
2fc102
+    if (state->use_id_mapping) {
2fc102
+        subreq = sdap_ad_tokengroups_initgr_mapping_send(state, ev, opts,
2fc102
+                                                         sysdb, domain, sh,
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
+                                                       name, orig_dn,
2fc102
+                                                       timeout);
2fc102
+    }
2fc102
+    if (subreq == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto immediately;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgroups_done, 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 sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
2fc102
+{
2fc102
+    struct sdap_ad_tokengroups_initgroups_state *state = NULL;
2fc102
+    struct tevent_req *req = NULL;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
+    state = tevent_req_data(req, struct sdap_ad_tokengroups_initgroups_state);
2fc102
+
2fc102
+    if (state->use_id_mapping) {
2fc102
+        ret = sdap_ad_tokengroups_initgr_mapping_recv(subreq);
2fc102
+    } else {
2fc102
+        ret = sdap_ad_tokengroups_initgr_posix_recv(subreq);
2fc102
+    }
2fc102
+    talloc_zfree(subreq);
2fc102
+    if (ret != EOK) {
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+done:
2fc102
+    if (ret != EOK) {
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_done(req);
2fc102
+}
2fc102
+
2fc102
 errno_t sdap_ad_tokengroups_initgroups_recv(struct tevent_req *req)
2fc102
 {
2fc102
     TEVENT_REQ_RETURN_ON_ERROR(req);
2fc102
-- 
2fc102
1.8.4.2
2fc102