sdap_async_nested_groups.c revision a47cb2e08e4004179d2a6b5f9a9340200270fbd0
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina/*
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SSSD
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina Authors:
d98fdd80331e93cd698281341360a3ce3e30afbePavel Březina Pavel Březina <pbrezina@redhat.com>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina Copyright (C) 2013 Red Hat
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
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
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/>.
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina*/
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <errno.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <string.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <tevent.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <talloc.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <ldb.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <dhash.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <stdint.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include <time.h>
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include "util/util.h"
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include "db/sysdb.h"
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include "providers/ldap/ldap_common.h"
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#include "providers/ldap/sdap_async.h"
5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9Lukas Slebodnik#include "providers/ldap/sdap_async_private.h"
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#define sdap_nested_group_sysdb_search_users(domain, filter) \
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina sdap_nested_group_sysdb_search((domain), (filter), true)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina#define sdap_nested_group_sysdb_search_groups(domain, filter) \
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina sdap_nested_group_sysdb_search((domain), (filter), false)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaenum sdap_nested_group_dn_type {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_NESTED_GROUP_DN_USER,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_NESTED_GROUP_DN_GROUP,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_NESTED_GROUP_DN_UNKNOWN
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_member {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type type;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *dn;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *user_filter;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *group_filter;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_ctx {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sss_domain_info *domain;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_options *opts;
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sdap_search_base **user_search_bases;
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sdap_search_base **group_search_bases;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_handle *sh;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_table_t *users;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_table_t *groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool try_deref;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int deref_treshold;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int max_nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_process_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups_max,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_entry,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type *_type);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *group_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_deref_recv(struct tevent_req *req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_extract_hash_table(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_table_t *table,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_entries,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs ***_entries)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **entries = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_value_t *values;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long num_entries;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned int i;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool hret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hret = hash_values(table, &num_entries, &values);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (hret != HASH_SUCCESS) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EIO;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (num_entries > 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entries = talloc_array(mem_ctx, struct sysdb_attrs *, num_entries);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entries == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (i = 0; i < num_entries; i++) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entry = talloc_get_type(values[i].ptr, struct sysdb_attrs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entries[i] = talloc_steal(entries, entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_num_entries != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_num_entries = num_entries;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_entries != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_entries = entries;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(values);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(entries);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_hash_entry(hash_table_t *table,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *table_name)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_key_t key;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_value_t value;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *name = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int hret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "Inserting [%s] into hash table [%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov name, table_name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina key.type = HASH_KEY_STRING;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina key.str = talloc_strdup(NULL, name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (key.str == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (hash_has_key(table, &key)) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(key.str);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EEXIST;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina value.type = HASH_VALUE_PTR;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina value.ptr = entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hret = hash_enter(table, &key, &value);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (hret != HASH_SUCCESS) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(key.str);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EIO;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_steal(table, key.str);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_steal(table, value.ptr);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_hash_user(struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *user)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return sdap_nested_group_hash_entry(group_ctx->users, user, "users");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *group)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map *map = group_ctx->opts->group_map;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina gid_t gid;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose int32_t ad_group_type;
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose bool posix_group = true;
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose if (group_ctx->opts->schema_type == SDAP_SCHEMA_AD) {
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose ret = sysdb_attrs_get_int32_t(group, SYSDB_GROUP_TYPE, &ad_group_type);
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n");
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose return ret;
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose }
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "AD group has type flags %#x.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ad_group_type);
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose /* Only security groups from AD are considered for POSIX groups.
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose * Additionally only global and universal group are taken to account
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose * for trusted domains. */
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose || (IS_SUBDOMAIN(group_ctx->domain)
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose posix_group = false;
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose gid = 0;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group.\n");
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose }
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &gid);
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose if (ret == ENOENT || (ret == EOK && gid == 0) || !posix_group) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "The group's gid was %s\n", ret == ENOENT ? "missing" : "zero");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Marking group as non-posix and setting GID=0!\n");
8280c5213094a72fcaa499dda2f8647246185d45Sumit Bose if (ret == ENOENT || !posix_group) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_uint32(group,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina map[SDAP_AT_GROUP_GID].sys_name, 0);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to add a GID to non-posix group!\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_bool(group, SYSDB_POSIX, false);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Error: Failed to mark group as non-posix!\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return sdap_nested_group_hash_entry(group_ctx->groups, group, "groups");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_sysdb_search(struct sss_domain_info *domain,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *filter,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool user)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina static const char *attrs[] = {SYSDB_CACHE_EXPIRE,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SYSDB_UIDNUM,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina NULL};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message **msgs = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t count;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina time_t now = time(NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina uint64_t expire;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina uid_t uid;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (user) {
d115f40c7a3999e3cbe705a2ff9cf0fd493f80fbMichal Zidek ret = sysdb_search_users(NULL, domain, filter, attrs,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &count, &msgs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
d115f40c7a3999e3cbe705a2ff9cf0fd493f80fbMichal Zidek ret = sysdb_search_groups(NULL, domain, filter, attrs,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &count, &msgs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (count != 1) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "More than one entry found?\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EFAULT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found an object with this origDN in the sysdb,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * check if it is valid */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (user) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina uid = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_UIDNUM, 0);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (uid == 0) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "User with no UID?\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EINVAL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina expire = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_CACHE_EXPIRE, 0);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (expire != 0 && expire <= now) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* needs refresh */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* valid object */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(msgs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
05f6866b89f790e25510b7eeca88ded617294011Pavel Březinasdap_nested_group_check_cache(struct sdap_options *opts,
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina struct sss_domain_info *domain,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *member_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type *_type)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TALLOC_CTX *tmp_ctx = NULL;
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina struct sdap_domain *sdap_domain = NULL;
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina struct sss_domain_info *member_domain = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *sanitized_dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tmp_ctx = talloc_new(NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (tmp_ctx == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sss_filter_sanitize(tmp_ctx, member_dn, &sanitized_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, sanitized_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (filter == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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;
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search in users */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina ret = sdap_nested_group_sysdb_search_users(member_domain, filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK || ret == EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* user found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_type = SDAP_NESTED_GROUP_DN_USER;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* error */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search in groups */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina ret = sdap_nested_group_sysdb_search_groups(member_domain, filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK || ret == EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_type = SDAP_NESTED_GROUP_DN_GROUP;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* error */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in the sysdb */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(tmp_ctx);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozekstatic bool
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_ent(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek const char *dn, char **filter, bool is_user)
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek{
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek struct sdap_domain *sditer = NULL;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek bool ret = false;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek struct sdap_search_base **search_bases;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek DLIST_FOR_EACH(sditer, group_ctx->opts->sdom) {
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek search_bases = is_user ? sditer->user_search_bases : \
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek sditer->group_search_bases;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek ret = sss_ldap_dn_in_search_bases(group_ctx, dn, search_bases,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek filter);
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek if (ret == true) {
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek break;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek }
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek }
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek return ret;
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek}
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozekstatic inline bool
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_user(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek const char *dn, char **filter)
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek{
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek return sdap_nested_member_is_ent(group_ctx, dn, filter, true);
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek}
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozekstatic inline bool
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozeksdap_nested_member_is_group(struct sdap_nested_group_ctx *group_ctx,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek const char *dn, char **filter)
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek{
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek return sdap_nested_member_is_ent(group_ctx, dn, filter, false);
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek}
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_split_members(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member **_missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int *_num_missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int *_num_groups)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TALLOC_CTX *tmp_ctx = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *missing = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type type;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *user_filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *group_filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_missing = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina hash_key_t key;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool bret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool is_user;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool is_group;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int i;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tmp_ctx = talloc_new(NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (tmp_ctx == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing = talloc_zero_array(tmp_ctx, struct sdap_nested_group_member,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->num_values);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (missing == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * if dn is in sysdb but expired
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * - we know what object type it is
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *
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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (i = 0; i < members->num_values; i++) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina dn = (char*)members->values[i].data;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina type = SDAP_NESTED_GROUP_DN_UNKNOWN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check hash tables */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina key.type = HASH_KEY_STRING;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina key.str = dn;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bret = hash_has_key(group_ctx->users, &key);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (bret) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bret = hash_has_key(group_ctx->groups, &key);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (bret) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check sysdb */
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina ret = sdap_nested_group_check_cache(group_ctx->opts, group_ctx->domain,
05f6866b89f790e25510b7eeca88ded617294011Pavel Březina dn, &type);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found and valid */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] found in cache, skipping\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN && ret != ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* error */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* try to determine type by dn */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (type == SDAP_NESTED_GROUP_DN_UNKNOWN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* user */
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek is_user = sdap_nested_member_is_user(group_ctx, dn,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek &user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek is_group = sdap_nested_member_is_group(group_ctx, dn,
55206e06bcfa0322cd817d34457e330545d6b877Jakub Hrozek &group_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (is_user && is_group) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search bases overlap */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is unknown object\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina type = SDAP_NESTED_GROUP_DN_UNKNOWN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (is_user) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is a user\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina type = SDAP_NESTED_GROUP_DN_USER;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (is_group) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is a group\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina type = SDAP_NESTED_GROUP_DN_GROUP;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* dn is outside search bases */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "[%s] is out of scope of configured "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "search bases, skipping\n", dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* check nesting level */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (type == SDAP_NESTED_GROUP_DN_GROUP) {
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 talloc_zfree(user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(group_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing[num_missing].dn = talloc_strdup(missing, dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (missing[num_missing].dn == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing[num_missing].type = type;
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);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina num_missing++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (type != SDAP_NESTED_GROUP_DN_USER) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina num_groups++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina missing = talloc_realloc(mem_ctx, missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member, num_missing);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (missing == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_missing) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_missing = talloc_steal(mem_ctx, missing);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_num_missing) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_num_missing = num_missing;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_num_groups) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_num_groups = num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(tmp_ctx);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozekstruct tevent_req *
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozeksdap_nested_group_send(TALLOC_CTX *mem_ctx,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct tevent_context *ev,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sdap_domain *sdom,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sdap_options *opts,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sdap_handle *sh,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek struct sysdb_attrs *group)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int i;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 if (state->group_ctx == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->users);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->groups);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = true;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->deref_treshold = dp_opt_get_int(opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_DEREF_THRESHOLD);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->max_nesting_level = dp_opt_get_int(opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_NESTING_LEVEL);
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek state->group_ctx->domain = sdom->dom;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->opts = opts;
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->sh = sh;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = sdap_has_deref_support(sh, opts);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* disable deref if threshold <= 0 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->group_ctx->deref_treshold <= 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* if any search base contains filter, disable dereference. */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->group_ctx->try_deref) {
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");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->group_ctx->try_deref) {
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 state->group_ctx->try_deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* insert initial group into hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx, group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to insert group into hash table "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* resolve group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_process_send(state, ev, state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 0, group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_process_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaerrno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_users,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs ***_users,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long *_num_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs ***_groups)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **users = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **groups = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long num_users;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina unsigned long num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->users,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &num_users, &users);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%lu users found in the hash table\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov num_users);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &num_groups, &groups);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%lu groups found in the hash table\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov num_groups);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_num_users != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_num_users = num_users;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_users != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_users = talloc_steal(mem_ctx, users);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_num_groups!= NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_num_groups = num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_groups != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_groups = talloc_steal(mem_ctx, groups);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_process_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *missing;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_missing_total;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_missing_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *group_dn;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool deref;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_process_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *group)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_process_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map *group_map = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *orig_dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_process_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev = ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level = nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina group_map = state->group_ctx->opts->group_map;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* get original dn */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve original dn "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_dn = talloc_strdup(state, orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->group_dn == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "About to process group [%s]\n", orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* get member list */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_el(group, group_map[SDAP_AT_GROUP_MEMBER].sys_name,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &members);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK; /* no members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve member list "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* get members that need to be refreshed */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_split_members(state, state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level, members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &state->missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &state->num_missing_total,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &state->num_missing_groups);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov state->num_missing_total, members->num_values, orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->num_missing_total == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK; /* we're done */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (group_ctx->try_deref
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina && state->num_missing_total > group_ctx->deref_treshold) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Dereferencing members of group [%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->deref = true;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_deref_send(state, ev, group_ctx, members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina orig_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "processed individually\n", orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_single_send(state, ev, group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_missing_total,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_missing_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_process_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_process_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_process_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->deref) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_deref_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOTSUP) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* dereference is not supported, try again without dereference */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx->try_deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->deref = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "processed individually\n", state->group_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_single_send(state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->missing,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_missing_total,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_missing_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_process_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_single_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_process_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_recurse_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int index;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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řezina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_recurse_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **nested_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_recurse_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_recurse_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev = ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->groups = nested_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups = num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->index = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level = nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process each group individually */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_recurse_step(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_recurse_step(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_recurse_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_recurse_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->index >= state->num_groups) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're done */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_process_send(state, state->ev, state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->groups[state->index]);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_recurse_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->index++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_recurse_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_process_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_recurse_step(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_recurse_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_single_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *current_member;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int member_index;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **nested_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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řezina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups_max,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev = ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->members = members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level = nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_members = num_members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->member_index = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina num_groups_max);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->nested_groups == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups = 0; /* we will count exact number of the groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process each member individually */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_single_step(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_step(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state = tevent_req_data(req, struct sdap_nested_group_single_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (state->member_index >= state->num_members) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're done */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member = &state->members[state->member_index];
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->member_index++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina switch (state->current_member->type) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_USER:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_user_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_GROUP:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_group_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_UNKNOWN:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_unknown_send(state, state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_single_step_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_single_step_process(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry = NULL;
369626f19a9083be643c796691798e2debf2f07bLukas Slebodnik enum sdap_nested_group_dn_type type = SDAP_NESTED_GROUP_DN_UNKNOWN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *orig_dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
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 &entry, &type);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->current_member->type = type;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina switch (state->current_member->type) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_USER:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry == NULL) {
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 if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* user not found, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save user in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_user(state->group_ctx, entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EEXIST) {
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina /* the user is already present, skip it */
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina talloc_zfree(entry);
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save user in hash table "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_GROUP:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry == NULL) {
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 if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
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);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_MINOR_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "The entry has no originalDN\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina orig_dn = "invalid";
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save group in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx, entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EEXIST) {
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina /* the group is already present, skip it */
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina talloc_zfree(entry);
a47cb2e08e4004179d2a6b5f9a9340200270fbd0Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save group in hash table "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* remember the group for later processing */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups[state->num_groups] = entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina case SDAP_NESTED_GROUP_DN_UNKNOWN:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in users nor nested_groups, continue */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_step_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_single_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process direct members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_single_step_process(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_single_step(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
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 state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level + 1);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_single_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* error */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we're not done yet */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
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řezina tevent_req_error(req, EINVAL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_single_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* all nested groups are completed */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_recurse_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing nested groups "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_single_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina/* This should be a function pointer set from the IPA provider */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *user_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_ctx *sysdb,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_user)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *user = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina char *name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_dn *dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *rdn_name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *users_comp_name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *acct_comp_name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const struct ldb_val *rdn_val;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const struct ldb_val *users_comp_val;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const struct ldb_val *acct_comp_val;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TALLOC_CTX *tmp_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tmp_ctx = talloc_new(NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (!tmp_ctx) return ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* return username if dn is in form:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina * uid=username,cn=users,cn=accounts,dc=example,dc=com */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(sysdb), user_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (dn == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* rdn, users, accounts and least one domain component */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ldb_dn_get_comp_num(dn) < 4) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina rdn_name = ldb_dn_get_rdn_name(dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (rdn_name == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EINVAL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* rdn must be 'uid' */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (strcasecmp("uid", rdn_name) != 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* second component must be 'cn=users' */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina users_comp_name = ldb_dn_get_component_name(dn, 1);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (strcasecmp("cn", users_comp_name) != 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina users_comp_val = ldb_dn_get_component_val(dn, 1);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (strncasecmp("users", (const char *) users_comp_val->data,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina users_comp_val->length) != 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* third component must be 'cn=accounts' */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina acct_comp_name = ldb_dn_get_component_name(dn, 2);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (strcasecmp("cn", acct_comp_name) != 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina acct_comp_val = ldb_dn_get_component_val(dn, 2);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (strncasecmp("accounts", (const char *) acct_comp_val->data,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina acct_comp_val->length) != 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOENT;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* value of rdn is username */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina user = sysdb_new_attrs(tmp_ctx);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (user == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina rdn_val = ldb_dn_get_rdn_val(dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina name = talloc_strndup(user, (const char *)rdn_val->data, rdn_val->length);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (name == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_string(user, SYSDB_NAME, name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_string(user, SYSDB_ORIG_DN, user_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCLASS, SYSDB_USER_CLASS);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_user = talloc_steal(mem_ctx, user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_free(tmp_ctx);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_lookup_user_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *user;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_user_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char **attrs = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *base_filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina group_ctx->domain->sysdb,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &state->user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* only pull down username and originalDN */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs = talloc_array(state, const char *, 3);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (attrs == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[0] = "objectClass";
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[1] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[2] = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 if (base_filter == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* use search base filter if needed */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina filter = sdap_get_id_specific_filter(state, base_filter,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member->user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (filter == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member->dn, LDAP_SCOPE_BASE, filter, attrs,
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek group_ctx->opts->user_map,
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek group_ctx->opts->user_map_cnt,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina dp_opt_get_int(group_ctx->opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_SEARCH_TIMEOUT),
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina false);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_user_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_user_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_user_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **user = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t count = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_get_generic_recv(subreq, state, &count, &user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina count = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (count == 1) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->user = user[0];
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (count == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->user = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "BASE search returned more than one records\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EIO;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_user)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
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řezina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_user != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_user = talloc_steal(mem_ctx, state->user);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_lookup_group_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *group;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map *map = group_ctx->opts->group_map;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char **attrs = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *base_filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *filter = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = build_attrs_from_map(state, group_ctx->opts->group_map,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_OPTS_GROUP, NULL, &attrs, NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* create filter */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina base_filter = talloc_asprintf(attrs, "(&(objectclass=%s)(%s=*))",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina map[SDAP_OC_GROUP].name,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina map[SDAP_AT_GROUP_NAME].name);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (base_filter == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* use search base filter if needed */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina filter = sdap_get_id_specific_filter(state, base_filter,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member->group_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (filter == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member->dn, LDAP_SCOPE_BASE, filter, attrs,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina map, SDAP_OPTS_GROUP,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina dp_opt_get_int(group_ctx->opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_SEARCH_TIMEOUT),
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina false);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_group_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_lookup_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_group_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **group = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t count = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_get_generic_recv(subreq, state, &count, &group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOENT) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina count = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (count == 1) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group = group[0];
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (count == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* group not found */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "BASE search returned more than one records\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EIO;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_group)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_group != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_group = talloc_steal(mem_ctx, state->group);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_lookup_unknown_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type type;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_member *member)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev = ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->member = member;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* try users first */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_user_send(state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_user_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found in users */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->entry = entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->type = SDAP_NESTED_GROUP_DN_USER;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found in users, try group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_nested_group_lookup_group_send(state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->member);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_group_done,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_lookup_unknown_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs *entry = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entry == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* not found, end request */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->entry = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->type = SDAP_NESTED_GROUP_DN_UNKNOWN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found in groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->entry = entry;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->type = SDAP_NESTED_GROUP_DN_GROUP;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **_entry,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina enum sdap_nested_group_dn_type *_type)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_entry != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_entry = talloc_steal(mem_ctx, state->entry);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (_type != NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina *_type = state->type;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastruct sdap_nested_group_deref_state {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sysdb_attrs **nested_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int num_groups;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina};
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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řezina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic struct tevent_req *
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_send(TALLOC_CTX *mem_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_context *ev,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_ctx *group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *group_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina int nesting_level)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *subreq = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_attr_map_info *maps = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina static const int num_maps = 2;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_options *opts = group_ctx->opts;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char **attrs = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t num_attrs = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_create(mem_ctx, &state,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->ev = ev;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->group_ctx = group_ctx;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->members = members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level = nesting_level;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups = 0; /* we will count exact number of the groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps = talloc_array(state, struct sdap_attr_map_info, num_maps);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (maps == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps[0].map = opts->user_map;
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek maps[0].num_attrs = opts->user_map_cnt;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps[1].map = opts->group_map;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps[1].num_attrs = SDAP_OPTS_GROUP;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 NULL, &attrs, &num_attrs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs = talloc_realloc(state, attrs, const char *, num_attrs + 2);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (attrs == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[num_attrs] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs[num_attrs + 1] = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* send request */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina subreq = sdap_deref_search_send(state, ev, opts, group_ctx->sh, group_dn,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina opts->group_map[SDAP_AT_GROUP_MEMBER].name,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina attrs, num_maps, maps,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina dp_opt_get_int(opts->basic,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SDAP_SEARCH_TIMEOUT));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto immediately;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_deref_direct_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinaimmediately:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_post(req, ev);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return req;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_deref_direct_process(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_options *opts = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_deref_attrs **entries = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct ldb_message_element *members = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *orig_dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina const char *member_dn = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t num_entries = 0;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina size_t i, j;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bool member_found;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina opts = state->group_ctx->opts;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members = state->members;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_deref_search_recv(subreq, state, &num_entries, &entries);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Received %zu dereference results, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "about to process them\n", num_entries);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina /*
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 */
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *,
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina num_entries);
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina if (state->nested_groups == NULL) {
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina ret = ENOMEM;
fc0d76ac54c813c78380ab388f69c69c3620155dPavel Březina goto done;
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina }
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (i = 0; i < num_entries; i++) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_string(entries[i]->attrs,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina SYSDB_ORIG_DN, &orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "The entry has no originalDN\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member_found = false;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina for (j = 0; j < members->num_values; j++) {
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 if (strcasecmp(orig_dn, member_dn) == 0) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina member_found = true;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina break;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (!member_found) {
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 struct ldb_val,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->num_values + 1);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (members->values == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->values[members->num_values].data =
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 ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->values[members->num_values].length = strlen(orig_dn);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina members->num_values++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (entries[i]->map == opts->user_map) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found a user */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save user in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_user(state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entries[i]->attrs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK && ret != EEXIST) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to save user in hash table "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (entries[i]->map == opts->group_map) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* we found a group */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* save group in hash table */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_hash_group(state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina entries[i]->attrs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EEXIST) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to save group in hash table "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* remember the group for later processing */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups[state->num_groups] = entries[i]->attrs;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups++;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* this should never happen, but if it does, do not loop forever */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_MINOR_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Entry does not match any known map, skipping\n");
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina continue;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina /* adjust size of nested groups array */
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina if (state->num_groups > 0) {
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina state->nested_groups = talloc_realloc(state, state->nested_groups,
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina struct sysdb_attrs *,
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina state->num_groups);
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina if (state->nested_groups == NULL) {
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina ret = ENOMEM;
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina goto done;
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina }
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina } else {
e6dee5182d07e3fdbcdfe5b1b3d36f1d26672223Pavel Březina talloc_zfree(state->nested_groups);
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina }
d9a000b54a23fd4a58481b864175b88a8a3f7949Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_direct_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct sdap_nested_group_deref_state *state = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process direct members */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_deref_direct_process(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "[%d]: %s\n", ret, strerror(ret));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
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 state->group_ctx,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nested_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->num_groups,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina state->nesting_level + 1);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (subreq == NULL) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = ENOMEM;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_set_callback(subreq, sdap_nested_group_deref_done, req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = EAGAIN;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinadone:
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
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řezina tevent_req_error(req, EINVAL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EAGAIN) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic void sdap_nested_group_deref_done(struct tevent_req *subreq)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina struct tevent_req *req = NULL;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina errno_t ret;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* process nested groups */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_recurse_recv(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina talloc_zfree(subreq);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_done(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina tevent_req_error(req, ret);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinastatic errno_t sdap_nested_group_deref_recv(struct tevent_req *req)
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina{
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina return EOK;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina}