Hi,

these two patches add a missing part to
https://fedorahosted.org/sssd/ticket/2481 (ID Views implementation does
not support IPA user&group overrides). Since it is not allowed to have
ghost members if a non-default view is applied because otherwise user
name overrides would not be covered ghosts members have to be resolved
for IPA groups in this case. The changes are only in the IPA provider so
they should not cause a regression in other providers. Since the generic
LDAP code use some IPA specific optimizations (derives user name from
the user's DN to avoid LDAP lookups) there wouldn't be a performance
benefit if this change would be in the generic LDAP code.

bye,
Sumit
From c6a74ed9a9a46c215462aa81eadbfac5c8c346e2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 10 Dec 2014 15:02:15 +0100
Subject: [PATCH 1/2] IPA: add get_be_acct_req_for_user_name()

Related to https://fedorahosted.org/sssd/ticket/2481
---
 src/providers/ipa/ipa_id.h    |  5 +++++
 src/providers/ipa/ipa_views.c | 13 +++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
index 
9d219f281847df0ba4ac24061e598eb6915f9c38..2bb5e0d38f42d4bbb04854dfb04804fecf6257e8
 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -87,6 +87,11 @@ errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const 
char *uuid,
                                  const char *domain_name,
                                  struct be_acct_req **_ar);
 
+errno_t get_be_acct_req_for_user_name(TALLOC_CTX *mem_ctx,
+                                      const char *user_name,
+                                      const char *domain_name,
+                                      struct be_acct_req **_ar);
+
 struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx,
                                             struct tevent_context *ev,
                                             struct sdap_id_ctx *sdap_id_ctx,
diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c
index 
c768186d7cf5e5a997e2ca27a167b62c8dc99b3f..ccaea69563728a5cecc202709da5dab51747c040
 100644
--- a/src/providers/ipa/ipa_views.c
+++ b/src/providers/ipa/ipa_views.c
@@ -177,6 +177,10 @@ static errno_t get_be_acct_req_for_xyz(TALLOC_CTX 
*mem_ctx, const char *val,
         ar->entry_type = BE_REQ_BY_UUID;
         ar->filter_type = BE_FILTER_UUID;
         break;
+    case BE_REQ_USER:
+        ar->entry_type = BE_REQ_USER;
+        ar->filter_type = BE_FILTER_NAME;
+        break;
     default:
         DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported request type [%d].\n", type);
         talloc_free(ar);
@@ -213,6 +217,15 @@ errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, 
const char *uuid,
                                    _ar);
 }
 
+errno_t get_be_acct_req_for_user_name(TALLOC_CTX *mem_ctx,
+                                      const char *user_name,
+                                      const char *domain_name,
+                                      struct be_acct_req **_ar)
+{
+    return get_be_acct_req_for_xyz(mem_ctx, user_name, domain_name, 
BE_REQ_USER,
+                                   _ar);
+}
+
 struct ipa_get_ad_override_state {
     struct tevent_context *ev;
     struct sdap_id_ctx *sdap_id_ctx;
-- 
2.1.0

From 47dd73e7ee559817d7913fc36266adfea6e50020 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 10 Dec 2014 15:03:18 +0100
Subject: [PATCH 2/2] IPA: resolve ghost members if a non-default view is
 applied

Related to https://fedorahosted.org/sssd/ticket/2481
---
 src/providers/ipa/ipa_id.c            | 217 ++++++++++++++++++++++++++++++++++
 src/providers/ipa/ipa_subdomains_id.c |   1 +
 2 files changed, 218 insertions(+)

diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 
5665a1835e8b0ab18325bfc68a8d8b5650730943..2b566f6fc97a25424c6106bd87958b38ce5ae20c
 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -144,6 +144,154 @@ static void ipa_account_info_done(struct tevent_req *req)
     sdap_handler_done(breq, dp_error, ret, error_text);
 }
 
