Blob Blame History Raw
From 179ac94a4910150b846ff1c959e766c5a31274cf Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Fri, 8 May 2015 14:49:09 +0200
Subject: [PATCH 10/13] LDAP: Add sdap_lookup_type enum
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Related:
    https://fedorahosted.org/sssd/ticket/2553

Change the boolan parameter of sdap_get_users_send and sdap_get_groups_send
to a tri-state that controls whether we expect only a single entry
(ie don't use the paging control), multiple entries with a search limit
(wildcard request) or multiple entries with no limit (enumeration).

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
 src/providers/ldap/ldap_auth.c         |  2 +-
 src/providers/ldap/ldap_id.c           | 16 +++++++-------
 src/providers/ldap/sdap_async.h        | 12 +++++++---
 src/providers/ldap/sdap_async_enum.c   |  4 ++--
 src/providers/ldap/sdap_async_groups.c | 40 ++++++++++++++++++++++++----------
 src/providers/ldap/sdap_async_users.c  | 32 ++++++++++++++++++++-------
 6 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 81717942613b4a91ebab668ba2ecfe13caab38be..217e80fd07abc41f2594d19397783683d44600cd 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -418,7 +418,7 @@ static struct tevent_req *get_user_dn_send(TALLOC_CTX *memctx,
                                    sh, attrs, filter,
                                    dp_opt_get_int(opts->basic,
                                                   SDAP_SEARCH_TIMEOUT),
-                                   false);
+                                   SDAP_LOOKUP_SINGLE);
     if (!subreq) {
         ret = ENOMEM;
         goto done;
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 61f09fc41d3210af5044f5338dd90db67e0123a7..73840d2885ed15a7a9dae2e9175d8361c8fdfe7d 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -396,12 +396,12 @@ static void users_get_search(struct tevent_req *req)
     struct users_get_state *state = tevent_req_data(req,
                                                      struct users_get_state);
     struct tevent_req *subreq;
-    bool multiple_results;
+    enum sdap_entry_lookup_type lookup_type;
 
     if (state->filter_type == BE_FILTER_WILDCARD) {
-        multiple_results = true;
+        lookup_type = SDAP_LOOKUP_WILDCARD;
     } else {
-        multiple_results = false;
+        lookup_type = SDAP_LOOKUP_SINGLE;
     }
 
     subreq = sdap_get_users_send(state, state->ev,
@@ -412,7 +412,7 @@ static void users_get_search(struct tevent_req *req)
                                  state->attrs, state->filter,
                                  dp_opt_get_int(state->ctx->opts->basic,
                                                 SDAP_SEARCH_TIMEOUT),
-                                 multiple_results);
+                                 lookup_type);
     if (!subreq) {
         tevent_req_error(req, ENOMEM);
         return;
@@ -901,12 +901,12 @@ static void groups_get_search(struct tevent_req *req)
     struct groups_get_state *state = tevent_req_data(req,
                                                      struct groups_get_state);
     struct tevent_req *subreq;
-    bool multiple_results;
+    enum sdap_entry_lookup_type lookup_type;
 
     if (state->filter_type == BE_FILTER_WILDCARD) {
-        multiple_results = true;
+        lookup_type = SDAP_LOOKUP_WILDCARD;
     } else {
-        multiple_results = false;
+        lookup_type = SDAP_LOOKUP_SINGLE;
     }
 
     subreq = sdap_get_groups_send(state, state->ev,
@@ -916,7 +916,7 @@ static void groups_get_search(struct tevent_req *req)
                                   state->attrs, state->filter,
                                   dp_opt_get_int(state->ctx->opts->basic,
                                                  SDAP_SEARCH_TIMEOUT),
-                                  multiple_results,
+                                  lookup_type,
                                   state->no_members);
     if (!subreq) {
         tevent_req_error(req, ENOMEM);
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index b23dfc313905d01caedd1eace6bcb525481b9ebe..09bc0d65407253f93514b30877850cc38009c625 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -59,6 +59,12 @@ errno_t sdap_connect_host_recv(TALLOC_CTX *mem_ctx,
                                struct sdap_handle **_sh);
 
 /* Search users in LDAP, return them as attrs */
+enum sdap_entry_lookup_type {
+    SDAP_LOOKUP_SINGLE,         /* Direct single-user/group lookup */
+    SDAP_LOOKUP_WILDCARD,       /* Multiple entries with a limit */
+    SDAP_LOOKUP_ENUMERATE,      /* Fetch all entries from the server */
+};
+
 struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx,
                                          struct tevent_context *ev,
                                          struct sss_domain_info *dom,
@@ -68,7 +74,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx,
                                          const char **attrs,
                                          const char *filter,
                                          int timeout,
-                                         bool enumeration);
+                                         enum sdap_entry_lookup_type lookup_type);
 int sdap_search_user_recv(TALLOC_CTX *memctx, struct tevent_req *req,
                           char **higher_usn, struct sysdb_attrs ***users,
                           size_t *count);
