Hi,

Attached find two patches for issue https://fedorahosted.org/sssd/ticket/1568

[PATCH 1/2]: LDAP: move sdap_get_initgr_state structure to private
 header
- moves the initgr state structure to private header so it can be used also in the ad initgroups module.

[PATCH 2/2] AD: Enable TokenGroups initgroups lookup

This is first implementation of getting TokenGroups lookup working.

If all of the group SIDs that are fetched via the users TokenGroups
attribute are in sysdb, the membership is processed this way. If any of
the groups is missing in the cache, it falls back to rfc2307bis

I'd file a ticket to enhance this to look up only groups which are missing in the sysdb, as we talked about with Jakub.

Ondra
--
Ondrej Kos
Associate Software Engineer
Identity Management - SSSD
Red Hat Czech
From 4047ef63b0bdfff0d6fe505e556aeeae6978b865 Mon Sep 17 00:00:00 2001
From: Ondrej Kos <o...@redhat.com>
Date: Tue, 3 Sep 2013 13:20:41 +0200
Subject: [PATCH 1/2] LDAP: move sdap_get_initgr_state structure to private
 header

---
 src/providers/ldap/sdap_async_initgroups.c | 23 -----------------------
 src/providers/ldap/sdap_async_private.h    | 23 +++++++++++++++++++++++
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index aa0ea4c1b28fa2a69390605d3fff3cfff1642aa1..315834153408ebc8b5e4837ea51b26460dc0469a 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2538,29 +2538,6 @@ static void rfc2307bis_nested_groups_done(struct tevent_req *subreq)
 
 /* ==Initgr-call-(groups-a-user-is-member-of)============================= */
 
-struct sdap_get_initgr_state {
-    struct tevent_context *ev;
-    struct sysdb_ctx *sysdb;
-    struct sdap_options *opts;
-    struct sss_domain_info *dom;
-    struct sdap_handle *sh;
-    struct sdap_id_ctx *id_ctx;
-    struct sdap_id_conn_ctx *conn;
-    const char *name;
-    const char **grp_attrs;
-    const char **user_attrs;
-    const char *user_base_filter;
-    char *filter;
-    int timeout;
-
-    struct sysdb_attrs *orig_user;
-
-    size_t user_base_iter;
-    struct sdap_search_base **user_search_bases;
-
-    bool use_id_mapping;
-};
-
 static errno_t sdap_get_initgr_next_base(struct tevent_req *req);
 static void sdap_get_initgr_user(struct tevent_req *subreq);
 static void sdap_get_initgr_done(struct tevent_req *subreq);
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 944c8a82b217268206a8ede846df92ea4f4dba03..4d0b86529a46ca7da495e44d4d9deaa2dd4e625f 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -35,6 +35,29 @@ struct dn_item {
     struct dn_item *prev;
 };
 
