diff options
author | Ondrej Kos <okos@redhat.com> | 2013-09-11 13:13:24 +0200 |
---|---|---|
committer | Ondrej Kos <okos@redhat.com> | 2013-09-11 18:51:27 +0200 |
commit | fbdd240344e41d6182792c7545842ef9c6ce0d86 (patch) | |
tree | 0628637afdc9a47e0d0e2f62180825fa7e4683c0 | |
parent | ca4ecd772482c4c49186ba50c3de511f453a7344 (diff) | |
download | sssd-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.h | 14 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups.c | 37 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups_ad.c | 283 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_private.h | 1 |
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); |