@@ -84,7 +90,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
                                        const char **attrs,
                                        const char *filter,
                                        int timeout,
-                                       bool enumeration);
+                                       enum sdap_entry_lookup_type lookup_type);
 int sdap_get_users_recv(struct tevent_req *req,
                         TALLOC_CTX *mem_ctx, char **timestamp);
 
@@ -96,7 +102,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
                                        const char **attrs,
                                        const char *filter,
                                        int timeout,
-                                       bool enumeration,
+                                       enum sdap_entry_lookup_type lookup_type,
                                        bool no_members);
 int sdap_get_groups_recv(struct tevent_req *req,
                          TALLOC_CTX *mem_ctx, char **timestamp);
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index 35afc55f809669a44aa2beda7d87dfe62d6ec10b..f22276c3ce6f839b765bbc1602fafb010cc37d89 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -635,7 +635,7 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
                                  state->attrs, state->filter,
                                  dp_opt_get_int(state->ctx->opts->basic,
                                                 SDAP_ENUM_SEARCH_TIMEOUT),
-                                 true);
+                                 SDAP_LOOKUP_ENUMERATE);
     if (!subreq) {
         ret = ENOMEM;
         goto fail;
@@ -811,7 +811,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
                                   state->attrs, state->filter,
                                   dp_opt_get_int(state->ctx->opts->basic,
                                                  SDAP_ENUM_SEARCH_TIMEOUT),
-                                  true, false);
+                                  SDAP_LOOKUP_ENUMERATE, false);
     if (!subreq) {
         ret = ENOMEM;
         goto fail;
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index e785307e60d0df5be96a5b2de2c07baabaf1e371..ad0354df1fce9011c68cabb6049e7feee92a44c0 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1721,7 +1721,7 @@ struct sdap_get_groups_state {
     const char *base_filter;
     char *filter;
     int timeout;
-    bool enumeration;
+    enum sdap_entry_lookup_type lookup_type;
     bool no_members;
 
     char *higher_usn;
@@ -1752,7 +1752,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
                                        const char **attrs,
                                        const char *filter,
                                        int timeout,
-                                       bool enumeration,
+                                       enum sdap_entry_lookup_type lookup_type,
                                        bool no_members)
 {
     errno_t ret;
@@ -1775,7 +1775,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
     state->groups =  NULL;
     state->count = 0;
     state->timeout = timeout;
-    state->enumeration = enumeration;
+    state->lookup_type = lookup_type;
     state->no_members = no_members;
     state->base_filter = filter;
     state->base_iter = 0;
@@ -1855,6 +1855,7 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
 {
     struct tevent_req *subreq;
     struct sdap_get_groups_state *state;
+    bool need_paging = false;
 
     state = tevent_req_data(req, struct sdap_get_groups_state);
 
@@ -1870,6 +1871,19 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
           "Searching for groups with base [%s]\n",
            state->search_bases[state->base_iter]->basedn);
 
+    switch (state->lookup_type) {
+    case SDAP_LOOKUP_SINGLE:
+        need_paging = false;
+        break;
+    /* Only requests that can return multiple entries should require
+     * the paging control
+     */
+    case SDAP_LOOKUP_WILDCARD:
+    case SDAP_LOOKUP_ENUMERATE:
+        need_paging = true;
+        break;
+    }
+
     subreq = sdap_get_and_parse_generic_send(
             state, state->ev, state->opts,
             state->ldap_sh != NULL ? state->ldap_sh : state->sh,
@@ -1878,7 +1892,7 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
             state->filter, state->attrs,
             state->opts->group_map, SDAP_OPTS_GROUP,
             0, NULL, NULL, 0, state->timeout,
-            state->enumeration); /* If we're enumerating, we need paging */
+            need_paging);
     if (!subreq) {
         return ENOMEM;
     }
@@ -1914,14 +1928,17 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC,
           "Search for groups, returned %zu results.\n", count);
 
