Blob Blame History Raw
From fbd38903a3c4985e560e6c670ead84597982242e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 19 Jun 2019 11:40:56 +0200
Subject: [PATCH] ipa: use LDAP not extdom to lookup IPA users and groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Currently when an IPA client is resolving trusted users and groups with
the help of the extdom plugin it uses the extdom plugin as well to
lookup IPA objects. This might cause issues if e.g. there is a user in
IPA with the same name as a group in AD or the other way round.

To solve this and to lower the load on the extdom plugin on the IPA
server side this patch will lookup IPA object directly from LDAP on the
IPA server.

Related to https://pagure.io/SSSD/sssd/issue/4073

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 27b141f38dd04d4b69e609a4cc64676a0716226e)
---
 src/providers/ipa/ipa_id.c       | 11 +-----
 src/providers/ipa/ipa_id.h       |  5 +++
 src/providers/ipa/ipa_s2n_exop.c | 67 ++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index f34692aa2..94d5f9d90 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -30,13 +30,6 @@
 #include "providers/ldap/sdap_async.h"
 #include "providers/ipa/ipa_id.h"
 
-static struct tevent_req *
-ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
-                             struct ipa_id_ctx *ipa_ctx,
-                             struct dp_id_data *ar);
-
-static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error);
-
 static bool is_object_overridable(struct dp_id_data *ar)
 {
     bool ret = false;
@@ -516,7 +509,7 @@ static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq);
 static void ipa_id_get_account_info_done(struct tevent_req *subreq);
 static void ipa_id_get_user_list_done(struct tevent_req *subreq);
 
-static struct tevent_req *
+struct tevent_req *
 ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
                              struct ipa_id_ctx *ipa_ctx,
                              struct dp_id_data *ar)
@@ -1120,7 +1113,7 @@ fail:
     return;
 }
 
-static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error)
+int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error)
 {
     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
                                           struct ipa_id_get_account_info_state);
diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
index fe9acfeef..c18e709b8 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -151,4 +151,9 @@ ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev,
                            struct ldb_message_element *users);
 int ipa_resolve_user_list_recv(struct tevent_req *req, int *dp_error);
 
+struct tevent_req *
+ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
+                             struct ipa_id_ctx *ipa_ctx,
+                             struct dp_id_data *ar);
+int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error);
 #endif
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index a07f73200..598b1568e 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -1121,6 +1121,7 @@ struct ipa_s2n_get_list_state {
 static errno_t ipa_s2n_get_list_step(struct tevent_req *req);
 static void ipa_s2n_get_list_get_override_done(struct tevent_req *subreq);
 static void ipa_s2n_get_list_next(struct tevent_req *subreq);
+static void ipa_s2n_get_list_ipa_next(struct tevent_req *subreq);
 static errno_t ipa_s2n_get_list_save_step(struct tevent_req *req);
 
 static struct tevent_req *ipa_s2n_get_list_send(TALLOC_CTX *mem_ctx,
@@ -1195,6 +1196,7 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
     uint32_t id;
     char *endptr;
     bool need_v1 = false;
+    struct dp_id_data *ar;
 
     parent_domain = get_domains_head(state->dom);
     switch (state->req_input.type) {
@@ -1222,6 +1224,35 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
 
         state->req_input.inp.name = short_name;
 
+        if (strcmp(state->obj_domain->name,
+            state->ipa_ctx->sdap_id_ctx->be->domain->name) == 0) {
+            DEBUG(SSSDBG_TRACE_INTERNAL,
+                  "Looking up IPA object [%s] from LDAP.\n",
+                  state->list[state->list_idx]);
+            ret = get_dp_id_data_for_user_name(state,
+                                               state->list[state->list_idx],
+                                               state->obj_domain->name,
+                                               &ar);
+            if (ret != EOK) {
+                DEBUG(SSSDBG_OP_FAILURE,
+                      "Failed to create lookup date for IPA object [%s].\n",
+                      state->list[state->list_idx]);
+                return ret;
+            }
+            ar->entry_type = state->entry_type;
+
+            subreq = ipa_id_get_account_info_send(state, state->ev,
+                                                  state->ipa_ctx, ar);
+            if (subreq == NULL) {
+                DEBUG(SSSDBG_OP_FAILURE,
+                      "ipa_id_get_account_info_send failed.\n");
+                return ENOMEM;
+            }
+            tevent_req_set_callback(subreq, ipa_s2n_get_list_ipa_next, req);
+
+            return EOK;
+        }
+
         break;
     case REQ_INP_ID:
         errno = 0;
@@ -1363,6 +1394,42 @@ fail:
     return;
 }
 
+static void ipa_s2n_get_list_ipa_next(struct tevent_req *subreq)
+{
+    int ret;
+    int dp_error;
+    struct tevent_req *req = tevent_req_callback_data(subreq,
+                                                      struct tevent_req);
+    struct ipa_s2n_get_list_state *state = tevent_req_data(req,
+                                               struct ipa_s2n_get_list_state);
+
+    ret = ipa_id_get_account_info_recv(subreq, &dp_error);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "ipa_id_get_account_info failed: %d %d\n", ret,
+                                 dp_error);
+        goto done;
+    }
+
+    state->list_idx++;
+    if (state->list[state->list_idx] == NULL) {
+        tevent_req_done(req);
+        return;
+    }
+
+    ret = ipa_s2n_get_list_step(req);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_list_step failed.\n");
+        goto done;
+    }
+
+    return;
+
+done:
+    tevent_req_error(req,ret);
+    return;
+}
+
 static void ipa_s2n_get_list_get_override_done(struct tevent_req *subreq)
 {
     int ret;
-- 
2.20.1