+struct sdap_get_initgr_state {
+    struct tevent_context *ev;
+    struct sysdb_ctx *sysdb;
+    struct sdap_options *opts;
+    struct sss_domain_info *dom;
+    struct sdap_handle *sh;
+    struct sdap_id_ctx *id_ctx;
+    struct sdap_id_conn_ctx *conn;
+    const char *name;
+    const char **grp_attrs;
+    const char **user_attrs;
+    const char *user_base_filter;
+    char *filter;
+    int timeout;
+
+    struct sysdb_attrs *orig_user;
+
+    size_t user_base_iter;
+    struct sdap_search_base **user_search_bases;
+
+    bool use_id_mapping;
+};
+
 bool is_dn(const char *str);
 errno_t update_dn_list(struct dn_item *dn_list,
                        const size_t count,
-- 
1.8.1.4

From e28b760ac18f0c51ee6cdfc65f9c69abfe9bd126 Mon Sep 17 00:00:00 2001
From: Ondrej Kos <o...@redhat.com>
Date: Tue, 3 Sep 2013 12:27:17 +0200
Subject: [PATCH 2/2] AD: Enable TokenGroups initgroups lookup

This is first implementation of getting TokenGroups lookup working.

If all of the group SIDs that are fetched via the users TokenGroups
attribute are in sysdb, the membership is processed this way. If any of
the groups is missing in the cache, it falls back to rfc2307bis
initgroups lookup.

Resolves:
https://fedorahosted.org/sssd/ticket/1568
---
 src/providers/ldap/sdap_async.h               |  1 +
 src/providers/ldap/sdap_async_initgroups.c    | 64 ++++++++++++++++++++----
 src/providers/ldap/sdap_async_initgroups_ad.c | 71 +++++++++++++++++----------
 src/providers/ldap/sdap_async_private.h       |  2 +
 4 files changed, 103 insertions(+), 35 deletions(-)

diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index c8031c9a9d527a6d808f1ddce096de23850ebfd6..432a561237fa70075b9c20609a5d661078d53019 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -279,6 +279,7 @@ sdap_get_ad_match_rule_initgroups_recv(struct tevent_req *req);
 
 struct tevent_req *
 sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
+                                        void *istate,
                                         struct tevent_context *ev,
                                         struct sdap_options *opts,
                                         struct sysdb_ctx *sysdb,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 315834153408ebc8b5e4837ea51b26460dc0469a..163654023c7aa7ea140950452302f03eb0206486 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2571,8 +2571,10 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
     state->name = name;
     state->grp_attrs = grp_attrs;
     state->orig_user = NULL;
+    state->cname = NULL;
     state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
     state->user_base_iter = 0;
+    state->failed_tokengroups = false;
     state->user_search_bases = sdom->user_search_bases;
     if (!state->user_search_bases) {
         DEBUG(SSSDBG_CRIT_FAILURE,
@@ -2745,13 +2747,16 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
         return;
     }
 
+    state->cname = cname;
+    talloc_steal(state, cname);
+
     DEBUG(9, ("Process user's groups\n"));
 
     switch (state->opts->schema_type) {
     case SDAP_SCHEMA_RFC2307:
         subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts,
                                           state->sysdb, state->dom, state->sh,
-                                          cname);
+                                          state->cname);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -2769,17 +2774,18 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
             return;
         }
 
-        if (state->use_id_mapping
-                && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
+        if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
             /* Take advantage of AD's tokenGroups mechanism to look up all
              * parent groups in a single request.
              */
-            subreq = sdap_get_ad_tokengroups_initgroups_send(state, state->ev,
+            subreq = sdap_get_ad_tokengroups_initgroups_send(state, state,
+                                                             state->ev,
                                                              state->opts,
                                                              state->sysdb,
                                                              state->dom,
                                                              state->sh,
-                                                             cname, orig_dn,
+                                                             state->cname,
+                                                             orig_dn,
                                                              state->timeout);
         } else if (state->opts->support_matching_rule
                     && dp_opt_get_bool(state->opts->basic,
@@ -2792,13 +2798,17 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
                                                             state->sysdb,
                                                             state->dom,
                                                             state->sh,
-                                                            cname, orig_dn,
+                                                            state->cname,
+                                                            orig_dn,
                                                             state->timeout);
         } else {
-            subreq = sdap_initgr_rfc2307bis_send(
-                    state, state->ev, state->opts, state->sysdb,
-                    state->dom, state->sh,
-                    cname, orig_dn);
+            subreq = sdap_initgr_rfc2307bis_send(state, state->ev,
+                                                 state->opts,
+                                                 state->sysdb,
+                                                 state->dom,
+                                                 state->sh,
+                                                 state->cname,
+                                                 orig_dn);
         }
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
@@ -2851,6 +2861,40 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
     char *dom_sid_str;
     char *group_sid_str;
     struct sdap_options *opts = state->opts;
+    const char *orig_dn;
+
+    if (state->failed_tokengroups) {
+        DEBUG(SSSDBG_MINOR_FAILURE, ("TokenGroups lookup failed, falling "
+                    "back to rfc2307bis initgroups call.\n"));
+
+        state->failed_tokengroups = false;
+
+        ret = sysdb_attrs_get_string(state->orig_user,
+                                     SYSDB_ORIG_DN,
+                                     &orig_dn);
+        if (ret != EOK) {
+            tevent_req_error(req, ret);
+            return;
+        }
+
+        subreq = sdap_initgr_rfc2307bis_send(state, state->ev,
+                                             state->opts,
+                                             state->sysdb,
+                                             state->dom,
+                                             state->sh,
+                                             state->cname,
+                                             orig_dn);
+
+        if (!subreq) {
+            tevent_req_error(req, ENOMEM);
+            return;
+        }
+
+        talloc_steal(subreq, orig_dn);
+        tevent_req_set_callback(subreq, sdap_get_initgr_done, req);
+
+        return;
+    }
 
     DEBUG(9, ("Initgroups done\n"));
 
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index e5649a2b9793253a55c48fba69cd3a902c0dc967..d4f598db1195f635cf773ab55828a92c0dfcc1eb 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -305,6 +305,7 @@ struct sdap_ad_tokengroups_initgr_state {
     struct sss_domain_info *domain;
     struct sdap_handle *sh;
     const char *username;
+    struct sdap_get_initgr_state *istate;
 };
 
 static void
@@ -312,6 +313,7 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *req);
 
 struct tevent_req *
 sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