-    if (!state->enumeration && count > 1) {
+    if (state->lookup_type == SDAP_LOOKUP_SINGLE && count > 1) {
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Individual group search returned multiple results\n");
         tevent_req_error(req, EINVAL);
         return;
     }
 
-    if (state->enumeration || count == 0) {
+    if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \
+            state->lookup_type == SDAP_LOOKUP_ENUMERATE || \
+        count == 0) {
+        /* No users found in this search or looking up multiple entries */
         next_base = true;
     }
 
@@ -2003,7 +2020,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
      * LDAP_MATCHING_RULE_IN_CHAIN available in
      * AD 2008 and later
      */
-    if (!state->enumeration) {
+    if (state->lookup_type == SDAP_LOOKUP_SINGLE) {
         if ((state->opts->schema_type != SDAP_SCHEMA_RFC2307)
                 && (dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0)
                 && !dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) {
@@ -2026,7 +2043,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
     /* If we're using LDAP_MATCHING_RULE_IN_CHAIN, start a subreq to
      * retrieve the members so we can save them in a single step.
      */
-    if (!state->enumeration
+    if (state->lookup_type == SDAP_LOOKUP_SINGLE
             && (state->opts->schema_type != SDAP_SCHEMA_RFC2307)
             && state->opts->support_matching_rule
             && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) {
@@ -2050,7 +2067,8 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
         return;
     }
 
-    if (state->enumeration
+    if ((state->lookup_type == SDAP_LOOKUP_ENUMERATE
+                || state->lookup_type == SDAP_LOOKUP_WILDCARD)
             && state->opts->schema_type != SDAP_SCHEMA_RFC2307
             && dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) {
         DEBUG(SSSDBG_TRACE_ALL, "Saving groups without members first "
@@ -2069,7 +2087,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
         subreq = sdap_process_group_send(state, state->ev, state->dom,
                                          state->sysdb, state->opts,
                                          state->sh, state->groups[i],
-                                         state->enumeration);
+                                         state->lookup_type == SDAP_LOOKUP_ENUMERATE);
 
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
@@ -2116,7 +2134,7 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
         ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
                                state->groups, state->count,
                                !state->dom->ignore_group_members, NULL,
-                               !state->enumeration,
+                               state->lookup_type == SDAP_LOOKUP_SINGLE,
                                &state->higher_usn);
         if (ret) {
             DEBUG(SSSDBG_OP_FAILURE, "Failed to store groups.\n");
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 216b49477bf21481265444c5c03df0aac7ee84e4..f66ae2604c867d4a5e8d223081ece9f1e474cf73 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -606,7 +606,7 @@ struct sdap_search_user_state {
     const char *base_filter;
     const char *filter;
     int timeout;
-    bool enumeration;
+    enum sdap_entry_lookup_type lookup_type;
 
     char *higher_usn;
     struct sysdb_attrs **users;
@@ -628,7 +628,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx,
                                          const char **attrs,
                                          const char *filter,
                                          int timeout,
-                                         bool enumeration)
+                                         enum sdap_entry_lookup_type lookup_type)
 {
     errno_t ret;
     struct tevent_req *req;
@@ -649,7 +649,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx,
     state->base_filter = filter;
     state->base_iter = 0;
     state->search_bases = search_bases;
-    state->enumeration = enumeration;
+    state->lookup_type = lookup_type;
 
     if (!state->search_bases) {
         DEBUG(SSSDBG_CRIT_FAILURE,
@@ -673,6 +673,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req)
 {
     struct tevent_req *subreq;
     struct sdap_search_user_state *state;
+    bool need_paging = false;
 
     state = tevent_req_data(req, struct sdap_search_user_state);
 
@@ -688,6 +689,19 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req)
           "Searching for users with base [%s]\n",
            state->search_bases[state->base_iter]->basedn);
 
+    switch (state->lookup_type) {
+    case SDAP_LOOKUP_SINGLE:
+        need_paging = false;
+        break;
+    /* Only requests that can return multiple entries should require
+     * the paging control
+     */
+    case SDAP_LOOKUP_WILDCARD:
+    case SDAP_LOOKUP_ENUMERATE:
+        need_paging = true;
+        break;
+    }
+
     subreq = sdap_get_and_parse_generic_send(
             state, state->ev, state->opts, state->sh,
             state->search_bases[state->base_iter]->basedn,
@@ -695,7 +709,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req)
             state->filter, state->attrs,
             state->opts->user_map, state->opts->user_map_cnt,
             0, NULL, NULL, 0, state->timeout,
-            state->enumeration); /* If we're enumerating, we need paging */
+            need_paging);
     if (subreq == NULL) {
         return ENOMEM;
     }
@@ -726,8 +740,10 @@ static void sdap_search_user_process(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC,
           "Search for users, returned %zu results.\n", count);
 
-    if (state->enumeration || count == 0) {
-        /* No users found in this search or enumerating */
+    if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \
+            state->lookup_type == SDAP_LOOKUP_ENUMERATE || \
+        count == 0) {
+        /* No users found in this search or looking up multiple entries */
         next_base = true;
     }
 
@@ -827,7 +843,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
                                        const char **attrs,
                                        const char *filter,
                                        int timeout,
-                                       bool enumeration)
+                                       enum sdap_entry_lookup_type lookup_type)
 {
     errno_t ret;
     struct tevent_req *req;
@@ -842,7 +858,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
     state->dom = dom;
 
     subreq = sdap_search_user_send(state, ev, dom, opts, search_bases,
-                                   sh, attrs, filter, timeout, enumeration);
+                                   sh, attrs, filter, timeout, lookup_type);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto done;
-- 
2.4.3