[SSSD] [PATCH] Fix enumeration for IPA providers

Jakub Hrozek jhrozek at redhat.com
Mon May 25 09:04:27 UTC 2015


Hi,

I found out that the IPA provider segfaults when it receives an
enumeration request. The first patch gets rid of the segfault, but there
would still be an error in the IPA provider is it would expect the
be_req contents to be usable for cache search. The second patch
shortcuts the enumeration request completely.

I even wonder if it was possible to shortcut the enumeration requests
sooner in the Data Provider and avoid sending them to the back ends
completely? Any downsides to this (except a possible 3rd party backend
that might allow an enumeration request on demand) ?

Finally, enumeration with IPA backend and ID views don't work at all,
but I wouldn't waste time with this at the moment -- just make sure that
we don't reqress.
-------------- next part --------------
>From 1621548d428f8fb42c3429b0936309c49ce02dbc Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 25 May 2015 10:20:39 +0200
Subject: [PATCH 1/2] DP: Set extra_value to NULL for enum requests

Some providers, notably IPA, rely on extra_value to be either a useful
value or NULL. In enumeration, however, extra_value was random. Set
the extra_value pointer explicitly to NULL to make it clear that it's
not used for enumeration and also use talloc_zero as future-proof.
---
 src/providers/data_provider_be.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index a37fbbc8d72d8bc0bf31b9b05a4aaf24c2f4c9e6..34c7b2c766ee4072ee980ad43f1e1d33ee7c8a5a 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1155,7 +1155,7 @@ static int be_get_account_info(struct sbus_request *dbus_req, void *user_data)
         goto done;
     }
 
-    req = talloc(be_req, struct be_acct_req);
+    req = talloc_zero(be_req, struct be_acct_req);
     if (!req) {
         err_maj = DP_ERR_FATAL;
         err_min = ENOMEM;
@@ -1202,6 +1202,7 @@ static int be_get_account_info(struct sbus_request *dbus_req, void *user_data)
         } else if (strcmp(filter, ENUM_INDICATOR) == 0) {
             req->filter_type = BE_FILTER_ENUM;
             req->filter_value = NULL;
+            req->extra_value = NULL;
         } else {
             err_maj = DP_ERR_FATAL;
             err_min = EINVAL;
-- 
2.1.0

-------------- next part --------------
>From 6e70c46888cbcd77134349e0adbefee1c7a8578f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 25 May 2015 10:21:05 +0200
Subject: [PATCH 2/2] Skip enumeration requests in IPA and AD providers as well

Checking the enum request in the underlying LDAP provider to skip it
might be too late as the richer IPA or AD providers depend on having a
useful result when the sdap request finishes.

Move the enumeration check earlier instead and allow directly in the IPA
or AD handler.
---
 src/providers/ad/ad_id.c         |  5 +++++
 src/providers/ipa/ipa_id.c       |  5 +++++
 src/providers/ldap/ldap_common.h |  3 +++
 src/providers/ldap/ldap_id.c     | 48 ++++++++++++++++------------------------
 4 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index ab3934727085fa94ee5bb09ffe0c62546650c42b..d8ea26875daf1ad38131eef7c1dd9957e776000f 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -350,6 +350,11 @@ ad_account_info_handler(struct be_req *be_req)
         return be_req_terminate(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline");
     }
 
+    if (sdap_is_enum_request(ar)) {
+        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
+        return sdap_handler_done(be_req, DP_ERR_OK, EOK, "Success");
+    }
+
     /* Try to shortcut if this is ID or SID search and it belongs to
      * other domain range than is in ar->domain. */
     shortcut = ad_account_can_shortcut(be_ctx, sdap_id_ctx->opts->idmap_ctx,
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 2bae97cd959af6d5ebceb697a9c8d7af33c358a6..24dfe32b1fcb03fe9c152a3569037ed126c8e6d6 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -89,6 +89,11 @@ void ipa_account_info_handler(struct be_req *breq)
 
     ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req);
 
+    if (sdap_is_enum_request(ar)) {
+        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
+        return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success");
+    }
+
     if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) {
         /* if domain names do not match, this is a subdomain case
          * subdomain lookups are handled differently on the server
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 57ad1b8458988d7e108f019c20f67bcde32539d4..c142af3452a0bc9a10d90d13c9586c4dd78a768b 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -102,6 +102,9 @@ int sdap_id_setup_tasks(struct be_ctx *be_ctx,
                         be_ptask_recv_t recv_fn,
                         void *pvt);
 
+/* Allow shortcutting an enumeration request */
+bool sdap_is_enum_request(struct be_acct_req *ar);
+
 struct tevent_req *
 sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
                           struct be_ctx *be_ctx,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 33c039082ef2d406578de3ac8d66561ce42fc793..ed132e59c242c135336ef7f452f02bc531097504 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -1359,6 +1359,20 @@ void sdap_account_info_handler(struct be_req *breq)
     return sdap_handle_account_info(breq, ctx, ctx->conn);
 }
 
+bool sdap_is_enum_request(struct be_acct_req *ar)
+{
+    switch (ar->entry_type & BE_REQ_TYPE_MASK) {
+    case BE_REQ_USER:
+    case BE_REQ_GROUP:
+    case BE_REQ_SERVICES:
+        if (ar->filter_type == BE_FILTER_ENUM) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 /* A generic LDAP account info handler */
 struct sdap_handle_acct_req_state {
     struct be_acct_req *ar;
@@ -1399,16 +1413,6 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
 
     switch (ar->entry_type & BE_REQ_TYPE_MASK) {
     case BE_REQ_USER: /* user */
-
-        /* skip enumerations on demand */
-        if (ar->filter_type == BE_FILTER_ENUM) {
-            DEBUG(SSSDBG_TRACE_LIBS,
-                  "Skipping user enumeration on demand\n");
-            state->err = "Success";
-            ret = EOK;
-            goto done;
-        }
-
         subreq = users_get_send(state, be_ctx->ev, id_ctx,
                                 sdom, conn,
                                 ar->filter_value,
@@ -1419,16 +1423,6 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
         break;
 
     case BE_REQ_GROUP: /* group */
-
-        /* skip enumerations on demand */
-        if (ar->filter_type == BE_FILTER_ENUM) {
-            DEBUG(SSSDBG_TRACE_LIBS,
-                  "Skipping group enumeration on demand\n");
-            state->err = "Success";
-            ret = EOK;
-            goto done;
-        }
-
         subreq = groups_get_send(state, be_ctx->ev, id_ctx,
                                  sdom, conn,
                                  ar->filter_value,
@@ -1473,15 +1467,6 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
         break;
 
     case BE_REQ_SERVICES:
-        /* skip enumerations on demand */
-        if (ar->filter_type == BE_FILTER_ENUM) {
-            DEBUG(SSSDBG_TRACE_LIBS,
-                  "Skipping service enumeration on demand\n");
-            state->err = "Success";
-            ret = EOK;
-            goto done;
-        }
-
         if (ar->filter_type == BE_FILTER_SECID
                 || ar->filter_type == BE_FILTER_UUID) {
             ret = EINVAL;
@@ -1667,6 +1652,11 @@ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx,
                                  EINVAL, "Invalid private data");
     }
 
+    if (sdap_is_enum_request(ar)) {
+        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
+        return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success");
+    }
+
     req = sdap_handle_acct_req_send(breq, ctx->be, ar, ctx,
                                     ctx->opts->sdom, conn, true);
     if (req == NULL) {
-- 
2.1.0



More information about the sssd-devel mailing list