sdap_async_nested_groups.c revision 5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9
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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL, ("Inserting [%s] into hash table [%s]\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &gid);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOENT || (ret == EOK && gid == 0)) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("The group's gid was %s\n", ret == ENOENT ? "missing" : "zero"));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("Marking group as non-posix and setting GID=0!\n"));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == ENOENT) {
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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_search_users(NULL, domain->sysdb, domain, filter, attrs,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina &count, &msgs);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sysdb_search_groups(NULL, domain->sysdb, 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březinasdap_nested_group_check_cache(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;
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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search in users */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_sysdb_search_users(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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_sysdb_search_groups(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
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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ret = sdap_nested_group_check_cache(group_ctx->domain, dn, &type);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (ret == EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* found and valid */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina is_user = sss_ldap_dn_in_search_bases(tmp_ctx, dn,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek group_ctx->user_search_bases,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek &user_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina is_group = sss_ldap_dn_in_search_bases(tmp_ctx, dn,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek group_ctx->group_search_bases,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek &group_filter);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (is_user && is_group) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina /* search bases overlap */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL, ("[%s] is out of scope of configured "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL, ("[%s] is outside nesting limit "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "(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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create hash table [%d]: %s\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create hash table [%d]: %s\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("User search base contains filter, "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("Group search base contains filter, "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to insert group into hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("%lu users found in the hash table\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("%lu groups found in the hash table\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve original dn "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve member list "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, ("Looking up %d/%d members of group [%s]\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, ("Dereferencing members of group [%s]\n",
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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 {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, ("Members of group [%s] will be "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, ("Members of group [%s] will be "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("User was looked up twice, "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "this shouldn't have happened.\n"));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to save user in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("The entry has no originalDN\n"));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina orig_dn = "invalid";
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina }
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL, ("[%s] is outside nesting limit "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "(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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("Group was looked up twice, "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "this shouldn't have happened.\n"));
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina goto done;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina } else if (ret != EOK) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to save group in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Error processing direct membership "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Error processing nested groups "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_MINOR_FAILURE, ("Couldn't parse out user information "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina group_ctx->opts->user_map, SDAP_OPTS_USER,
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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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;
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina maps[0].num_attrs = SDAP_OPTS_USER;
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 bool bret;
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
0e65abe5cf2abf5d4b431cf6bd161b419f07901dLukas Slebodnik DEBUG(SSSDBG_TRACE_INTERNAL, ("Received %zu dereference results, "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bret = sss_ldap_dn_in_search_bases(state, orig_dn,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek opts->sdom->user_search_bases, NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (!bret) {
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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("Unable to save user in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_TRACE_ALL, ("[%s] is outside nesting limit "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "(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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina bret = sss_ldap_dn_in_search_bases(state, orig_dn,
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek opts->sdom->group_search_bases, NULL);
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina if (!bret) {
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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("Unable to save group in hash table "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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,
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina ("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) {
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Error processing direct membership "
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina "[%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 */
02b2c042d0c2ace289583c8e5e4ead1eff481376Pavel Březina 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}