diff options
-rw-r--r-- | src/providers/ldap/sdap_async.h | 7 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups.c | 44 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups_ad.c | 136 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_private.h | 1 |
4 files changed, 133 insertions, 55 deletions
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index af41c719..3b6aaee6 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -286,10 +286,13 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx, struct sdap_handle *sh, const char *name, const char *orig_dn, - int timeout); + int timeout, + bool use_id_mapping); errno_t -sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req); +sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req, + bool *_lookup_sids, + char ***_group_sid_list); errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c index e3539e91..a926dc72 100644 --- a/src/providers/ldap/sdap_async_initgroups.c +++ b/src/providers/ldap/sdap_async_initgroups.c @@ -2571,6 +2571,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, state->name = name; state->grp_attrs = grp_attrs; state->orig_user = NULL; + state->cname = NULL; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->user_base_iter = 0; state->user_search_bases = sdom->user_search_bases; @@ -2665,7 +2666,6 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) int ret; errno_t sret; const char *orig_dn; - const char *cname; bool in_transaction = false; DEBUG(9, ("Receiving info for the user\n")); @@ -2738,7 +2738,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) in_transaction = false; ret = sysdb_get_real_name(state, state->sysdb, - state->dom, state->name, &cname); + state->dom, state->name, &state->cname); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Cannot canonicalize username\n")); tevent_req_error(req, ret); @@ -2751,7 +2751,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) case SDAP_SCHEMA_RFC2307: subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts, state->sysdb, state->dom, state->sh, - cname); + state->cname); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -2769,8 +2769,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) return; } - if (state->use_id_mapping - && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) { + if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) { /* Take advantage of AD's tokenGroups mechanism to look up all * parent groups in a single request. */ @@ -2779,8 +2778,10 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) state->sysdb, state->dom, state->sh, - cname, orig_dn, - state->timeout); + state->cname, + orig_dn, + state->timeout, + state->use_id_mapping); } else if (state->opts->support_matching_rule && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_INITGROUPS)) { @@ -2792,13 +2793,17 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) state->sysdb, state->dom, state->sh, - cname, orig_dn, + state->cname, + orig_dn, state->timeout); } else { - subreq = sdap_initgr_rfc2307bis_send( - state, state->ev, state->opts, state->sysdb, - state->dom, state->sh, - cname, orig_dn); + subreq = sdap_initgr_rfc2307bis_send(state, state->ev, + state->opts, + state->sysdb, + state->dom, + state->sh, + state->cname, + orig_dn); } if (!subreq) { tevent_req_error(req, ENOMEM); @@ -2852,7 +2857,8 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) char *group_sid_str; struct sdap_options *opts = state->opts; - DEBUG(9, ("Initgroups done\n")); + char **group_sid_list; + bool lookup_sids = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { @@ -2867,9 +2873,8 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) case SDAP_SCHEMA_RFC2307BIS: case SDAP_SCHEMA_AD: - if (state->use_id_mapping - && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) { - ret = sdap_get_ad_tokengroups_initgroups_recv(subreq); + 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, @@ -2890,6 +2895,13 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) break; } + if (lookup_sids) { + DEBUG(SSSDBG_TRACE_FUNC, ("Some of users TokenGroups not found in " + "cache, will perform LDAP lookup.\n")); + } + + DEBUG(9, ("Initgroups done\n")); + talloc_zfree(subreq); if (ret) { DEBUG(9, ("Error in initgroups: [%d][%s]\n", diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c index e5649a2b..8fc56c0e 100644 --- a/src/providers/ldap/sdap_async_initgroups_ad.c +++ b/src/providers/ldap/sdap_async_initgroups_ad.c @@ -305,6 +305,9 @@ struct sdap_ad_tokengroups_initgr_state { struct sss_domain_info *domain; struct sdap_handle *sh; const char *username; + bool use_id_mapping; + bool lookup_sids; + char **group_sid_list; }; static void @@ -319,7 +322,8 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx, struct sdap_handle *sh, const char *name, const char *orig_dn, - int timeout) + int timeout, + bool use_id_mapping) { struct tevent_req *req; struct tevent_req *subreq; @@ -336,6 +340,9 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx, state->domain = domain; state->sh = sh; state->username = name; + state->use_id_mapping = use_id_mapping; + state->lookup_sids = false; + state->group_sid_list = NULL; subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, @@ -359,6 +366,7 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq) errno_t ret, sret; enum idmap_error_code err; size_t user_count, group_count, i; + size_t sid_count = 0; TALLOC_CTX *tmp_ctx; bool in_transaction = false; char *sid_str; @@ -442,6 +450,14 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq) } group_count = 0; + if (!state->use_id_mapping) { + state->group_sid_list = talloc_array(state, char*, el->num_values + 1); + if (!state->group_sid_list) { + ret = ENOMEM; + goto done; + } + } + for (i = 0; i < el->num_values; i++) { /* Get the SID and convert it to a GID */ @@ -464,20 +480,29 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq) DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n")); ret = EOK; continue; - } else if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - ("Could not convert SID to GID: [%s]. Skipping\n", - strerror(ret))); - continue; } - DEBUG(SSSDBG_TRACE_LIBS, - ("Processing membership GID [%lu]\n", - gid)); + if (state->use_id_mapping) { + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not convert SID to GID: [%s]. Skipping\n", + strerror(ret))); + continue; + } + + DEBUG(SSSDBG_TRACE_LIBS, + ("Processing membership GID [%lu]\n", + gid)); + + /* Check whether this GID already exists in the sysdb */ + ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain, + gid, attrs, &msg); + } else { + ret = sysdb_search_group_by_sid_str(tmp_ctx, state->sysdb, + state->domain, sid_str, attrs, + &msg); + } - /* Check whether this GID already exists in the sysdb */ - ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain, - gid, attrs, &msg); if (ret == EOK) { group_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (!group_name) { @@ -486,23 +511,59 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq) ret = EINVAL; goto done; } - } else if (ret == ENOENT) { - /* This is a new group. For now, we will store it - * under the name of its SID. When a direct lookup of - * the group or its GID occurs, it will replace this - * temporary entry. - */ - group_name = sid_str; - ret = sysdb_add_incomplete_group(state->sysdb, - state->domain, - group_name, gid, - NULL, sid_str, false, now); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - ("Could not create incomplete group: [%s]\n", - strerror(ret))); + + ldap_grouplist[group_count] = + talloc_strdup(ldap_grouplist, group_name); + if (!ldap_grouplist[group_count]) { + ret = ENOMEM; goto done; } + + group_count++; + + } else if (ret == ENOENT) { + if (state->use_id_mapping) { + /* This is a new group. For now, we will store it + * under the name of its SID. When a direct lookup of + * the group or its GID occurs, it will replace this + * temporary entry. + */ + group_name = sid_str; + ret = sysdb_add_incomplete_group(state->sysdb, + state->domain, + group_name, gid, + NULL, sid_str, false, now); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not create incomplete group: [%s]\n", + strerror(ret))); + goto done; + } + + ldap_grouplist[group_count] = + talloc_strdup(ldap_grouplist, group_name); + if (!ldap_grouplist[group_count]) { + ret = ENOMEM; + goto done; + } + + group_count++; + + } else { + DEBUG(SSSDBG_MINOR_FAILURE, ("SID [%s] not found in cache, " + "will be looked up\n", sid_str)); + + state->lookup_sids = true; + + state->group_sid_list[sid_count] = + talloc_strdup(state, sid_str); + if (!state->group_sid_list[sid_count]) { + ret = ENOMEM; + goto done; + } + + sid_count++; + } } else { /* Unexpected error */ DEBUG(SSSDBG_MINOR_FAILURE, @@ -510,17 +571,9 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq) strerror(ret))); goto done; } - - ldap_grouplist[group_count] = - talloc_strdup(ldap_grouplist, group_name); - if (!ldap_grouplist[group_count]) { - ret = ENOMEM; - goto done; - } - - group_count++; } ldap_grouplist[group_count] = NULL; + state->group_sid_list[sid_count] = NULL; /* Get the current sysdb group list for this user * so we can update it. @@ -582,8 +635,17 @@ done: } errno_t -sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req) +sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req, + bool *_lookup_sids, + char ***_group_sid_list) { + struct sdap_ad_tokengroups_initgr_state *state = + tevent_req_data(req, struct sdap_ad_tokengroups_initgr_state); + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_lookup_sids = state->lookup_sids; + *_group_sid_list = state->group_sid_list; + return EOK; } diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h index 4d0b8652..27b8e365 100644 --- a/src/providers/ldap/sdap_async_private.h +++ b/src/providers/ldap/sdap_async_private.h @@ -44,6 +44,7 @@ struct sdap_get_initgr_state { struct sdap_id_ctx *id_ctx; struct sdap_id_conn_ctx *conn; const char *name; + const char *cname; const char **grp_attrs; const char **user_attrs; const char *user_base_filter; |