+struct ipa_resolve_user_list_state {
+    struct tevent_context *ev;
+    struct sdap_id_ctx *sdap_id_ctx;
+    struct be_req *be_req;
+    struct ldb_message_element *users;
+    const char *domain_name;
+    size_t user_idx;
+
+    int dp_error;
+};
+
+static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req);
+static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq);
+
+static struct tevent_req *
+ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev,
+                           struct be_req *be_req,
+                           struct sdap_id_ctx *sdap_id_ctx,
+                           const char *domain_name,
+                           struct ldb_message_element *users)
+{
+    int ret;
+    struct tevent_req *req;
+    struct ipa_resolve_user_list_state *state;
+
+    req = tevent_req_create(memctx, &state,
+                            struct ipa_resolve_user_list_state);
+    if (req == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
+        return NULL;
+    }
+
+    state->ev = ev;
+    state->sdap_id_ctx = sdap_id_ctx;
+    state->be_req = be_req;
+    state->domain_name = domain_name;
+    state->users = users;
+    state->user_idx = 0;
+    state->dp_error = DP_ERR_FATAL;
+
+    ret = ipa_resolve_user_list_get_user_step(req);
+    if (ret == EAGAIN) {
+        return req;
+    }
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "ipa_resolve_user_list_get_user_step failed.\n");
+    }
+
+    if (ret == EOK) {
+        state->dp_error = DP_ERR_OK;
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
+    tevent_req_post(req, ev);
+    return req;
+}
+
+static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req)
+{
+    int ret;
+    struct tevent_req *subreq;
+    struct be_acct_req *ar;
+    struct ipa_resolve_user_list_state *state = tevent_req_data(req,
+                                            struct 
ipa_resolve_user_list_state);
+
+    if (state->user_idx >= state->users->num_values) {
+        return EOK;
+    }
+
+    ret = get_be_acct_req_for_user_name(state,
+                                     
state->users->values[state->user_idx].data,
+                                     state->domain_name, &ar);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_user_name failed.\n");
+        return ret;
+    }
+
+    DEBUG(SSSDBG_TRACE_ALL, "Trying to resolve user [%s].\n", 
ar->filter_value);
+
+    subreq = sdap_handle_acct_req_send(state, state->be_req, ar,
+                                       state->sdap_id_ctx,
+                                       state->sdap_id_ctx->opts->sdom,
+                                       state->sdap_id_ctx->conn, true);
+    if (subreq == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n");
+        return ENOMEM;
+    }
+
+    tevent_req_set_callback(subreq, ipa_resolve_user_list_get_user_done, req);
+
+    return EAGAIN;
+}
+
+static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq)
+{
+    struct tevent_req *req = tevent_req_callback_data(subreq,
+                                                struct tevent_req);
+    struct ipa_resolve_user_list_state *state = tevent_req_data(req,
+                                            struct 
ipa_resolve_user_list_state);
+    int ret;
+
+    ret = sdap_handle_acct_req_recv(subreq, &state->dp_error, NULL, NULL);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret);
+        goto done;
+    }
+
+    state->user_idx++;
+
+    ret = ipa_resolve_user_list_get_user_step(req);
+    if (ret == EAGAIN) {
+        return;
+    }
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "ipa_resolve_user_list_get_user_step failed.\n");
+    }
+
+done:
+    if (ret == EOK) {
+        state->dp_error = DP_ERR_OK;
+        tevent_req_done(req);
+    } else {
+        if (state->dp_error == DP_ERR_OK) {
+            state->dp_error = DP_ERR_FATAL;
+        }
+        tevent_req_error(req, ret);
+    }
+    return;
+}
+
+static int ipa_resolve_user_list_recv(struct tevent_req *req, int *dp_error)
+{
+    struct ipa_resolve_user_list_state *state = tevent_req_data(req,
+                                            struct 
ipa_resolve_user_list_state);
+
+    if (dp_error) {
+        *dp_error = state->dp_error;
+    }
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    return EOK;
+}
+
 struct ipa_id_get_account_info_state {
     struct tevent_context *ev;
     struct ipa_id_ctx *ipa_ctx;
@@ -157,6 +305,7 @@ struct ipa_id_get_account_info_state {
 
     struct sysdb_attrs *override_attrs;
     struct ldb_message *obj_msg;
+    struct ldb_message_element *ghosts;
     int dp_error;
 };
 
@@ -166,6 +315,7 @@ static errno_t 
ipa_id_get_account_info_get_original_step(struct tevent_req *req,
                                                         struct be_acct_req 
*ar);
 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 *
 ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
@@ -405,6 +555,17 @@ static void ipa_id_get_account_info_orig_done(struct 
tevent_req *subreq)
         goto fail;
     }
 
