summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Kos <okos@redhat.com>2013-09-11 13:13:24 +0200
committerOndrej Kos <okos@redhat.com>2013-09-11 18:51:27 +0200
commitfbdd240344e41d6182792c7545842ef9c6ce0d86 (patch)
tree0628637afdc9a47e0d0e2f62180825fa7e4683c0
parentca4ecd772482c4c49186ba50c3de511f453a7344 (diff)
downloadsssd-token4.tar.gz
sssd-token4.tar.xz
sssd-token4.zip
AD: Add lookup for SIDs not found in cache during TokenGroupstoken4
Explanation Resolves: https://fedorahosted.org/sssd/ticket/XXXX
-rw-r--r--src/providers/ldap/sdap_async.h14
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c37
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c283
-rw-r--r--src/providers/ldap/sdap_async_private.h1
4 files changed, 333 insertions, 2 deletions
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 0c682992..2e461ac9 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -294,6 +294,20 @@ sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req,
bool *_lookup_sids,
const char ***_group_sid_list);
+struct tevent_req *
+sdap_get_ad_token_initgr_sidlookup_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ struct sdap_handle *sh,
+ const char *name,
+ const char *orig_dn,
+ const char **group_sid_list);
+
+errno_t
+sdap_get_ad_token_initgr_sidlookup_recv(struct tevent_req *req);
+
errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
struct sdap_options *opts,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 7bc6f1a5..ed795547 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2574,6 +2574,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
state->cname = NULL;
state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
state->user_base_iter = 0;
+ state->sids_looked_up = false;
state->user_search_bases = sdom->user_search_bases;
if (!state->user_search_bases) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -2856,6 +2857,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
char *dom_sid_str;
char *group_sid_str;
struct sdap_options *opts = state->opts;
+ const char *orig_dn;
const char **group_sid_list;
bool lookup_sids = false;
@@ -2872,8 +2874,12 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
case SDAP_SCHEMA_RFC2307BIS:
case SDAP_SCHEMA_AD:
- if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
- ret = sdap_get_ad_tokengroups_initgroups_recv(subreq, &lookup_sids, &group_sid_list);
+ if (state->sids_looked_up) {
+ ret = sdap_get_ad_token_initgr_sidlookup_recv(subreq);
+ } else if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
+ ret = sdap_get_ad_tokengroups_initgroups_recv(subreq,
+ &lookup_sids,
+ &group_sid_list);
}
else if (state->opts->support_matching_rule
&& dp_opt_get_bool(state->opts->basic,
@@ -2897,6 +2903,33 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
if (lookup_sids) {
DEBUG(SSSDBG_TRACE_FUNC, ("Some of users TokenGroups not found in "
"cache, will perform LDAP lookup.\n"));
+
+ ret = sysdb_attrs_get_string(state->orig_user,
+ SYSDB_ORIG_DN,
+ &orig_dn);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = sdap_get_ad_token_initgr_sidlookup_send(state, state->ev,
+ state->opts,
+ state->sysdb,
+ state->dom,
+ state->sh,
+ state->cname,
+ orig_dn,
+ group_sid_list);
+
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ state->sids_looked_up = true;
+
+ tevent_req_set_callback(subreq, sdap_get_initgr_done, req);
+ return;
}
DEBUG(9, ("Initgroups done\n"));
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index 723b009c..a781a6ed 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -3,6 +3,7 @@
Authors:
Stephen Gallagher <sgallagh@redhat.com>
+ Ondrej Kos <okos@redhat.com>
Copyright (C) 2012 Red Hat
@@ -649,3 +650,285 @@ sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req,
return EOK;
}
+
+struct sdap_ad_token_initgr_sidlookup_state {
+ struct tevent_context *ev;
+ struct sdap_options *opts;
+ struct sysdb_ctx *sysdb;
+ struct sss_domain_info *domain;
+ struct sdap_handle *sh;
+ struct sdap_search_base **search_bases;
+ struct sysdb_attrs **ldap_groups;
+ const char **attrs;
+ const char *username;
+ const char *base_filter;
+ size_t ldap_groups_count;
+ size_t base_iter;
+ char *filter;
+ int timeout;
+};
+
+static void
+sdap_get_ad_token_initgr_sidlookup_process(struct tevent_req *subreq);
+
+static errno_t sdap_get_ad_token_initgr_sidlookup_next_base(struct tevent_req *req);
+
+struct tevent_req *
+sdap_get_ad_token_initgr_sidlookup_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ struct sdap_handle *sh,
+ const char *name,
+ const char *orig_dn,
+ const char **group_sid_list)
+{
+ errno_t ret;
+ int i;
+ struct tevent_req *req;
+ struct sdap_ad_token_initgr_sidlookup_state *state;
+ const char **filter_members;
+ char *clean_orig_dn;
+ char *sid_filter = NULL;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct sdap_ad_token_initgr_sidlookup_state);
+ if (!req) return NULL;
+
+ state->ev = ev;
+ state->opts = opts;
+ state->sysdb = sysdb;
+ state->domain = domain;
+ state->sh = sh;
+ state->search_bases = opts->sdom->group_search_bases;
+ state->ldap_groups = NULL;
+ state->username = name;
+ state->ldap_groups_count = 0;
+ state->base_iter = 0;
+ state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
+
+ filter_members = talloc_array(state, const char *, 2);
+ if (!filter_members) {
+ ret = ENOMEM;
+ goto done;
+ }
+ filter_members[0] = opts->group_map[SDAP_AT_GROUP_MEMBER].name;
+ filter_members[1] = NULL;
+
+ ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP,
+ filter_members, &state->attrs, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Could not build attribute map: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
+ if (ret != EOK) goto done;
+
+ i = 0;
+ while (group_sid_list[i]) {
+ sid_filter = talloc_asprintf(state, "%s(%s=%s)",
+ sid_filter ? sid_filter : "",
+ opts->group_map[SDAP_AT_GROUP_OBJECTSID].name,
+ group_sid_list[i]);
+ i++;
+ }
+
+ state->base_filter =
+ talloc_asprintf(state, "(&(objectclass=%s)(|%s)(!(%s=0)))",
+ opts->group_map[SDAP_OC_GROUP].name,
+ sid_filter,
+ opts->group_map[SDAP_AT_GROUP_GID].name);
+ if (!state->base_filter) {
+ ret = ENOMEM;
+ goto done;
+ }
+ talloc_zfree(clean_orig_dn);
+
+ ret = sdap_get_ad_token_initgr_sidlookup_next_base(req);
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ }
+
+ return req;
+}
+
+static errno_t sdap_get_ad_token_initgr_sidlookup_next_base(struct tevent_req *req)
+{
+ struct tevent_req *subreq;
+ struct sdap_ad_token_initgr_sidlookup_state *state;
+
+ state = tevent_req_data(req, struct sdap_ad_token_initgr_sidlookup_state);
+
+ talloc_zfree(state->filter);
+
+ state->filter = sdap_get_id_specific_filter(
+ state,
+ state->base_filter,
+ state->search_bases[state->base_iter]->filter);
+ if (!state->filter) {
+ return ENOMEM;
+ }
+
+ subreq = sdap_get_generic_send(
+ state, state->ev, state->opts, state->sh,
+ state->search_bases[state->base_iter]->basedn,
+ state->search_bases[state->base_iter]->scope,
+ state->filter, state->attrs,
+ state->opts->group_map, SDAP_OPTS_GROUP,
+ state->timeout,
+ true);
+ if (!subreq) {
+ talloc_zfree(req);
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq,
+ sdap_get_ad_token_initgr_sidlookup_process,
+ req);
+
+ return EOK;
+}
+
+static void sdap_get_ad_token_initgr_sidlookup_process(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq, struct tevent_req);
+ struct sdap_ad_token_initgr_sidlookup_state *state =
+ tevent_req_data(req, struct sdap_ad_token_initgr_sidlookup_state);
+ struct sysdb_attrs **ldap_groups;
+ char **groupnames = NULL;
+ bool in_transaction = false;
+ size_t count;
+ size_t i;
+ errno_t ret, tret;
+
+ ret = sdap_get_generic_recv(subreq, state, &count, &ldap_groups);
+
+ talloc_zfree(subreq);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ DEBUG(SSSDBG_TRACE_LIBS, ("Found %d parent groups for user [%s]\n",
+ count, state->username));
+
+ /* Add this batch of groups to the list */
+ if (count > 0) {
+ state->ldap_groups =
+ talloc_realloc(state,
+ state->ldap_groups,
+ struct sysdb_attrs *,
+ state->ldap_groups_count + count + 1);
+ if (!state->ldap_groups) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* Copy the new groups into the list.
+ */
+ for (i = 0; i < count; i++) {
+ state->ldap_groups[state->ldap_groups_count + i] =
+ talloc_steal(state->ldap_groups, ldap_groups[i]);
+ }
+
+ state->ldap_groups_count += count;
+
+ state->ldap_groups[state->ldap_groups_count] = NULL;
+ }
+
+ state->base_iter++;
+
+ /* Check for additional search bases, and iterate
+ * through again.
+ */
+ if (state->search_bases[state->base_iter] != NULL) {
+ ret = sdap_get_ad_token_initgr_sidlookup_next_base(req);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ if (state->ldap_groups_count > 0) {
+ ret = sysdb_attrs_primary_name_list(
+ state->sysdb,
+ state,
+ state->ldap_groups,
+ state->ldap_groups_count,
+ state->opts->group_map[SDAP_AT_GROUP_NAME].name,
+ &groupnames);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ ret = sysdb_transaction_start(state->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
+ goto done;
+ }
+ in_transaction = true;
+
+ ret = sdap_add_incomplete_groups(state->sysdb,
+ state->domain,
+ state->opts,
+ groupnames,
+ state->ldap_groups,
+ state->ldap_groups_count);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("Could not add incomplete groups [%d]:%s\n",
+ ret, strerror(ret)));
+ goto done;
+ }
+
+ i = 0;
+ while (groupnames[i]) {
+ ret = sysdb_add_group_member(state->sysdb,
+ state->domain,
+ groupnames[i],
+ state->username,
+ SYSDB_MEMBER_USER);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Could not add member [%s] to group "
+ "[%s]. Skipping.\n",
+ state->username,
+ groupnames[i]));
+ }
+ i++;
+ }
+
+ ret = sysdb_transaction_commit(state->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
+ goto done;
+ }
+ in_transaction = false;
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Saving user groups done.\n"));
+
+done:
+ if (in_transaction) {
+ tret = sysdb_transaction_cancel(state->sysdb);
+ if (tret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to cancel transaction\n"));
+ }
+ }
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_done(req);
+}
+
+errno_t
+sdap_get_ad_token_initgr_sidlookup_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 27b8e365..1e882f5e 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -57,6 +57,7 @@ struct sdap_get_initgr_state {
struct sdap_search_base **user_search_bases;
bool use_id_mapping;
+ bool sids_looked_up;
};
bool is_dn(const char *str);