d98fdd80331e93cd698281341360a3ce3e30afbePavel Březina Pavel Březina <pbrezina@redhat.com>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina Copyright (C) 2013 Red Hat
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina This program is free software; you can redistribute it and/or modify
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina it under the terms of the GNU General Public License as published by
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina the Free Software Foundation; either version 3 of the License, or
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina (at your option) any later version.
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina This program is distributed in the hope that it will be useful,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina GNU General Public License for more details.
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina You should have received a copy of the GNU General Public License
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9Lukas Slebodnik#include "providers/ldap/sdap_async_private.h"
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio#define sdap_nested_group_sysdb_search_users(domain, dn) \
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio sdap_nested_group_sysdb_search((domain), (dn), true)
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio#define sdap_nested_group_sysdb_search_groups(domain, dn) \
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio sdap_nested_group_sysdb_search((domain), (dn), false)
c6bda70d6131b5e8cd760ad690fae001d1765547Jakub Hrozek#endif /* EXTERNAL_MEMBERS_CHUNK */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_process_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_deref_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_extract_hash_table(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_entries,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned int i;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hret = hash_values(table, &num_entries, &values);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entries = talloc_array(mem_ctx, struct sysdb_attrs *, num_entries);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (i = 0; i < num_entries; i++) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entry = talloc_get_type(values[i].ptr, struct sysdb_attrs);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozekstatic errno_t sdap_nested_group_hash_insert(hash_table_t *table,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "Inserting [%s] into hash table [%s]\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek if (overwrite == false && hash_has_key(table, &key)) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozekstatic errno_t sdap_nested_group_hash_entry(hash_table_t *table,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek return sdap_nested_group_hash_insert(table, name, entry, false, table_name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_hash_user(struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return sdap_nested_group_hash_entry(group_ctx->users, user, "users");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map *map = group_ctx->opts->group_map;
bad2fc8133d941e5a6c8d8016c9689e039265c61Lukas Slebodnik ret = sdap_check_ad_group_type(group_ctx->domain, group_ctx->opts,
8a8618717c99b7331125fa736b45d9155da797d3Jakub Hrozek use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
72db1f3ce67b0634f2843088f1198b3b350b72abLukas Slebodnik can_find_gid = posix_group && !use_id_mapping;
e3c994b7b779e6d6d6d125ee28d30bd139590f49Jakub Hrozek ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name,
72db1f3ce67b0634f2843088f1198b3b350b72abLukas Slebodnik if (!can_find_gid || ret == ENOENT || (ret == EOK && gid == 0)) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "The group's gid was %s\n", ret == ENOENT ? "missing" : "zero");
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz "Marking group as non-POSIX and setting GID=0!\n");
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz "Failed to add a GID to non-POSIX group!\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_bool(group, SYSDB_POSIX, false);
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz "Error: Failed to mark group as non-POSIX!\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return sdap_nested_group_hash_entry(group_ctx->groups, group, "groups");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozekstatic errno_t sdap_nested_group_external_add(hash_table_t *table,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek "Inserting external member [%s] into external members hash table\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ext_mem = talloc_zero(table, struct sdap_external_missing_member);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ext_mem->parent_group_dns = talloc_zero_array(ext_mem,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek const char *,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_hash_insert(table, ext_member, ext_mem,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek true, "missing external users");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek talloc_array_length(ext_mem->parent_group_dns)) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ext_mem->parent_group_dns = talloc_realloc(ext_mem,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek const char *,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ext_mem->parent_group_dns[ext_mem->parent_dn_idx] = \
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek if (ext_mem->parent_group_dns[ext_mem->parent_dn_idx] == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_sysdb_search(struct sss_domain_info *domain,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina static const char *attrs[] = {SYSDB_CACHE_EXPIRE,
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio ret = sysdb_search_users_by_orig_dn(NULL, domain, dn, attrs,
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio ret = sysdb_search_groups_by_orig_dn(NULL, domain, dn, attrs,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "More than one entry found?\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found an object with this origDN in the sysdb,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * check if it is valid */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina uid = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_UIDNUM, 0);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "User with no UID?\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina expire = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_CACHE_EXPIRE, 0);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* needs refresh */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* valid object */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březinasdap_nested_group_check_cache(struct sdap_options *opts,
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina /* determine correct domain of this member */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina sdap_domain = sdap_domain_get_by_dn(opts, member_dn);
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina member_domain = sdap_domain == NULL ? domain : sdap_domain->dom;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search in users */
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_SYSDB_SEARCH_USERS_PRE);
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio ret = sdap_nested_group_sysdb_search_users(member_domain, member_dn);
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_SYSDB_SEARCH_USERS_POST);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* user found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search in groups */
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_SYSDB_SEARCH_GROUPS_PRE);
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio ret = sdap_nested_group_sysdb_search_groups(member_domain, member_dn);
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_SYSDB_SEARCH_GROUPS_POST);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in the sysdb */
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_ent(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek DLIST_FOR_EACH(sditer, group_ctx->opts->sdom) {
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek search_bases = is_user ? sditer->user_search_bases : \
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek ret = sss_ldap_dn_in_search_bases(group_ctx, dn, search_bases,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek if (ret == true) {
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozekstatic inline bool
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_user(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek return sdap_nested_member_is_ent(group_ctx, dn, filter, true);
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozekstatic inline bool
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_group(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek return sdap_nested_member_is_ent(group_ctx, dn, filter, false);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_split_members(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *missing = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing = talloc_zero_array(tmp_ctx, struct sdap_nested_group_member,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* create list of missing members
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * skip dn if:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - is present in user or group hash table
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - is present in sysdb and not expired
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - it is a group and we have reached the maximal nesting level
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - it is not under user nor group search bases
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * if dn is in sysdb but expired
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - we know what object type it is
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * if dn is not in hash table or sysdb
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - try to determine type of object by search base that match dn
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check hash tables */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check sysdb */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina ret = sdap_nested_group_check_cache(group_ctx->opts, group_ctx->domain,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found and valid */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] found in cache, skipping\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* try to determine type by dn */
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek is_user = sdap_nested_member_is_user(group_ctx, dn,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek is_group = sdap_nested_member_is_group(group_ctx, dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search bases overlap */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is unknown object\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (is_user) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is a user\n", dn);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is a group\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* dn is outside search bases */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is out of scope of configured "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check nesting level */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (nesting_level >= group_ctx->max_nesting_level) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "(level %d), skipping\n", dn, nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing[num_missing].dn = talloc_strdup(missing, dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing[num_missing].user_filter = talloc_steal(missing, user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing[num_missing].group_filter = talloc_steal(missing, group_filter);
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek if (threshold > 0 && num_missing > threshold) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member, num_missing);
759fd29a597533a3f5489246c0d2b658d8bee417Pavel Reichl /* talloc_realloc behaves as talloc_free if 3rd parameter (count) is 0,
759fd29a597533a3f5489246c0d2b658d8bee417Pavel Reichl * so it's OK to return NULL then
b5137d2fe9223f71740c2a9be35d7762f136c41aLukas Slebodniksdap_nested_group_add_ext_members(struct sdap_nested_group_ctx *group_ctx,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "A group with no originalDN!?!\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek for (size_t i = 0; i < ext_members->num_values; i++) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ext_member_attr = (const char *) ext_members->values[i].data;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_external_add(group_ctx->missing_external,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek "Cannot add %s into external members [%d]: %s\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_ext_members(struct sdap_options *opts,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct ldb_message_element *ext_members = NULL;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek opts->group_map[SDAP_AT_GROUP_EXT_MEMBER].sys_name,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve external member list "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_state);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* create main nested group context */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = talloc_zero(state, struct sdap_nested_group_ctx);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->users);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->groups);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz state->group_ctx->deref_threshold = dp_opt_get_int(opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->max_nesting_level = dp_opt_get_int(opts->basic,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek state->group_ctx->user_search_bases = sdom->user_search_bases;
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek state->group_ctx->group_search_bases = sdom->group_search_bases;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = sdap_has_deref_support(sh, opts);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* disable deref if threshold <= 0 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* if any search base contains filter, disable dereference. */
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek for (i = 0; opts->sdom->user_search_bases[i] != NULL; i++) {
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek if (opts->sdom->user_search_bases[i]->filter != NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "User search base contains filter, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "dereference will be disabled\n");
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek for (i = 0; opts->sdom->group_search_bases[i] != NULL; i++) {
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek if (opts->sdom->group_search_bases[i]->filter != NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Group search base contains filter, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "dereference will be disabled\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* insert initial group into hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx, group);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to insert group into hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* resolve group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_process_send(state, ev, state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaerrno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_users,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->users,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%lu users found in the hash table\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->groups,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%lu groups found in the hash table\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_process_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_process_state *state = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina group_map = state->group_ctx->opts->group_map;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* get original dn */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve original dn "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_dn = talloc_strdup(state, orig_dn);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "About to process group [%s]\n", orig_dn);
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_PROCESS_SEND, state->group_dn);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek /* get member list, both direct and external */
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek state->ext_members = sdap_nested_group_ext_members(state->group_ctx->opts,
2efc26d6e54b68a079e8f11fa24d04867d432476Jakub Hrozek ret = sysdb_attrs_get_el_ext(group, group_map[SDAP_AT_GROUP_MEMBER].sys_name,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek if (ret == ENOENT && state->ext_members == NULL) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = EOK; /* no members, direct or external */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve member list "
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek split_threshold = state->group_ctx->try_deref ? \
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* get members that need to be refreshed */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_split_members(state, state->group_ctx,
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek "More members were missing than the deref threshold\n");
2efc26d6e54b68a079e8f11fa24d04867d432476Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split member list "
b5137d2fe9223f71740c2a9be35d7762f136c41aLukas Slebodnik ret = sdap_nested_group_add_ext_members(state->group_ctx,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split external member list "
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek && hash_count(state->group_ctx->missing_external) == 0) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek /* If there are only indirect members of the group, it's still safe to
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek * proceed and let the direct lookup code just fall through.
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek "Looking up %d/%d members of group [%s]\n",
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek state->members ? state->members->num_values : 0,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process members */
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz && state->num_missing_total > group_ctx->deref_threshold) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Dereferencing members of group [%s]\n",
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek subreq = sdap_nested_group_deref_send(state, ev, group_ctx,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_single_send(state, ev, group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_process_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_process_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_process_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_process_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* dereference is not supported, try again without dereference */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "processed individually\n", state->group_dn);
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek /* If we previously short-cut dereference, we need to split the
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek * members again to get full list of missing member types
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek ret = sdap_nested_group_split_members(state, state->group_ctx,
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split member list "
beec1ee5799570f34a51ea57674c7291c15f7022Jakub Hrozek "[%d]: %s\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_process_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_process_recv(struct tevent_req *req)
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek struct sdap_nested_group_process_state *state = NULL;
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek state = tevent_req_data(req, struct sdap_nested_group_process_state);
630f3ff08c1d17c7900b9bde814922f775ca2703Jakub Hrozek PROBE(SDAP_NESTED_GROUP_PROCESS_RECV, state->group_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_recurse_step(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_recurse_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_recurse_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_recurse_state *state = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process each group individually */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_recurse_step(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_recurse_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_recurse_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're done */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_process_send(state, state->ev, state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_recurse_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_recurse_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_recurse_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *current_member;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_step(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_step_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups = 0; /* we will count exact number of the groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process each member individually */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_step(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_single_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->member_index >= state->num_members) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're done */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member = &state->members[state->member_index];
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_user_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_group_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_unknown_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_single_step_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_step_process(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
369626f19a9083be643c796691798e2debf2f07bLukas Slebodnik enum sdap_nested_group_dn_type type = SDAP_NESTED_GROUP_DN_UNKNOWN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_single_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* set correct type if possible */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->current_member->type == SDAP_NESTED_GROUP_DN_UNKNOWN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_unknown_recv(state, subreq,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* type was not unknown, receive data */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* user not found, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save user in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_user(state->group_ctx, entry);
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina /* the user is already present, skip it */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save user in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* type was not unknown, receive data */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* the type was unknown so we had to pull the group,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * but we don't want to process it if we have reached
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * the nesting level */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->nesting_level >= state->group_ctx->max_nesting_level) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &orig_dn);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "The entry has no originalDN\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "(level %d), skipping\n", orig_dn, state->nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save group in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx, entry);
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina /* the group is already present, skip it */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save group in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* remember the group for later processing */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups[state->num_groups] = entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in users nor nested_groups, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_step_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_single_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process direct members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_single_step_process(subreq);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we have processed all direct members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * now recurse and process nested groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_recurse_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_single_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're not done yet */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* tevent_req_error() cannot cope with EOK */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "We should not get here with EOK\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* all nested groups are completed */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing nested groups "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx,
a6dd4a6c55773e81490dcafd61d4b9782705e9bfPavel Březina ret = ipa_get_rdn(tmp_ctx, sysdb, user_dn, &name, "uid",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_string(user, SYSDB_NAME, name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_string(user, SYSDB_ORIG_DN, user_dn);
0e238c259c066cf997aaa940d33d6bda96c15925Sumit Bose ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_user_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state *state = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (group_ctx->opts->schema_type == SDAP_SCHEMA_IPA_V1) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* if the schema is IPA, then just shortcut and guess the name */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_get_ipa_user(state, member->dn,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't parse out user information "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "based on DN %s, falling back to an LDAP lookup\n", member->dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* only pull down username and originalDN */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[1] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* create filter */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina base_filter = talloc_asprintf(state, "(objectclass=%s)",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina group_ctx->opts->user_map[SDAP_OC_USER].name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* use search base filter if needed */
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina filter = sdap_combine_filters(state, base_filter, member->user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_user_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_user_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_get_generic_recv(subreq, state, &count, &user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (count == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "BASE search returned more than one records\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map *map = group_ctx->opts->group_map;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = build_attrs_from_map(state, group_ctx->opts->group_map,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* create filter */
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek base_filter = talloc_asprintf(attrs, "(&(%s)(%s=*))", oc_list,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* use search base filter if needed */
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina filter = sdap_combine_filters(state, base_filter, member->group_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_group_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_get_generic_recv(subreq, state, &count, &group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (count == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "BASE search returned more than one records\n");
24c3188e29df52d6df7070007e1c65d152b57fe9Jakub Hrozekstatic errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_group = talloc_steal(mem_ctx, state->group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_lookup_unknown_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* try users first */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_user_send(state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_user_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found in users */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in users, try group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_group_send(state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_group_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found, end request */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found in groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_entry = talloc_steal(mem_ctx, state->entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_direct_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups = 0; /* we will count exact number of the groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps = talloc_array(state, struct sdap_attr_map_info, num_maps);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* pull down the whole group map,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * but only pull down username and originalDN for users */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs = talloc_realloc(state, attrs, const char *, num_attrs + 2);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[num_attrs] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* send request */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_deref_search_send(state, ev, opts, group_ctx->sh, group_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_deref_direct_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_direct_process(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_deref_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_deref_search_recv(subreq, state, &num_entries, &entries);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Received %zu dereference results, "
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina * We don't have any knowledge about possible number of groups when
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina * dereferencing. We expect that every member is a group and we will
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina * allocate enough space to hold it. We will shrink the memory later.
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (i = 0; i < num_entries; i++) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(entries[i]->attrs,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "The entry has no originalDN\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* Ensure that all members returned from the deref request are included
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * in the member processing. Sometimes we will get more results back
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * from deref/asq than we got from the initial lookup, as is the case
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * with Active Directory and its range retrieval mechanism.
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* FIXME: This is inefficient for very large sets of groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member_dn = (const char *)members->values[j].data;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* Append newly found member to member list.
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * Changes in state->members will propagate into sysdb_attrs of
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * the group. */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->members->values = talloc_realloc(members, members->values,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina (uint8_t *)talloc_strdup(members->values, orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (members->values[members->num_values].data == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->values[members->num_values].length = strlen(orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found a user */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* skip the user if it is not amongst configured search bases */
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek if (!sdap_nested_member_is_user(state->group_ctx, orig_dn, NULL)) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save user in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_user(state->group_ctx,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to save user in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (entries[i]->map == opts->group_map) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found a group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* skip the group if we have reached the nesting limit */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->nesting_level >= state->group_ctx->max_nesting_level) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "(level %d), skipping\n", orig_dn, state->nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* skip the group if it is not amongst configured search bases */
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek if (!sdap_nested_member_is_group(state->group_ctx, orig_dn, NULL)) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save group in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to save group in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* remember the group for later processing */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups[state->num_groups] = entries[i]->attrs;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* this should never happen, but if it does, do not loop forever */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Entry does not match any known map, skipping\n");
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina /* adjust size of nested groups array */
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina state->nested_groups = talloc_realloc(state, state->nested_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_direct_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_deref_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process direct members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_deref_direct_process(subreq);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we have processed all direct members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * now recurse and process nested groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_recurse_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_deref_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* tevent_req_error() cannot cope with EOK */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "We should not get here with EOK\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process nested groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_deref_recv(struct tevent_req *req)
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_external_missing_member *missing_mem;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozekstruct sdap_nested_group_lookup_external_state {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_step(struct tevent_req *req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_done(struct tevent_req *subreq);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_link(struct tevent_req *req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek const char ***_parents);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state = NULL;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek if (state->ext_ctx->ext_member_resolve_send == NULL
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek || state->ext_ctx->ext_member_resolve_recv == NULL) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "hash_entries returned %d\n", ret);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_lookup_external_step(req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_step(struct tevent_req *req)
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state = NULL;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek subreq = state->ext_ctx->ext_member_resolve_send(state,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu/%lu\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_done(struct tevent_req *subreq)
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state = NULL;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = state->ext_ctx->ext_member_resolve_recv(state, subreq,
c6bda70d6131b5e8cd760ad690fae001d1765547Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "Refreshed member %lu\n", state->eniter);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek state->ext_members[state->eniter].missing_mem = \
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek state->ext_members[state->eniter].dom = member_dom;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek state->ext_members[state->eniter].ext_member_attr = \
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek state->ext_members[state->eniter].member_type = member_type;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "All external members processed\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_lookup_external_link(req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_lookup_external_step(req);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozeksdap_nested_group_lookup_external_link(struct tevent_req *req)
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state = NULL;
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_transaction_start(state->group_dom->sysdb);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, "The member %s could not be resolved\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_lookup_external_link_member(state,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_transaction_commit(state->group_dom->sysdb);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek tret = sysdb_transaction_cancel(state->group_dom->sysdb);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek struct sdap_nested_group_lookup_external_state *state,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_attrs_get_string(member->attrs, SYSDB_NAME, &name);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "No name for a user\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek /* This only works because the groups were saved in a previous
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek * transaction */
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek for (i=0; i < member->missing_mem->parent_dn_idx; i++) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek orig_dn = member->missing_mem->parent_group_dns[i];
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek "Linking external members %s from domain %s to parents of %s\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sdap_nested_group_memberof_dn_by_original_dn(tmp_ctx,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek /* We don't have to remove the members here, since all members attributes
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek * are always written anew
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek ret = sysdb_update_members_dn(member->dom, name, member->member_type,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Cannot link %s@%s to its parents\n",
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek const char ***_parents)
4c508463be960682cf94b4e5a39be2f8f49067c8Fabiano Fidêncio ret = sysdb_search_groups_by_orig_dn(tmp_ctx, group_dom, original_dn,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek "More than one entry found by originalDN?\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek memberof = ldb_msg_find_element(msgs[0], SYSDB_MEMBEROF);
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek if (memberof == NULL || memberof->num_values == 0) {
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek "The external group is not a member of any groups\n");
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek const char *,
c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3eJakub Hrozek for (size_t i = 0; i < memberof->num_values; i++) {