+    if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_GROUP
+            && state->obj_msg != NULL
+            && state->ipa_ctx->view_name != NULL
+            && strcmp(state->ipa_ctx->view_name,
+                      SYSDB_DEFAULT_VIEW_NAME) != 0) {
+        /* check for ghost members because shost members are not allowed if a
+         * view other than the default view is applied.*/
+
+        state->ghosts = ldb_msg_find_element(state->obj_msg, SYSDB_GHOST);
+    }
+
     if (state->override_attrs == NULL) {
         uuid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_UUID, NULL);
         if (uuid == NULL) {
@@ -457,6 +618,21 @@ static void ipa_id_get_account_info_orig_done(struct 
tevent_req *subreq)
         }
     }
 
+    if (state->ghosts != NULL) {
+        /* Resolve ghost members */
+        subreq = ipa_resolve_user_list_send(state, state->ev, state->be_req,
+                                            state->ipa_ctx->sdap_id_ctx,
+                                            state->domain->name,
+                                            state->ghosts);
+        if (subreq == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
+            ret = ENOMEM;
+            goto fail;
+        }
+        tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req);
+        return;
+    }
+
     state->dp_error = DP_ERR_OK;
     tevent_req_done(req);
     return;
@@ -508,6 +684,47 @@ static void ipa_id_get_account_info_done(struct tevent_req 
*subreq)
         goto fail;
     }
 
+    if (state->ghosts != NULL) {
+        /* Resolve ghost members */
+        subreq = ipa_resolve_user_list_send(state, state->ev, state->be_req,
+                                            state->ipa_ctx->sdap_id_ctx,
+                                            state->domain->name,
+                                            state->ghosts);
+        if (subreq == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
+            ret = ENOMEM;
+            goto fail;
+        }
+        tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req);
+        return;
+    }
+
+    state->dp_error = DP_ERR_OK;
+    tevent_req_done(req);
+    return;
+
+fail:
+    state->dp_error = dp_error;
+    tevent_req_error(req, ret);
+    return;
+}
+
+static void ipa_id_get_user_list_done(struct tevent_req *subreq)
+{
+    struct tevent_req *req = tevent_req_callback_data(subreq,
+                                                struct tevent_req);
+    struct ipa_id_get_account_info_state *state = tevent_req_data(req,
+                                          struct 
ipa_id_get_account_info_state);
+    int dp_error = DP_ERR_FATAL;
+    int ret;
+
+    ret = ipa_resolve_user_list_recv(subreq, &dp_error);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user list %d\n", ret);
+        goto fail;
+    }
+
     state->dp_error = DP_ERR_OK;
     tevent_req_done(req);
     return;
diff --git a/src/providers/ipa/ipa_subdomains_id.c 
b/src/providers/ipa/ipa_subdomains_id.c
index 
5c53876dc9a7080c3b361d9cc72f0eedecff8600..79285548d9470b34d66b366367fb69ef57710f83
 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -862,6 +862,7 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx,
                             SYSDB_SID_STR,
                             SYSDB_OBJECTCLASS,
                             SYSDB_UUID,
+                            SYSDB_GHOST,
                             NULL };
     char *name;
 
-- 
2.1.0

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

Reply via email to