+                                        void *istate,
                                         struct tevent_context *ev,
                                         struct sdap_options *opts,
                                         struct sysdb_ctx *sysdb,
@@ -336,6 +338,7 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
     state->domain = domain;
     state->sh = sh;
     state->username = name;
+    state->istate = (struct sdap_get_initgr_state *)istate;
 
     subreq = sdap_get_generic_send(
             state, state->ev, state->opts, state->sh,
@@ -464,20 +467,29 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
             DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
             ret = EOK;
             continue;
-        } else if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE,
-                  ("Could not convert SID to GID: [%s]. Skipping\n",
-                   strerror(ret)));
-            continue;
         }
 
-        DEBUG(SSSDBG_TRACE_LIBS,
-              ("Processing membership GID [%lu]\n",
-               gid));
+        if (state->istate->use_id_mapping) {
+            if (ret != EOK) {
+                DEBUG(SSSDBG_MINOR_FAILURE,
+                      ("Could not convert SID to GID: [%s]. Skipping\n",
+                       strerror(ret)));
+                continue;
+            }
+
+            DEBUG(SSSDBG_TRACE_LIBS,
+                  ("Processing membership GID [%lu]\n",
+                   gid));
+
+            /* Check whether this GID already exists in the sysdb */
+            ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain,
+                                            gid, attrs, &msg);
+        } else {
+            ret = sysdb_search_group_by_sid_str(tmp_ctx, state->sysdb,
+                                                state->domain, sid_str, attrs,
+                                                &msg);
+        }
 
-        /* Check whether this GID already exists in the sysdb */
-        ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain,
-                                        gid, attrs, &msg);
         if (ret == EOK) {
             group_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
             if (!group_name) {
@@ -487,20 +499,29 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
                 goto done;
             }
         } else if (ret == ENOENT) {
-            /* This is a new group. For now, we will store it
-             * under the name of its SID. When a direct lookup of
-             * the group or its GID occurs, it will replace this
-             * temporary entry.
-             */
-            group_name = sid_str;
-            ret = sysdb_add_incomplete_group(state->sysdb,
-                                             state->domain,
-                                             group_name, gid,
-                                             NULL, sid_str, false, now);
-            if (ret != EOK) {
-                DEBUG(SSSDBG_MINOR_FAILURE,
-                      ("Could not create incomplete group: [%s]\n",
-                       strerror(ret)));
+            if (state->istate->use_id_mapping) {
+                /* This is a new group. For now, we will store it
+                 * under the name of its SID. When a direct lookup of
+                 * the group or its GID occurs, it will replace this
+                 * temporary entry.
+                 */
+                group_name = sid_str;
+                ret = sysdb_add_incomplete_group(state->sysdb,
+                                                 state->domain,
+                                                 group_name, gid,
+                                                 NULL, sid_str, false, now);
+                if (ret != EOK) {
+                    DEBUG(SSSDBG_MINOR_FAILURE,
+                          ("Could not create incomplete group: [%s]\n",
+                           strerror(ret)));
+                    goto done;
+                }
+            } else {
+                DEBUG(SSSDBG_MINOR_FAILURE, ("SID [%s] not in cache, "
+                            "performing fallback.\n", sid_str));
+
+                state->istate->failed_tokengroups = true;
+                ret = EOK;
                 goto done;
             }
         } else {
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 4d0b86529a46ca7da495e44d4d9deaa2dd4e625f..ba720835960319b49c389f4ca42c083bfe41879f 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -44,6 +44,7 @@ struct sdap_get_initgr_state {
     struct sdap_id_ctx *id_ctx;
     struct sdap_id_conn_ctx *conn;
     const char *name;
+    const char *cname;
     const char **grp_attrs;
     const char **user_attrs;
     const char *user_base_filter;
@@ -56,6 +57,7 @@ struct sdap_get_initgr_state {
     struct sdap_search_base **user_search_bases;
 
     bool use_id_mapping;
+    bool failed_tokengroups;
 };
 
 bool is_dn(const char *str);
-- 
1.8.1.4

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to