diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 9dcba621f85..48c9b29cd73 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -65,6 +65,7 @@ #define SYSDB_DOMAIN_ID_RANGE_CLASS "domainIDRange" #define SYSDB_TRUSTED_AD_DOMAIN_RANGE_CLASS "TrustedADDomainRange" #define SYSDB_CERTMAP_CLASS "certificateMappingRule" +#define SYSDB_AD_FSP_CLASS "foreignSecurityPrincipal" #define SYSDB_DN "dn" #define SYSDB_NAME "name" diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c index fe352437893..03a04b0ae42 100644 --- a/src/providers/ad/ad_opts.c +++ b/src/providers/ad/ad_opts.c @@ -346,3 +346,18 @@ struct sdap_attr_map ad_sudorule_map[] = { { "ldap_sudorule_entry_usn", NULL, SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; + +enum ad_fsp_entry_attrs { + SDAP_OC_FSP = 0, + SDAP_AT_FSP_NAME, + SDAP_AT_FSP_OBJECTSID, + + SDAP_OPTS_FSP /* attrs counter */ +}; + +struct sdap_attr_map ad_fsp_map[] = { + { "ldap_fsp_object_class", "foreignSecurityPrincipal", SYSDB_AD_FSP_CLASS, NULL }, + { "ldap_fsp_name", "cn", SYSDB_NAME, NULL }, + { "ldap_fsp_objectsid", "objectSID", SYSDB_SID, NULL }, + SDAP_ATTR_MAP_TERMINATOR +}; diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 070818f8ac8..4cf401e6c37 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -1992,6 +1992,202 @@ static void generic_ext_search_handler(struct tevent_req *subreq, tevent_req_done(req); } +/* ==Generic Search exposing all options with multiple maps === */ +struct sdap_get_and_multi_parse_generic_state { + struct sdap_attr_map *map; + int map_num_attrs; + struct sdap_attr_map_info *maps; + size_t num_maps; + + struct sdap_reply sreply; + struct sdap_options *opts; +}; + +static void sdap_get_and_multi_parse_generic_done(struct tevent_req *subreq); +static errno_t +sdap_get_and_multi_parse_generic_parse_entry(struct sdap_handle *sh, + struct sdap_msg *msg, + void *pvt); + +struct tevent_req * +sdap_get_and_multi_parse_generic_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct sdap_options *opts, + struct sdap_handle *sh, + const char *search_base, + int scope, + const char *filter, + const char **attrs, + struct sdap_attr_map_info *maps, + size_t num_maps, + int attrsonly, + LDAPControl **serverctrls, + LDAPControl **clientctrls, + int sizelimit, + int timeout, + bool allow_paging) +{ + struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; + struct sdap_get_and_multi_parse_generic_state *state = NULL; + unsigned int flags = 0; + + req = tevent_req_create(memctx, &state, + struct sdap_get_and_multi_parse_generic_state); + if (!req) return NULL; + + state->maps = maps; + state->num_maps = num_maps; + state->opts = opts; + + if (allow_paging) { + flags |= SDAP_SRCH_FLG_PAGING; + } + + if (attrsonly) { + flags |= SDAP_SRCH_FLG_ATTRS_ONLY; + } + + subreq = sdap_get_generic_ext_send(state, ev, opts, sh, search_base, + scope, filter, attrs, serverctrls, + clientctrls, sizelimit, timeout, + sdap_get_and_multi_parse_generic_parse_entry, + state, flags); + if (!subreq) { + talloc_zfree(req); + return NULL; + } + tevent_req_set_callback(subreq, sdap_get_and_multi_parse_generic_done, req); + + return req; +} + +static errno_t +sdap_get_and_multi_parse_generic_parse_entry(struct sdap_handle *sh, + struct sdap_msg *msg, + void *pvt) +{ + errno_t ret; + struct sdap_get_and_multi_parse_generic_state *state = + talloc_get_type(pvt, struct sdap_get_and_multi_parse_generic_state); + struct berval **vals; + int i, mi; + struct sdap_attr_map *map; + int num_attrs = 0; + struct sysdb_attrs *attrs = NULL; + char *tmp; + char *dn = NULL; + TALLOC_CTX *tmp_ctx; + bool disable_range_rtrvl; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + tmp = ldap_get_dn(sh->ldap, msg->msg); + if (!tmp) { + ret = EINVAL; + goto done; + } + + dn = talloc_strdup(tmp_ctx, tmp); + ldap_memfree(tmp); + if (!dn) { + ret = ENOMEM; + goto done; + } + + /* Find all suitable maps in the list */ + vals = ldap_get_values_len(sh->ldap, msg->msg, "objectClass"); + if (!vals) { + DEBUG(SSSDBG_OP_FAILURE, + "Unknown entry type, no objectClass found for DN [%s]!\n", dn); + ret = EINVAL; + goto done; + } + for (mi =0; mi < state->num_maps; mi++) { + map = NULL; + for (i = 0; vals[i]; i++) { + /* the objectclass is always the first name in the map */ + if (strncasecmp(state->maps[mi].map[0].name, + vals[i]->bv_val, vals[i]->bv_len) == 0) { + /* it's an entry of the right type */ + DEBUG(SSSDBG_TRACE_INTERNAL, + "Matched objectclass [%s] on DN [%s], will use associated map\n", + state->maps[mi].map[0].name, dn); + map = state->maps[mi].map; + num_attrs = state->maps[mi].num_attrs; + break; + } + } + if (!map) { + DEBUG(SSSDBG_TRACE_INTERNAL, + "DN [%s] did not match the objectClass [%s]\n", + dn, state->maps[mi].map[0].name); + continue; + } + + disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, + SDAP_DISABLE_RANGE_RETRIEVAL); + + ret = sdap_parse_entry(state, sh, msg, + map, num_attrs, + &attrs, disable_range_rtrvl); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret)); + goto done; + } + ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, map[0].name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to add objectclass.\n"); + goto done; + } + + break; + } + ldap_value_free_len(vals); + + /* If some mapped entry was found, add to to the reply */ + if (attrs != NULL) { + ret = add_to_reply(state, &state->sreply, attrs); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "add_to_reply failed.\n"); + goto done; + } + } + + ret = EOK; +done: + talloc_zfree(tmp_ctx); + return ret; +} + +static void sdap_get_and_multi_parse_generic_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sdap_get_and_multi_parse_generic_state *state = tevent_req_data(req, + struct sdap_get_and_multi_parse_generic_state); + + return generic_ext_search_handler(subreq, state->opts); +} + +int sdap_get_and_multi_parse_generic_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *reply_count, + struct sysdb_attrs ***reply) +{ + struct sdap_get_and_multi_parse_generic_state *state = tevent_req_data(req, + struct sdap_get_and_multi_parse_generic_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *reply_count = state->sreply.reply_count; + *reply = talloc_steal(mem_ctx, state->sreply.reply); + + return EOK; +} + /* ==Generic Search exposing all options======================= */ struct sdap_get_and_parse_generic_state { struct sdap_attr_map *map; diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 80b403bc3ca..996d8822062 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -260,6 +260,28 @@ int sdap_get_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply_list); +struct tevent_req * +sdap_get_and_multi_parse_generic_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct sdap_options *opts, + struct sdap_handle *sh, + const char *search_base, + int scope, + const char *filter, + const char **attrs, + struct sdap_attr_map_info *maps, + size_t num_maps, + int attrsonly, + LDAPControl **serverctrls, + LDAPControl **clientctrls, + int sizelimit, + int timeout, + bool allow_paging); +int sdap_get_and_multi_parse_generic_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *reply_count, + struct sysdb_attrs ***reply); + bool sdap_has_deref_support_ex(struct sdap_handle *sh, struct sdap_options *opts, bool ignore_client); diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c index 8a97c9db888..99ff4585f95 100644 --- a/src/providers/ldap/sdap_async_nested_groups.c +++ b/src/providers/ldap/sdap_async_nested_groups.c @@ -47,6 +47,7 @@ enum sdap_nested_group_dn_type { SDAP_NESTED_GROUP_DN_USER, SDAP_NESTED_GROUP_DN_GROUP, + SDAP_NESTED_GROUP_DN_FSP, SDAP_NESTED_GROUP_DN_UNKNOWN }; @@ -102,36 +103,31 @@ sdap_nested_group_single_send(TALLOC_CTX *mem_ctx, static errno_t sdap_nested_group_single_recv(struct tevent_req *req); static struct tevent_req * -sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, +sdap_nested_group_lookup_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member); -static errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_user); - -static struct tevent_req * -sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_nested_group_ctx *group_ctx, - struct sdap_nested_group_member *member); +struct sdap_nested_group_single_state { + struct tevent_context *ev; + struct sdap_nested_group_ctx *group_ctx; + struct sdap_nested_group_member *members; + int nesting_level; -static errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_group); + struct sdap_nested_group_member *current_member; + int num_members; + int member_index; -static struct tevent_req * -sdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_nested_group_ctx *group_ctx, - struct sdap_nested_group_member *member); + struct sysdb_attrs **nested_groups; + int num_groups; + bool ignore_unreadable_references; +}; static errno_t -sdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_entry, - enum sdap_nested_group_dn_type *_type); +sdap_nested_group_lookup_recv(struct sdap_nested_group_single_state *mem_ctx, + struct tevent_req *req, + struct sysdb_attrs **_entry, + enum sdap_nested_group_dn_type *_type); static struct tevent_req * sdap_nested_group_deref_send(TALLOC_CTX *mem_ctx, @@ -1339,21 +1335,6 @@ static errno_t sdap_nested_group_recurse_recv(struct tevent_req *req) return EOK; } -struct sdap_nested_group_single_state { - struct tevent_context *ev; - struct sdap_nested_group_ctx *group_ctx; - struct sdap_nested_group_member *members; - int nesting_level; - - struct sdap_nested_group_member *current_member; - int num_members; - int member_index; - - struct sysdb_attrs **nested_groups; - int num_groups; - bool ignore_unreadable_references; -}; - static errno_t sdap_nested_group_single_step(struct tevent_req *req); static void sdap_nested_group_single_step_done(struct tevent_req *subreq); static void sdap_nested_group_single_done(struct tevent_req *subreq); @@ -1484,23 +1465,9 @@ static errno_t sdap_nested_group_single_step(struct tevent_req *req) } } while (ignore); - switch (state->current_member->type) { - case SDAP_NESTED_GROUP_DN_USER: - subreq = sdap_nested_group_lookup_user_send(state, state->ev, - state->group_ctx, - state->current_member); - break; - case SDAP_NESTED_GROUP_DN_GROUP: - subreq = sdap_nested_group_lookup_group_send(state, state->ev, - state->group_ctx, - state->current_member); - break; - case SDAP_NESTED_GROUP_DN_UNKNOWN: - subreq = sdap_nested_group_lookup_unknown_send(state, state->ev, - state->group_ctx, - state->current_member); - break; - } + subreq = sdap_nested_group_lookup_member_send(state, state->ev, + state->group_ctx, + state->current_member); if (subreq == NULL) { return ENOMEM; @@ -1517,39 +1484,24 @@ sdap_nested_group_single_step_process(struct tevent_req *subreq) struct sdap_nested_group_single_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs *entry = NULL; - enum sdap_nested_group_dn_type type = SDAP_NESTED_GROUP_DN_UNKNOWN; const char *orig_dn = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_single_state); - /* set correct type if possible */ - if (state->current_member->type == SDAP_NESTED_GROUP_DN_UNKNOWN) { - ret = sdap_nested_group_lookup_unknown_recv(state, subreq, - &entry, &type); - if (ret != EOK) { - goto done; - } - - if (entry != NULL) { - state->current_member->type = type; - } + /* parse attributes and set correct type if possible */ + ret = sdap_nested_group_lookup_recv(state, subreq, + &entry, &state->current_member->type); + if (ret != EOK) { + goto done; } switch (state->current_member->type) { case SDAP_NESTED_GROUP_DN_USER: if (entry == NULL) { - /* type was not unknown, receive data */ - ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry); - if (ret != EOK) { - goto done; - } - - if (entry == NULL) { - /* user not found, continue */ - break; - } + /* user not found, continue */ + break; } /* The original DN of the user object itself might differ from the one @@ -1580,16 +1532,8 @@ sdap_nested_group_single_step_process(struct tevent_req *subreq) break; case SDAP_NESTED_GROUP_DN_GROUP: if (entry == NULL) { - /* type was not unknown, receive data */ - ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry); - if (ret != EOK) { - goto done; - } - - if (entry == NULL) { - /* group not found, continue */ - break; - } + /* group not found, continue */ + break; } else { /* the type was unknown so we had to pull the group, * but we don't want to process it if we have reached @@ -1626,6 +1570,15 @@ sdap_nested_group_single_step_process(struct tevent_req *subreq) state->num_groups++; break; + + case SDAP_NESTED_GROUP_DN_FSP: + /* TODO: handle Foreign Security Principal here + * since we don't know how to do it now, then we skip them for now */ + + DEBUG(SSSDBG_TRACE_FUNC, "Ignoring Foreign Security Principal reference [%s]\n", + state->current_member->dn); + break; + case SDAP_NESTED_GROUP_DN_UNKNOWN: if (state->ignore_unreadable_references) { DEBUG(SSSDBG_TRACE_FUNC, "Ignoring unreadable reference [%s]\n", @@ -1729,77 +1682,30 @@ static errno_t sdap_nested_group_single_recv(struct tevent_req *req) return EOK; } -static errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx, - const char *user_dn, - struct sysdb_ctx *sysdb, - struct sysdb_attrs **_user) -{ - TALLOC_CTX *tmp_ctx; - struct sysdb_attrs *user; - char *name; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - ret = ipa_get_rdn(tmp_ctx, sysdb, user_dn, &name, "uid", - "cn", "users", "cn", "accounts"); - if (ret != EOK) { - goto done; - } - - user = sysdb_new_attrs(tmp_ctx); - if (user == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_attrs_add_string(user, SYSDB_NAME, name); - if (ret != EOK) { - goto done; - } - - ret = sysdb_attrs_add_string(user, SYSDB_ORIG_DN, user_dn); - if (ret != EOK) { - goto done; - } - - ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS); - if (ret != EOK) { - goto done; - } - - *_user = talloc_steal(mem_ctx, user); - -done: - talloc_free(tmp_ctx); - return ret; -} - -struct sdap_nested_group_lookup_user_state { - struct sysdb_attrs *user; +struct sdap_nested_group_lookup_member_state { + struct sysdb_attrs *member; }; -static void sdap_nested_group_lookup_user_done(struct tevent_req *subreq); +static void sdap_nested_group_lookup_member_done(struct tevent_req *subreq); static struct tevent_req * -sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, +sdap_nested_group_lookup_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member) { - struct sdap_nested_group_lookup_user_state *state = NULL; + struct sdap_nested_group_lookup_member_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char **attrs = NULL; const char *base_filter = NULL; const char *filter = NULL; errno_t ret; + struct sdap_attr_map_info *maps = NULL; + size_t num_maps = 2; req = tevent_req_create(mem_ctx, &state, - struct sdap_nested_group_lookup_user_state); + struct sdap_nested_group_lookup_member_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; @@ -1807,33 +1713,36 @@ sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, PROBE(SDAP_NESTED_GROUP_LOOKUP_USER_SEND); - if (group_ctx->opts->schema_type == SDAP_SCHEMA_IPA_V1) { - /* if the schema is IPA, then just shortcut and guess the name */ - ret = sdap_nested_group_get_ipa_user(state, member->dn, - group_ctx->domain->sysdb, - &state->user); - if (ret == EOK) { - goto immediately; - } - - DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't parse out user information " - "based on DN %s, falling back to an LDAP lookup\n", member->dn); - } - - /* only pull down username and originalDN */ + /* pull down everything */ attrs = talloc_array(state, const char *, 3); if (attrs == NULL) { ret = ENOMEM; goto immediately; } - attrs[0] = "objectClass"; - attrs[1] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name; + attrs[0] = "objectclass"; + attrs[1] = "*"; attrs[2] = NULL; + maps = talloc_array(state, struct sdap_attr_map_info, num_maps +1); + if (maps == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to allocate memory for attribute maps.\n"); + ret = ENOMEM; + goto immediately; + } + maps[0].map = group_ctx->opts->user_map; + maps[0].num_attrs = SDAP_OPTS_USER; + maps[1].map = group_ctx->opts->group_map; + maps[1].num_attrs = SDAP_OPTS_GROUP; + maps[2].map = NULL; + maps[2].num_attrs = 0; + /* create filter */ - base_filter = talloc_asprintf(state, "(objectclass=%s)", - group_ctx->opts->user_map[SDAP_OC_USER].name); + base_filter = talloc_asprintf(state, "(|(objectclass=%s)(objectclass=%s)(objectclass=%s))", + group_ctx->opts->user_map[SDAP_OC_USER].name, + SYSDB_AD_FSP_CLASS, + group_ctx->opts->group_map[SDAP_OC_GROUP].name); if (base_filter == NULL) { ret = ENOMEM; goto immediately; @@ -1847,19 +1756,29 @@ sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, } /* search */ + subreq = sdap_get_and_multi_parse_generic_send(state, ev, group_ctx->opts, + group_ctx->sh, member->dn, + LDAP_SCOPE_BASE, filter, + attrs, maps, num_maps, + false, NULL, NULL, 0, + dp_opt_get_int( + group_ctx->opts->basic, + SDAP_SEARCH_TIMEOUT), + false); +#if 0 subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh, member->dn, LDAP_SCOPE_BASE, filter, attrs, - group_ctx->opts->user_map, - group_ctx->opts->user_map_cnt, + NULL, 0, dp_opt_get_int(group_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); +#endif if (subreq == NULL) { ret = ENOMEM; goto immediately; } - tevent_req_set_callback(subreq, sdap_nested_group_lookup_user_done, req); + tevent_req_set_callback(subreq, sdap_nested_group_lookup_member_done, req); return req; @@ -1874,164 +1793,20 @@ sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, return req; } -static void sdap_nested_group_lookup_user_done(struct tevent_req *subreq) -{ - struct sdap_nested_group_lookup_user_state *state = NULL; - struct tevent_req *req = NULL; - struct sysdb_attrs **user = NULL; - size_t count = 0; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state); - - ret = sdap_get_generic_recv(subreq, state, &count, &user); - talloc_zfree(subreq); - if (ret == ENOENT) { - count = 0; - } else if (ret != EOK) { - goto done; - } - - if (count == 1) { - state->user = user[0]; - } else if (count == 0) { - /* group not found */ - state->user = NULL; - } else { - DEBUG(SSSDBG_OP_FAILURE, - "BASE search returned more than one records\n"); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - -static errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_user) -{ - struct sdap_nested_group_lookup_user_state *state = NULL; - state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state); - - PROBE(SDAP_NESTED_GROUP_LOOKUP_USER_RECV); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - if (_user != NULL) { - *_user = talloc_steal(mem_ctx, state->user); - } - - return EOK; -} - -struct sdap_nested_group_lookup_group_state { - struct sysdb_attrs *group; -}; - -static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq); -static struct tevent_req * -sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_nested_group_ctx *group_ctx, - struct sdap_nested_group_member *member) -{ - struct sdap_nested_group_lookup_group_state *state = NULL; - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; - struct sdap_attr_map *map = group_ctx->opts->group_map; - const char **attrs = NULL; - const char *base_filter = NULL; - const char *filter = NULL; - char *oc_list; - errno_t ret; - - PROBE(SDAP_NESTED_GROUP_LOOKUP_GROUP_SEND); - - req = tevent_req_create(mem_ctx, &state, - struct sdap_nested_group_lookup_group_state); - if (req == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); - return NULL; - } - - ret = build_attrs_from_map(state, group_ctx->opts->group_map, - SDAP_OPTS_GROUP, NULL, &attrs, NULL); - if (ret != EOK) { - goto immediately; - } - - /* create filter */ - oc_list = sdap_make_oc_list(state, map); - if (oc_list == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); - ret = ENOMEM; - goto immediately; - } - - base_filter = talloc_asprintf(attrs, "(&(%s)(%s=*))", oc_list, - map[SDAP_AT_GROUP_NAME].name); - if (base_filter == NULL) { - ret = ENOMEM; - goto immediately; - } - - /* use search base filter if needed */ - filter = sdap_combine_filters(state, base_filter, member->group_filter); - if (filter == NULL) { - ret = ENOMEM; - goto immediately; - } - - /* search */ - subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh, - member->dn, LDAP_SCOPE_BASE, filter, attrs, - map, SDAP_OPTS_GROUP, - dp_opt_get_int(group_ctx->opts->basic, - SDAP_SEARCH_TIMEOUT), - false); - if (subreq == NULL) { - ret = ENOMEM; - goto immediately; - } - - tevent_req_set_callback(subreq, sdap_nested_group_lookup_group_done, req); - - return req; - -immediately: - if (ret == EOK) { - tevent_req_done(req); - } else { - tevent_req_error(req, ret); - } - tevent_req_post(req, ev); - - return req; -} - -static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq) +static void sdap_nested_group_lookup_member_done(struct tevent_req *subreq) { - struct sdap_nested_group_lookup_group_state *state = NULL; + struct sdap_nested_group_lookup_member_state *state = NULL; struct tevent_req *req = NULL; - struct sysdb_attrs **group = NULL; + struct sysdb_attrs **member = NULL; size_t count = 0; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state); + state = tevent_req_data(req, struct sdap_nested_group_lookup_member_state); - ret = sdap_get_generic_recv(subreq, state, &count, &group); + ret = sdap_get_and_multi_parse_generic_recv(subreq, state, &count, &member); + //ret = sdap_get_generic_recv(subreq, state, &count, &member); talloc_zfree(subreq); if (ret == ENOENT) { count = 0; @@ -2040,10 +1815,10 @@ static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq) } if (count == 1) { - state->group = group[0]; + state->member = member[0]; } else if (count == 0) { /* group not found */ - state->group = NULL; + state->member = NULL; } else { DEBUG(SSSDBG_OP_FAILURE, "BASE search returned more than one records\n"); @@ -2062,191 +1837,71 @@ static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq) tevent_req_done(req); } -static errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_group) -{ - struct sdap_nested_group_lookup_group_state *state = NULL; - state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state); - - PROBE(SDAP_NESTED_GROUP_LOOKUP_GROUP_RECV); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - if (_group != NULL) { - *_group = talloc_steal(mem_ctx, state->group); - } - - return EOK; -} - -struct sdap_nested_group_lookup_unknown_state { - struct tevent_context *ev; - struct sdap_nested_group_ctx *group_ctx; - struct sdap_nested_group_member *member; - enum sdap_nested_group_dn_type type; - struct sysdb_attrs *entry; -}; - -static void -sdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq); - -static void -sdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq); - -static struct tevent_req * -sdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_nested_group_ctx *group_ctx, - struct sdap_nested_group_member *member) -{ - struct sdap_nested_group_lookup_unknown_state *state = NULL; - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; - errno_t ret; - - req = tevent_req_create(mem_ctx, &state, - struct sdap_nested_group_lookup_unknown_state); - if (req == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); - return NULL; - } - - PROBE(SDAP_NESTED_GROUP_LOOKUP_UNKNOWN_SEND); - - state->ev = ev; - state->group_ctx = group_ctx; - state->member = member; - - /* try users first */ - subreq = sdap_nested_group_lookup_user_send(state, - state->ev, - state->group_ctx, - state->member); - if (subreq == NULL) { - ret = ENOMEM; - tevent_req_error(req, ret); - tevent_req_post(req, ev); - } else { - tevent_req_set_callback(subreq, - sdap_nested_group_lookup_unknown_user_done, - req); - } - - return req; -} - -static void -sdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq) +static errno_t +sdap_nested_group_lookup_recv(struct sdap_nested_group_single_state *mem_ctx, + struct tevent_req *req, + struct sysdb_attrs **_entry, + enum sdap_nested_group_dn_type *_type) { - struct sdap_nested_group_lookup_unknown_state *state = NULL; - struct tevent_req *req = NULL; - struct sysdb_attrs *entry = NULL; - errno_t ret; + const char *val = NULL; + const char **val_list = NULL; + errno_t ret = EOK; + struct sdap_nested_group_lookup_member_state *state = NULL; - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); + state = tevent_req_data(req, struct sdap_nested_group_lookup_member_state); - ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry); - talloc_zfree(subreq); - if (ret != EOK) { - goto done; - } + PROBE(SDAP_NESTED_GROUP_LOOKUP_UNKNOWN_RECV); - if (entry != NULL) { - /* found in users */ - state->entry = entry; - state->type = SDAP_NESTED_GROUP_DN_USER; - ret = EOK; - goto done; - } + TEVENT_REQ_RETURN_ON_ERROR(req); - /* not found in users, try group */ - subreq = sdap_nested_group_lookup_group_send(state, - state->ev, - state->group_ctx, - state->member); - if (subreq == NULL) { - ret = ENOMEM; - goto done; + if (state->member == NULL) { + *_type = SDAP_NESTED_GROUP_DN_UNKNOWN; + *_entry = NULL; + return EOK; } - tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_group_done, - req); + *_entry = talloc_steal(mem_ctx, state->member); + sysdb_attrs_get_string(state->member, SYSDB_ORIG_DN, &val); - ret = EAGAIN; - -done: + /* Figure out what we got here */ + ret = sysdb_attrs_get_string_array(state->member, SYSDB_OBJECTCLASS, + mem_ctx->group_ctx, &val_list); if (ret == EOK) { - tevent_req_done(req); - } else if (ret != EAGAIN) { - tevent_req_error(req, ret); - } - - return; -} - -static void -sdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq) -{ - struct sdap_nested_group_lookup_unknown_state *state = NULL; - struct tevent_req *req = NULL; - struct sysdb_attrs *entry = NULL; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); - - ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry); - talloc_zfree(subreq); - if (ret != EOK) { - goto done; - } - - if (entry == NULL) { - /* not found, end request */ - state->entry = NULL; - state->type = SDAP_NESTED_GROUP_DN_UNKNOWN; + struct sdap_attr_map *user_map, *group_map; + + user_map = mem_ctx->group_ctx->opts->user_map; + group_map = mem_ctx->group_ctx->opts->group_map; + + if (string_in_list(SYSDB_AD_FSP_CLASS, discard_const(val_list), false)) { + + *_type = SDAP_NESTED_GROUP_DN_FSP; + + } else if (string_in_list(user_map[SDAP_OC_USER].name, + discard_const(val_list), false)) { + DEBUG(SSSDBG_TRACE_ALL, "%s is User\n", val); + /* if we expected a group by a filter, we return NULL */ + if (*_type == SDAP_NESTED_GROUP_DN_GROUP ) + *_entry = NULL; + *_type = SDAP_NESTED_GROUP_DN_USER; + + } else if (string_in_list(group_map[SDAP_OC_GROUP].name, + discard_const(val_list), false)) { + DEBUG(SSSDBG_TRACE_ALL, "%s is Group\n", val); + if (*_type == SDAP_NESTED_GROUP_DN_USER ) + *_entry = NULL; + *_type = SDAP_NESTED_GROUP_DN_GROUP; + + } else { + DEBUG(SSSDBG_TRACE_ALL, "unexpected object %s??\n", val); + *_type = SDAP_NESTED_GROUP_DN_UNKNOWN; + } + talloc_free(val_list); } else { - /* found in groups */ - state->entry = entry; - state->type = SDAP_NESTED_GROUP_DN_GROUP; - } - - ret = EOK; - -done: - if (ret != EOK) { - tevent_req_error(req, ret); - return; + DEBUG(SSSDBG_TRACE_ALL, "can't find objectclass for %s??\n", val); + *_type = SDAP_NESTED_GROUP_DN_UNKNOWN; } - tevent_req_done(req); -} - -static errno_t -sdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct sysdb_attrs **_entry, - enum sdap_nested_group_dn_type *_type) -{ - struct sdap_nested_group_lookup_unknown_state *state = NULL; - state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); - - PROBE(SDAP_NESTED_GROUP_LOOKUP_UNKNOWN_RECV); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - if (_entry != NULL) { - *_entry = talloc_steal(mem_ctx, state->entry); - } - - if (_type != NULL) { - *_type = state->type; - } - - - return EOK; + return ret; } struct sdap_nested_group_deref_state { diff --git a/src/tests/cmocka/common_mock_sdap.c b/src/tests/cmocka/common_mock_sdap.c index 9bbaaf4fb7e..b07ca661dba 100644 --- a/src/tests/cmocka/common_mock_sdap.c +++ b/src/tests/cmocka/common_mock_sdap.c @@ -118,6 +118,35 @@ int sdap_get_generic_recv(struct tevent_req *req, return sss_mock_type(int); } +struct tevent_req *sdap_get_and_multi_parse_generic_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sdap_options *opts, + struct sdap_handle *sh, + const char *search_base, + int scope, + const char *filter, + const char **attrs, + struct sdap_attr_map *map, + int map_num_attrs, + int timeout, + bool allow_paging) +{ + return test_req_succeed_send(mem_ctx, ev); +} + +int sdap_get_and_multi_parse_generic_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *reply_count, + struct sysdb_attrs ***reply) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + *reply_count = sss_mock_type(size_t); + *reply = sss_mock_ptr_type(struct sysdb_attrs **); + + return sss_mock_type(int); +} + struct tevent_req * sdap_deref_search_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, diff --git a/src/tests/cmocka/common_mock_sysdb_objects.c b/src/tests/cmocka/common_mock_sysdb_objects.c index 5dc9e4e7810..7b7a77ea50f 100644 --- a/src/tests/cmocka/common_mock_sysdb_objects.c +++ b/src/tests/cmocka/common_mock_sysdb_objects.c @@ -22,6 +22,7 @@ #include "db/sysdb.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_sysdb_objects.h" +#include "providers/ldap/ldap_opts.h" enum sysdb_attr_type { SYSDB_ATTR_TYPE_BOOL, @@ -189,6 +190,18 @@ mock_sysdb_group_rfc2307bis(TALLOC_CTX *mem_ctx, } } + ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, rfc2307_group_map[SDAP_OC_GROUP].def_name); + if (ret != EOK) { + talloc_zfree(attrs); + return NULL; + } + + ret = sysdb_attrs_add_string(attrs, rfc2307_group_map[SDAP_AT_GROUP_NAME].def_name, name); + if (ret != EOK) { + talloc_zfree(attrs); + return NULL; + } + return attrs; } @@ -198,6 +211,26 @@ mock_sysdb_user(TALLOC_CTX *mem_ctx, uid_t uid, const char *name) { - return mock_sysdb_object(mem_ctx, base_dn, name, - SYSDB_UIDNUM, uid); + struct sysdb_attrs *attrs = NULL; + errno_t ret; + + attrs = mock_sysdb_object(mem_ctx, base_dn, name, + SYSDB_UIDNUM, uid); + if (attrs == NULL) { + return NULL; + } + + ret = sysdb_attrs_add_string(attrs, rfc2307_user_map[SDAP_AT_USER_NAME].def_name, name); + if (ret != EOK) { + talloc_zfree(attrs); + return NULL; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, rfc2307_user_map[SDAP_OC_USER].def_name); + if (ret != EOK) { + talloc_zfree(attrs); + return NULL; + } + + return attrs; } diff --git a/src/tests/cmocka/test_nested_groups.c b/src/tests/cmocka/test_nested_groups.c index 25fd3de0cf4..8cf140b6df5 100644 --- a/src/tests/cmocka/test_nested_groups.c +++ b/src/tests/cmocka/test_nested_groups.c @@ -194,6 +194,7 @@ static void nested_groups_test_one_group_unique_members(void **state) "user2" }; + test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ @@ -202,15 +203,15 @@ static void nested_groups_test_one_group_unique_members(void **state) user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2"); assert_non_null(user2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -285,9 +286,9 @@ static void nested_groups_test_one_group_unique_members_one_ignored(void **state user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -339,15 +340,15 @@ static void nested_groups_test_one_group_dup_users(void **state) user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -403,16 +404,16 @@ static void nested_groups_test_one_group_unique_group_members(void **state) group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "emptygroup2", NULL); assert_non_null(group2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -466,16 +467,16 @@ static void nested_groups_test_one_group_dup_group_members(void **state) group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -536,37 +537,37 @@ static void nested_groups_test_nested_chain(void **state) user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "group1", group1_members); assert_non_null(group1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2"); assert_non_null(user2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "group2", group2_members); assert_non_null(group2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); user3_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2003, "user3"); assert_non_null(user3_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user3_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user3_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); @@ -628,23 +629,23 @@ static void nested_groups_test_nested_chain_with_error(void **state) 1001, "group1", group1_members); assert_non_null(group1_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group1_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group1_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "group2", group2_members); assert_non_null(group2_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, group2_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, group2_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); user_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user_reply[0]); - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, user_reply); - will_return(sdap_get_generic_recv, EIO); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, user_reply); + will_return(sdap_get_and_multi_parse_generic_recv, EIO); sss_will_return_always(sdap_has_deref_support, false); @@ -1013,10 +1014,22 @@ mock_group_with_ext_members(struct nested_groups_test_ctx *test_ctx, } } + ret = sysdb_attrs_add_string(ext_group, SYSDB_OBJECTCLASS, rfc2307_group_map[SDAP_OC_GROUP].def_name); + if (ret != EOK) { + talloc_zfree(ext_group_reply); + return NULL; + } + + ret = sysdb_attrs_add_string(ext_group, rfc2307_group_map[SDAP_AT_GROUP_NAME].def_name, name); + if (ret != EOK) { + talloc_zfree(ext_group_reply); + return NULL; + } + ext_group_reply[0] = ext_group; - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, ext_group_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, ext_group_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); return ext_group; } @@ -1176,8 +1189,11 @@ static void nested_group_external_member_test(void **state) char *fqdn; /* LDAP provider doesn't support external groups by default */ + /* does anyone know why we had the following code? + * Disabled now: test_ctx->sdap_opts->group_map[SDAP_AT_GROUP_MEMBER].name = \ discard_const(TEST_EXT_MEMBER); + */ test_ctx->sdap_opts->ext_ctx = test_ctx->ext_ctx; rootgroup.gr_name = discard_const("rootgroup"); @@ -1198,9 +1214,9 @@ static void nested_group_external_member_test(void **state) nestedgroup_members); assert_non_null(nested_group_ldap_attrs); nested_group_reply[0] = nested_group_ldap_attrs; - will_return(sdap_get_generic_recv, 1); - will_return(sdap_get_generic_recv, nested_group_reply); - will_return(sdap_get_generic_recv, ERR_OK); + will_return(sdap_get_and_multi_parse_generic_recv, 1); + will_return(sdap_get_and_multi_parse_generic_recv, nested_group_reply); + will_return(sdap_get_and_multi_parse_generic_recv, ERR_OK); ext_group.gr_name = discard_const("extgroup"); ext_group.gr_gid = 2001;