|
|
2fc102 |
From 8c714cbf1d0ce2cbddc4222ade51e1f93f36dbe8 Mon Sep 17 00:00:00 2001
|
|
|
2fc102 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
2fc102 |
Date: Wed, 22 Jan 2014 15:21:24 +0100
|
|
|
2fc102 |
Subject: [PATCH 71/71] AD: Establish cross-domain memberships after
|
|
|
2fc102 |
enumeration finishes
|
|
|
2fc102 |
|
|
|
2fc102 |
Because domain enumeration currently works for each domain separately,
|
|
|
2fc102 |
the code has to establish cross-domain memberships after all domains are
|
|
|
2fc102 |
enumerated. The code works as follows:
|
|
|
2fc102 |
|
|
|
2fc102 |
1) check if any *sub*domains were enumerated. If not, do nothing
|
|
|
2fc102 |
2) if any of the groups saved had more original members than
|
|
|
2fc102 |
sysdb members, check if members of these groups can be linked now
|
|
|
2fc102 |
that all users and groups are saved using the orig_member
|
|
|
2fc102 |
attribute of the group matched against originalDN member of the
|
|
|
2fc102 |
user.
|
|
|
2fc102 |
|
|
|
2fc102 |
Related:
|
|
|
2fc102 |
https://fedorahosted.org/sssd/ticket/2142
|
|
|
2fc102 |
---
|
|
|
2fc102 |
src/providers/ad/ad_id.c | 390 +++++++++++++++++++++++++++++++++++++--
|
|
|
2fc102 |
src/providers/ad/ad_subdomains.c | 11 --
|
|
|
2fc102 |
2 files changed, 379 insertions(+), 22 deletions(-)
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
index a47aa4f75ab348b0f4597fea264d770b5abe3184..e3302c15774ab1c24b16cefc274313e447b31e5c 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_id.c
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
@@ -420,10 +420,13 @@ struct ad_enumeration_state {
|
|
|
2fc102 |
struct tevent_context *ev;
|
|
|
2fc102 |
|
|
|
2fc102 |
struct sdap_domain *sdom;
|
|
|
2fc102 |
+ struct sdap_domain *sditer;
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
static void ad_enumeration_conn_done(struct tevent_req *subreq);
|
|
|
2fc102 |
static void ad_enumeration_master_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static errno_t ad_enum_sdom(struct tevent_req *req, struct sdap_domain *sd,
|
|
|
2fc102 |
+ struct ad_id_ctx *id_ctx);
|
|
|
2fc102 |
static void ad_enumeration_done(struct tevent_req *subreq);
|
|
|
2fc102 |
|
|
|
2fc102 |
struct tevent_req *
|
|
|
2fc102 |
@@ -452,6 +455,7 @@ ad_enumeration_send(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
state->ectx = ectx;
|
|
|
2fc102 |
state->ev = ev;
|
|
|
2fc102 |
state->sdom = ectx->sdom;
|
|
|
2fc102 |
+ state->sditer = state->sdom;
|
|
|
2fc102 |
state->id_ctx = talloc_get_type(ectx->pvt, struct ad_id_ctx);
|
|
|
2fc102 |
|
|
|
2fc102 |
state->sdap_op = sdap_id_op_create(state,
|
|
|
2fc102 |
@@ -526,7 +530,6 @@ ad_enumeration_master_done(struct tevent_req *subreq)
|
|
|
2fc102 |
char *flat_name;
|
|
|
2fc102 |
char *master_sid;
|
|
|
2fc102 |
char *forest;
|
|
|
2fc102 |
- struct sdap_id_conn_ctx *user_conn;
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = ad_master_domain_recv(subreq, state,
|
|
|
2fc102 |
&flat_name, &master_sid, &forest);
|
|
|
2fc102 |
@@ -545,32 +548,57 @@ ad_enumeration_master_done(struct tevent_req *subreq)
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
- if (dp_opt_get_bool(state->id_ctx->ad_options->basic, AD_ENABLE_GC)) {
|
|
|
2fc102 |
- user_conn = state->id_ctx->gc_ctx;
|
|
|
2fc102 |
+ ret = ad_enum_sdom(req, state->sdom, state->id_ctx);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("Could not enumerate domain %s\n", state->sdom->dom->name));
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Execution will resume in ad_enumeration_done */
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_enum_sdom(struct tevent_req *req,
|
|
|
2fc102 |
+ struct sdap_domain *sd,
|
|
|
2fc102 |
+ struct ad_id_ctx *id_ctx)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct sdap_id_conn_ctx *user_conn;
|
|
|
2fc102 |
+ struct tevent_req *subreq;
|
|
|
2fc102 |
+ struct ad_enumeration_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct ad_enumeration_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (dp_opt_get_bool(id_ctx->ad_options->basic, AD_ENABLE_GC)) {
|
|
|
2fc102 |
+ user_conn = id_ctx->gc_ctx;
|
|
|
2fc102 |
} else {
|
|
|
2fc102 |
- user_conn = state->id_ctx->ldap_ctx;
|
|
|
2fc102 |
+ user_conn = id_ctx->ldap_ctx;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
/* Groups are searched for in LDAP, users in GC. Services (if present,
|
|
|
2fc102 |
* which is unlikely in AD) from LDAP as well
|
|
|
2fc102 |
*/
|
|
|
2fc102 |
subreq = sdap_dom_enum_ex_send(state, state->ev,
|
|
|
2fc102 |
- state->id_ctx->sdap_id_ctx,
|
|
|
2fc102 |
- state->sdom,
|
|
|
2fc102 |
- user_conn, /* Users */
|
|
|
2fc102 |
- state->id_ctx->ldap_ctx, /* Groups */
|
|
|
2fc102 |
- state->id_ctx->ldap_ctx); /* Services */
|
|
|
2fc102 |
+ id_ctx->sdap_id_ctx,
|
|
|
2fc102 |
+ sd,
|
|
|
2fc102 |
+ user_conn, /* Users */
|
|
|
2fc102 |
+ id_ctx->ldap_ctx, /* Groups */
|
|
|
2fc102 |
+ id_ctx->ldap_ctx); /* Services */
|
|
|
2fc102 |
if (subreq == NULL) {
|
|
|
2fc102 |
/* The ptask API will reschedule the enumeration on its own on
|
|
|
2fc102 |
* failure */
|
|
|
2fc102 |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
("Failed to schedule enumeration, retrying later!\n"));
|
|
|
2fc102 |
- tevent_req_error(req, ENOMEM);
|
|
|
2fc102 |
- return;
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
tevent_req_set_callback(subreq, ad_enumeration_done, req);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+static errno_t ad_enum_cross_dom_members(struct sdap_options *opts,
|
|
|
2fc102 |
+ struct sss_domain_info *dom);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
static void
|
|
|
2fc102 |
ad_enumeration_done(struct tevent_req *subreq)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
@@ -579,6 +607,7 @@ ad_enumeration_done(struct tevent_req *subreq)
|
|
|
2fc102 |
struct tevent_req);
|
|
|
2fc102 |
struct ad_enumeration_state *state = tevent_req_data(req,
|
|
|
2fc102 |
struct ad_enumeration_state);
|
|
|
2fc102 |
+ struct ad_id_ctx *subdom_id_ctx;
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = sdap_dom_enum_ex_recv(subreq);
|
|
|
2fc102 |
talloc_zfree(subreq);
|
|
|
2fc102 |
@@ -589,9 +618,348 @@ ad_enumeration_done(struct tevent_req *subreq)
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+ state->sditer = state->sditer->next;
|
|
|
2fc102 |
+ if (state->sditer != NULL) {
|
|
|
2fc102 |
+ subdom_id_ctx = talloc_get_type(state->sdom->pvt, struct ad_id_ctx);
|
|
|
2fc102 |
+ if (subdom_id_ctx == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot retrieve subdomain ad_id_ctx!\n"));
|
|
|
2fc102 |
+ tevent_req_error(req, EFAULT);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = ad_enum_sdom(req, state->sditer, state->sditer->pvt);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not enumerate domain %s\n",
|
|
|
2fc102 |
+ state->sditer->dom->name));
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Execution will resume in ad_enumeration_done */
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* No more subdomains to enumerate. Check if we need to fixup
|
|
|
2fc102 |
+ * cross-domain membership
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (state->sditer != state->sdom) {
|
|
|
2fc102 |
+ /* We did enumerate at least one subdomain. Walk the subdomains
|
|
|
2fc102 |
+ * and fixup members for each of them
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ for (state->sditer = state->sdom;
|
|
|
2fc102 |
+ state->sditer;
|
|
|
2fc102 |
+ state->sditer = state->sditer->next) {
|
|
|
2fc102 |
+ ret = ad_enum_cross_dom_members(state->id_ctx->ad_options->id,
|
|
|
2fc102 |
+ state->sditer->dom);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Could not check cross-domain "
|
|
|
2fc102 |
+ "memberships for %s, group memberships might be "
|
|
|
2fc102 |
+ "incomplete!\n", state->sdom->dom->name));
|
|
|
2fc102 |
+ continue;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
tevent_req_done(req);
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+static errno_t ad_group_extra_members(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
+ const struct ldb_message *group,
|
|
|
2fc102 |
+ struct sss_domain_info *dom,
|
|
|
2fc102 |
+ char ***_group_only);
|
|
|
2fc102 |
+static errno_t ad_group_add_member(struct sdap_options *opts,
|
|
|
2fc102 |
+ struct sss_domain_info *group_domain,
|
|
|
2fc102 |
+ struct ldb_dn *group_dn,
|
|
|
2fc102 |
+ const char *member);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_enum_cross_dom_members(struct sdap_options *opts,
|
|
|
2fc102 |
+ struct sss_domain_info *dom)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ errno_t sret;
|
|
|
2fc102 |
+ char *filter;
|
|
|
2fc102 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
2fc102 |
+ const char *attrs[] = {
|
|
|
2fc102 |
+ SYSDB_NAME,
|
|
|
2fc102 |
+ SYSDB_MEMBER,
|
|
|
2fc102 |
+ SYSDB_ORIG_MEMBER,
|
|
|
2fc102 |
+ NULL
|
|
|
2fc102 |
+ };
|
|
|
2fc102 |
+ size_t count, i, mi;
|
|
|
2fc102 |
+ struct ldb_message **msgs;
|
|
|
2fc102 |
+ bool in_transaction = false;
|
|
|
2fc102 |
+ char **group_only;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
2fc102 |
+ if (tmp_ctx == NULL) return ENOMEM;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sysdb_transaction_start(dom->sysdb);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ in_transaction = true;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ filter = talloc_asprintf(tmp_ctx, "(%s=*)", SYSDB_NAME);
|
|
|
2fc102 |
+ if (filter == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sysdb_search_groups(tmp_ctx, dom->sysdb, dom,
|
|
|
2fc102 |
+ filter, attrs, &count, &msgs);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ for (i = 0; i < count; i++) {
|
|
|
2fc102 |
+ ret = ad_group_extra_members(tmp_ctx, msgs[i], dom, &group_only);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Failed to check extra members\n"));
|
|
|
2fc102 |
+ } else if (group_only == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("No extra members\n"));
|
|
|
2fc102 |
+ continue;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Group has extra members */
|
|
|
2fc102 |
+ for (mi = 0; group_only[mi]; mi++) {
|
|
|
2fc102 |
+ ret = ad_group_add_member(opts, dom, msgs[i]->dn, group_only[mi]);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add [%s]: %s\n",
|
|
|
2fc102 |
+ group_only[mi], strerror(ret)));
|
|
|
2fc102 |
+ continue;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ talloc_zfree(group_only);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sysdb_transaction_commit(dom->sysdb);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ in_transaction = false;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+done:
|
|
|
2fc102 |
+ if (in_transaction) {
|
|
|
2fc102 |
+ sret = sysdb_transaction_cancel(dom->sysdb);
|
|
|
2fc102 |
+ if (sret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ talloc_free(tmp_ctx);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_group_stored_orig_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
|
|
|
2fc102 |
+ struct ldb_dn *dn, char ***_odn_list);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_group_extra_members(TALLOC_CTX *mem_ctx, const struct ldb_message *group,
|
|
|
2fc102 |
+ struct sss_domain_info *dom, char ***_group_only)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
2fc102 |
+ struct ldb_message_element *m, *om;
|
|
|
2fc102 |
+ const char *name;
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ char **sysdb_odn_list;
|
|
|
2fc102 |
+ const char **group_odn_list;
|
|
|
2fc102 |
+ char **group_only = NULL;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (_group_only == NULL) return EINVAL;
|
|
|
2fc102 |
+ *_group_only = NULL;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
2fc102 |
+ if (tmp_ctx == NULL) return ENOMEM;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ om = ldb_msg_find_element(group, SYSDB_ORIG_MEMBER);
|
|
|
2fc102 |
+ m = ldb_msg_find_element(group, SYSDB_MEMBER);
|
|
|
2fc102 |
+ name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL);
|
|
|
2fc102 |
+ if (name == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("A group with no name!\n"));
|
|
|
2fc102 |
+ ret = EFAULT;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (om == NULL || om->num_values == 0) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_FUNC, ("Group %s has no original members\n", name));
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (m == NULL || (m->num_values < om->num_values)) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
2fc102 |
+ ("Group %s has %d members but %d original members\n",
|
|
|
2fc102 |
+ name, m ? m->num_values : 0, om->num_values));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Get the list of originalDN attributes that are already
|
|
|
2fc102 |
+ * linked to the group
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ ret = ad_group_stored_orig_members(tmp_ctx, dom, group->dn,
|
|
|
2fc102 |
+ &sysdb_odn_list);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("Could not retrieve list of original members for %s\n",
|
|
|
2fc102 |
+ name));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Get the list of original DN attributes the group had in AD */
|
|
|
2fc102 |
+ group_odn_list = sss_ldb_el_to_string_list(tmp_ctx, om);
|
|
|
2fc102 |
+ if (group_odn_list == NULL) {
|
|
|
2fc102 |
+ ret = EFAULT;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Compare the two lists */
|
|
|
2fc102 |
+ ret = diff_string_lists(tmp_ctx, discard_const(group_odn_list),
|
|
|
2fc102 |
+ sysdb_odn_list, &group_only, NULL, NULL);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("Could not compare lists of members for %s\n", name));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+ *_group_only = talloc_steal(mem_ctx, group_only);
|
|
|
2fc102 |
+done:
|
|
|
2fc102 |
+ talloc_free(tmp_ctx);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_group_stored_orig_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
|
|
|
2fc102 |
+ struct ldb_dn *dn, char ***_odn_list)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
2fc102 |
+ size_t m_count, i;
|
|
|
2fc102 |
+ struct ldb_message **members;
|
|
|
2fc102 |
+ const char *attrs[] = {
|
|
|
2fc102 |
+ SYSDB_NAME,
|
|
|
2fc102 |
+ SYSDB_ORIG_DN,
|
|
|
2fc102 |
+ NULL
|
|
|
2fc102 |
+ };
|
|
|
2fc102 |
+ char **odn_list;
|
|
|
2fc102 |
+ const char *odn;
|
|
|
2fc102 |
+ size_t oi;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
2fc102 |
+ if (tmp_ctx == NULL) return ENOMEM;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Get all entries member element points to */
|
|
|
2fc102 |
+ ret = sysdb_asq_search(tmp_ctx, dom->sysdb, dn, NULL, SYSDB_MEMBER,
|
|
|
2fc102 |
+ attrs, &m_count, &members);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ odn_list = talloc_zero_array(tmp_ctx, char *, m_count + 1);
|
|
|
2fc102 |
+ if (odn_list == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Get a list of their original DNs */
|
|
|
2fc102 |
+ oi = 0;
|
|
|
2fc102 |
+ for (i = 0; i < m_count; i++) {
|
|
|
2fc102 |
+ odn = ldb_msg_find_attr_as_string(members[i], SYSDB_ORIG_DN, NULL);
|
|
|
2fc102 |
+ if (odn == NULL) {
|
|
|
2fc102 |
+ continue;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ odn_list[oi] = talloc_strdup(odn_list, odn);
|
|
|
2fc102 |
+ if (odn_list[oi] == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ oi++;
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Member %s already in sysdb\n", odn));
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+ *_odn_list = talloc_steal(mem_ctx, odn_list);
|
|
|
2fc102 |
+done:
|
|
|
2fc102 |
+ talloc_free(tmp_ctx);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
+ad_group_add_member(struct sdap_options *opts,
|
|
|
2fc102 |
+ struct sss_domain_info *group_domain,
|
|
|
2fc102 |
+ struct ldb_dn *group_dn,
|
|
|
2fc102 |
+ const char *member)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct sdap_domain *sd;
|
|
|
2fc102 |
+ struct ldb_dn *base_dn;
|
|
|
2fc102 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ const char *mem_filter;
|
|
|
2fc102 |
+ size_t msgs_count;
|
|
|
2fc102 |
+ struct ldb_message **msgs;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* This member would be from a different domain */
|
|
|
2fc102 |
+ sd = sdap_domain_get_by_dn(opts, member);
|
|
|
2fc102 |
+ if (sd == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_MINOR_FAILURE, ("No matching domain for %s\n", member));
|
|
|
2fc102 |
+ return ENOENT;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
2fc102 |
+ if (tmp_ctx == NULL) return ENOMEM;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ mem_filter = talloc_asprintf(tmp_ctx, "(%s=%s)",
|
|
|
2fc102 |
+ SYSDB_ORIG_DN, member);
|
|
|
2fc102 |
+ if (mem_filter == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ base_dn = sysdb_domain_dn(sd->dom->sysdb, tmp_ctx, sd->dom);
|
|
|
2fc102 |
+ if (base_dn == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sysdb_search_entry(tmp_ctx, sd->dom->sysdb, base_dn,
|
|
|
2fc102 |
+ LDB_SCOPE_SUBTREE, mem_filter, NULL,
|
|
|
2fc102 |
+ &msgs_count, &msgs);
|
|
|
2fc102 |
+ if (ret == ENOENT) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_FUNC, ("No member [%s] in sysdb\n", member));
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ } else if (ret != EOK) {
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("[%s] found in sysdb\n", member));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (msgs_count != 1) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
2fc102 |
+ ("Search by orig DN returned %zd results!\n", msgs_count));
|
|
|
2fc102 |
+ ret = EFAULT;
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sysdb_mod_group_member(group_domain->sysdb, msgs[0]->dn,
|
|
|
2fc102 |
+ group_dn, SYSDB_MOD_ADD);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add [%s] as a member of [%s]\n",
|
|
|
2fc102 |
+ ldb_dn_get_linearized(msgs[0]->dn),
|
|
|
2fc102 |
+ ldb_dn_get_linearized(group_dn)));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = EOK;
|
|
|
2fc102 |
+done:
|
|
|
2fc102 |
+ talloc_free(tmp_ctx);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
errno_t
|
|
|
2fc102 |
ad_enumeration_recv(struct tevent_req *req)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
index e7871cc32407893948fe1b2803258d68c70889c1..0d9652b5c615add47958cfdc61eba862a332ae4d 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
@@ -177,17 +177,6 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
|
|
|
2fc102 |
return EFAULT;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
- ret = sdap_id_setup_tasks(be_ctx,
|
|
|
2fc102 |
- ad_id_ctx->sdap_id_ctx,
|
|
|
2fc102 |
- sdom,
|
|
|
2fc102 |
- ldap_enumeration_send,
|
|
|
2fc102 |
- ldap_enumeration_recv,
|
|
|
2fc102 |
- ad_id_ctx->sdap_id_ctx);
|
|
|
2fc102 |
- if (ret != EOK) {
|
|
|
2fc102 |
- talloc_free(ad_options);
|
|
|
2fc102 |
- return ret;
|
|
|
2fc102 |
- }
|
|
|
2fc102 |
-
|
|
|
2fc102 |
/* Set up the ID mapping object */
|
|
|
2fc102 |
ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
|
|
|
2fc102 |
id_ctx->sdap_id_ctx->opts->idmap_ctx;
|
|
|
2fc102 |
--
|
|
|
2fc102 |
1.8.4.2
|
|
|
2fc102 |
|