ipa_netgroups.c revision 5e9bc89b28f1ac3ce573ecdece74fe9623580c28
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek/*
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek SSSD
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Async IPA Helper routines for netgroups
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Authors:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Jan Zeleny <jzeleny@redhat.com>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Copyright (C) 2011 Red Hat
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is free software; you can redistribute it and/or modify
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek it under the terms of the GNU General Public License as published by
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (at your option) any later version.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is distributed in the hope that it will be useful,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek GNU General Public License for more details.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek You should have received a copy of the GNU General Public License
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek*/
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "util/util.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "db/sysdb.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "providers/ldap/sdap_async_private.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "providers/ipa/ipa_id.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "db/sysdb.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include <ctype.h>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#define ENTITY_NG 1
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#define ENTITY_USER 2
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#define ENTITY_HOST 4
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstruct ipa_get_netgroups_state {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_context *ev;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_options *opts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_options *ipa_opts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_handle *sh;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_ctx *sysdb;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_domain_info *dom;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int timeout;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *base_filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t netgr_base_iter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t host_base_iter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t user_base_iter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Entities which have been already asked for
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * and are scheduled for inspection */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_table_t *new_netgroups;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_table_t *new_users;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_table_t *new_hosts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int current_entity;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int entities_found;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_attrs **netgroups;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int netgroups_count;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek};
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_ctx *ctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_domain_info *dom,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_options *opts,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_attrs *attrs)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ldb_message_element *el;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_attrs *netgroup_attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *name = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t c;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_NAME].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (el->num_values == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek name = (const char *)el->values[0].data;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Storing netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgroup_attrs = sysdb_new_attrs(mem_ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!netgroup_attrs) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (el->num_values == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Original DN is not available for [%s].\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek el->values[0].data, name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_ORIG_DN,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (const char *)el->values[0].data);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_TRIPLE, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (el->num_values == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("No netgroup triples for netgroup [%s].\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroup_attrs, SYSDB_NETGROUP_TRIPLE, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for(c = 0; c < el->num_values; c++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek SYSDB_NETGROUP_TRIPLE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (const char*)el->values[c].data);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (el->num_values == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("No original members for netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding original members to netgroup [%s]\n", name));
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozek for(c = 0; c < el->num_values; c++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (const char*)el->values[c].data);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_MEMBER, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (el->num_values == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("No members for netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding members to netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for(c = 0; c < el->num_values; c++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_NETGROUP_MEMBER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (const char*)el->values[c].data);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(6, ("Storing info for netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_add_netgroup(ctx, name, NULL, netgroup_attrs, NULL,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek dom->netgroup_timeout, 0);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekfail:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(2, ("Failed to save netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_netgr_next_base(struct tevent_req *req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_get_netgroups_process(struct tevent_req *subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_process_all(struct ipa_get_netgroups_state *state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstruct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_context *ev,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_ctx *sysdb,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_domain_info *dom,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_options *opts,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_options *ipa_options,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_handle *sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *filter,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int timeout)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek req = tevent_req_create(memctx, &state, struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!req) return NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->ev = ev;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts = opts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->ipa_opts = ipa_options;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->sh = sh;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->sysdb = sysdb;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->attrs = attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->timeout = timeout;
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozek state->base_filter = filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->netgr_base_iter = 0;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->dom = dom;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!ipa_options->id->netgroup_search_bases) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Netgroup lookup request without a search base\n"));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_netgroups);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_users);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_hosts);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_next_base(req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_error(req, ret);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_post(req, ev);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return req;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_netgr_next_base(struct tevent_req *req)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *subreq;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_search_base **netgr_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state = tevent_req_data(req, struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases = state->ipa_opts->id->netgroup_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_zfree(state->filter);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter = sdap_get_id_specific_filter(
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->base_filter,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases[state->netgr_base_iter]->filter);
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozek if (!state->filter) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Searching for netgroups with base [%s]\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases[state->netgr_base_iter]->basedn));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases[state->netgr_base_iter]->basedn,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases[state->netgr_base_iter]->scope,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter, state->attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->netgroup_map, IPA_OPTS_NETGROUP,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->timeout,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek true);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!subreq) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_get_netgroups_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_netgr_members_process(struct tevent_req *subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_get_netgroups_process(struct tevent_req *subreq)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state = tevent_req_data(req,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int i, ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ldb_message_element *ng_found;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ldb_message_element *host_found;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ldb_message_element *user_found;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_search_base **netgr_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_attrs **netgroups;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t netgroups_count;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *orig_dn;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *dn;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bool fetch_members = false;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_key_t key;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_value_t value;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases = state->ipa_opts->id->netgroup_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sdap_get_generic_recv(subreq, state, &netgroups_count, &netgroups);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_zfree(subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(6, ("Search for netgroups, returned %d results.\n", netgroups_count));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (netgroups_count == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* No netgroups found in this search */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->netgr_base_iter++;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (netgr_bases[state->netgr_base_iter]) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* There are more search bases to try */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_next_base(req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_error(req, ENOENT);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOENT;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_strdup(state, "(|");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filter == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for (i = 0; i < netgroups_count; i++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &ng_found);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_USER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &user_found);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_HOST,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &host_found);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_string(netgroups[i], SYSDB_ORIG_DN, &orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek key.type = HASH_KEY_STRING;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek value.type = HASH_VALUE_PTR;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek key.str = discard_const(orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek value.ptr = netgroups[i];
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = hash_enter(state->new_netgroups, &key, &value);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != HASH_SUCCESS) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ng_found->num_values) state->entities_found |= ENTITY_NG;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (user_found->num_values) state->entities_found |= ENTITY_USER;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (host_found->num_values) state->entities_found |= ENTITY_HOST;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (state->entities_found == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek continue;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = sss_filter_sanitize(state, orig_dn, &dn);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Add this to the filter */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf_append(filter, "(%s=%s)",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->netgroup_map[IPA_AT_NETGROUP_MEMBER_OF].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filter == NULL) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = ENOMEM;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek fetch_members = true;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (!fetch_members) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = ipa_netgr_process_all(state);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_error(req, ret);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_done(req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter = talloc_asprintf_append(filter, ")");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (state->filter == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (state->entities_found & ENTITY_NG) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->netgr_base_iter = 0;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = ipa_netgr_fetch_netgroups(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else if (state->entities_found & ENTITY_USER) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = ipa_netgr_fetch_users(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto done;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else if (state->entities_found & ENTITY_HOST) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_fetch_hosts(state, req);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (ret != EOK) goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_error(req, ret);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozekstatic int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *base_filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *subreq;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_search_base **bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek bases = state->ipa_opts->id->netgroup_search_bases;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (bases[state->netgr_base_iter] == NULL) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek /* No more bases to try */
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek return ENOENT;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->netgr_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter?base_filter:"",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->netgroup_map[SDAP_OC_NETGROUP].name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filter == NULL)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases[state->netgr_base_iter]->basedn,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases[state->netgr_base_iter]->scope,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter, state->attrs, state->opts->netgroup_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek IPA_OPTS_NETGROUP, state->timeout, true);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->current_entity = ENTITY_NG;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (subreq == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *attrs[] = { state->opts->user_map[SDAP_AT_USER_NAME].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->user_map[SDAP_AT_USER_MEMBEROF].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "objectclass", NULL };
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *base_filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *subreq;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_search_base **bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases = state->ipa_opts->id->user_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (bases[state->user_base_iter] == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOENT;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->user_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter?base_filter:"",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->user_map[SDAP_OC_USER].name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filter == NULL)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek dp_opt_get_string(state->opts->basic,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek SDAP_USER_SEARCH_BASE),
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek LDAP_SCOPE_SUBTREE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter, attrs, state->opts->user_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek SDAP_OPTS_USER, state->timeout, true);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->current_entity = ENTITY_USER;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (subreq == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(attrs);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *base_filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *subreq;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sdap_search_base **bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases = state->ipa_opts->host_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (bases[state->host_base_iter] == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOENT;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->host_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter?base_filter:"",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->ipa_opts->host_map[IPA_OC_HOST].name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filter == NULL)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = build_attrs_from_map(state, state->ipa_opts->host_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek IPA_OPTS_HOST, NULL, &attrs, NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(filter);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases[state->host_base_iter]->basedn,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases[state->host_base_iter]->scope,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter, attrs, state->ipa_opts->host_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek IPA_OPTS_HOST, state->timeout, true);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->current_entity = ENTITY_HOST;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (subreq == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(filter);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_netgr_members_process(struct tevent_req *subreq)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state = tevent_req_data(req,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sysdb_attrs **entities;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek size_t count;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret, i;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *orig_dn;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *orig_dn_lower;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_table_t *table;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_key_t key;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek hash_value_t value;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int (* next_call)(struct ipa_get_netgroups_state *,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bool next_batch_scheduled = false;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sdap_get_generic_recv(subreq, state, &count, &entities);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_zfree(subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik DEBUG(SSSDBG_TRACE_INTERNAL, ("Found %u members in current search base\n", count));
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik next_call = NULL;
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik /* While processing a batch of entities from one search base,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * schedule query for another search base if there is one
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek *
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * If there is no other search base, another class of entities
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * will be scheduled for lookup after processing of current
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * batch. The order of lookup is: netgroups -> users -> hosts
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (state->current_entity == ENTITY_NG) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of netgroups */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->netgr_base_iter++;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_fetch_netgroups(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek table = state->new_netgroups;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* If there is a member netgroup, we always have to
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * ask for both member users and hosts
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * -> now schedule users
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek next_call = ipa_netgr_fetch_users;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (state->current_entity == ENTITY_USER) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of users */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->user_base_iter++;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_fetch_users(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek table = state->new_users;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (state->entities_found & ENTITY_HOST ||
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->entities_found & ENTITY_NG) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek next_call = ipa_netgr_fetch_hosts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (state->current_entity == ENTITY_HOST) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of hosts */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->host_base_iter++;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_fetch_hosts(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek table = state->new_hosts;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Invalid entity type given for processing: %d\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->current_entity));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret == EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Next search base has been scheduled for inspection,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * don't try to look for other type of entities
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek next_batch_scheduled = true;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (ret != ENOENT) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Process all member entites and store them in the designated hash table */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek key.type = HASH_KEY_STRING;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek value.type = HASH_VALUE_PTR;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for (i = 0; i < count; i++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_string(entities[i], SYSDB_ORIG_DN, &orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek orig_dn_lower = talloc_strdup(table, orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (orig_dn_lower == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Transform the DN to lower case.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * this is important, as the member/memberof attributes
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * have the value also in lower-case
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek key.str = orig_dn_lower;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek while (*orig_dn_lower != '\0') {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek *orig_dn_lower = tolower(*orig_dn_lower);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek orig_dn_lower++;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek value.ptr = entities[i];
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = hash_enter(table, &key, &value);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != HASH_SUCCESS) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (next_batch_scheduled) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* The next search base is already scheduled to be searched */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (next_call) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* There is another class of members that has to be retrieved
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * - schedule the lookup
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = next_call(state, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* All members, that could have been fetched, were fetched */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ipa_netgr_process_all(state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) goto fail;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
tevent_req_done(req);
}
return;
fail:
tevent_req_error(req, ret);
return;
}
static bool extract_netgroups(hash_entry_t *entry, void *pvt)
{
struct ipa_get_netgroups_state *state;
state = talloc_get_type(pvt, struct ipa_get_netgroups_state);
state->netgroups[state->netgroups_count] = talloc_get_type(entry->value.ptr,
struct sysdb_attrs);
state->netgroups_count++;
return true;
}
struct extract_state {
const char *group;
const char **entries;
int entries_count;
};
static bool extract_entities(hash_entry_t *entry, void *pvt)
{
int i, ret;
struct extract_state *state;
struct sysdb_attrs *member;
struct ldb_message_element *el;
struct ldb_message_element *name_el;
state = talloc_get_type(pvt, struct extract_state);
member = talloc_get_type(entry->value.ptr, struct sysdb_attrs);
ret = sysdb_attrs_get_el(member, SYSDB_ORIG_MEMBEROF, &el);
if (ret != EOK) return false;
ret = sysdb_attrs_get_el(member, SYSDB_NAME, &name_el);
if (ret != EOK || name_el == NULL || name_el->num_values == 0) {
return false;
}
for (i = 0; i < el->num_values; i++) {
if (strcmp((char *)el->values[i].data, state->group) == 0) {
state->entries = talloc_realloc(state, state->entries, const char *,
state->entries_count + 1);
if (state->entries == NULL) {
return false;
}
state->entries[state->entries_count] = (char *)name_el->values[0].data;
state->entries_count++;
break;
}
}
return true;
}
static int extract_members(TALLOC_CTX *mem_ctx,
struct sysdb_attrs *netgroup,
const char *member_type,
hash_table_t *lookup_table,
const char ***_ret_array,
int *_ret_count)
{
struct extract_state *state;
struct ldb_message_element *el;
struct sysdb_attrs *member;
hash_key_t key;
hash_value_t value;
const char **process = NULL;
const char **ret_array = NULL;
int process_count = 0;
int ret_count = 0;
int ret, i, pi;
key.type = HASH_KEY_STRING;
value.type = HASH_VALUE_PTR;
state = talloc_zero(mem_ctx, struct extract_state);
if (state == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_get_el(netgroup, member_type, &el);
if (ret != EOK && ret != ENOENT) {
goto done;
}
if (ret == EOK) {
for (i = 0; i < el->num_values; i++) {
key.str = (char *)el->values[i].data;
ret = hash_lookup(lookup_table, &key, &value);
if (ret != HASH_SUCCESS && ret != HASH_ERROR_KEY_NOT_FOUND) {
ret = ENOENT;
goto done;
}
if (ret == HASH_ERROR_KEY_NOT_FOUND) {
process = talloc_realloc(mem_ctx, process, const char *, process_count + 1);
if (process == NULL) {
ret = ENOMEM;
goto done;
}
process[process_count] = (char *)el->values[i].data;
process_count++;
} else {
ret_array = talloc_realloc(mem_ctx, ret_array, const char *, ret_count + 1);
if (ret_array == NULL) {
ret = ENOMEM;
goto done;
}
member = talloc_get_type(value.ptr, struct sysdb_attrs);
ret = sysdb_attrs_get_string(member, SYSDB_NAME, &ret_array[ret_count]);
if (ret != EOK) {
goto done;
}
ret_count++;
}
for (pi = 0; pi < process_count; pi++) {
state->group = process[pi];
hash_iterate(lookup_table, extract_entities, state);
if (state->entries_count > 0) {
ret_array = talloc_realloc(mem_ctx, ret_array, const char *,
ret_count + state->entries_count);
if (ret_array == NULL) {
ret = ENOMEM;
goto done;
}
memcpy(&ret_array[ret_count], state->entries,
state->entries_count*sizeof(const char *));
ret_count += state->entries_count;
}
state->entries_count = 0;
talloc_zfree(state->entries);
}
}
} else {
ret_array = NULL;
}
*_ret_array = ret_array;
*_ret_count = ret_count;
ret = EOK;
done:
return ret;
}
static int ipa_netgr_process_all(struct ipa_get_netgroups_state *state)
{
int i, j, k, ret;
const char **members;
struct sysdb_attrs *member;
const char *member_name;
struct extract_state *extract_state;
struct ldb_message_element *external_hosts;
const char *dash[] = {"-"};
const char **uids = NULL;
const char **hosts = NULL;
int uids_count = 0;
int hosts_count = 0;
hash_key_t key;
hash_value_t value;
const char *domain;
char *triple;
state->netgroups = talloc_zero_array(state, struct sysdb_attrs *,
hash_count(state->new_netgroups));
if (state->netgroups == NULL) {
return ENOMEM;
}
extract_state = talloc_zero(state, struct extract_state);
if (extract_state == NULL) {
ret = ENOMEM;
goto done;
}
key.type = HASH_KEY_STRING;
value.type = HASH_VALUE_PTR;
hash_iterate(state->new_netgroups, extract_netgroups, state);
for (i = 0; i < state->netgroups_count; i++) {
/* load all its member netgroups, translate */
DEBUG(SSSDBG_TRACE_INTERNAL, ("Extracting netgroup members of netgroup %d\n", i));
ret = sysdb_attrs_get_string_array(state->netgroups[i],
SYSDB_ORIG_NETGROUP_MEMBER,
state, &members);
if (ret != EOK && ret != ENOENT) {
goto done;
}
j = 0;
if (ret == EOK) {
for (j = 0; members[j]; j++) {
key.str = discard_const(members[j]);
ret = hash_lookup(state->new_netgroups, &key, &value);
if (ret != HASH_SUCCESS) {
ret = ENOENT;
goto done;
}
member = talloc_get_type(value.ptr, struct sysdb_attrs);
ret = sysdb_attrs_get_string(member, SYSDB_NAME, &member_name);
if (ret != EOK) {
goto done;
}
ret = sysdb_attrs_add_string(state->netgroups[i],
SYSDB_NETGROUP_MEMBER,
member_name);
if (ret != EOK) {
goto done;
}
}
talloc_zfree(members);
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Extracted %d netgroup members\n", j));
/* Load all UIDs */
DEBUG(SSSDBG_TRACE_ALL, ("Extracting user members of netgroup %d\n", i));
ret = extract_members(state, state->netgroups[i],
SYSDB_ORIG_MEMBER_USER,
state->new_users,
&uids, &uids_count);
if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Extracted %d user members\n", uids_count));
DEBUG(SSSDBG_TRACE_ALL, ("Extracting host members of netgroup %d\n", i));
ret = extract_members(state, state->netgroups[i],
SYSDB_ORIG_MEMBER_HOST,
state->new_hosts,
&hosts, &hosts_count);
if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Extracted %d host members\n", hosts_count));
ret = sysdb_attrs_get_el(state->netgroups[i],
SYSDB_ORIG_NETGROUP_EXTERNAL_HOST,
&external_hosts);
if (ret != EOK) {
goto done;
}
if (external_hosts->num_values > 0) {
hosts = talloc_realloc(state, hosts, const char *,
hosts_count + external_hosts->num_values);
if (hosts == NULL) {
ret = ENOMEM;
goto done;
}
for (j = 0; j < external_hosts->num_values; j++) {
hosts[hosts_count] = talloc_strdup(hosts, (char *)external_hosts->values[j].data);
if (hosts[hosts_count] == NULL) {
ret = ENOMEM;
goto done;
}
hosts_count++;
}
}
ret = sysdb_attrs_get_string(state->netgroups[i], SYSDB_NETGROUP_DOMAIN,
&domain);
if (ret != EOK) {
goto done;
}
if (uids_count > 0 || hosts_count > 0) {
if (uids_count == 0) {
uids_count = 1;
uids = dash;
}
if (hosts_count == 0) {
hosts_count = 1;
hosts = dash;
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Putting together triples of "
"netgroup %d\n", i));
for (j = 0; j < uids_count; j++) {
for (k = 0; k < hosts_count; k++) {
triple = talloc_asprintf(state, "(%s,%s,%s)",
hosts[k], uids[j],
domain);
if (triple == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_add_string(state->netgroups[i],
SYSDB_NETGROUP_TRIPLE,
triple);
if (ret != EOK) {
goto done;
}
}
}
}
ret = ipa_save_netgroup(state, state->sysdb, state->dom,
state->opts, state->netgroups[i]);
if (ret != EOK) {
goto done;
}
}
ret = EOK;
done:
return ret;
}
int ipa_get_netgroups_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *reply_count,
struct sysdb_attrs ***reply)
{
struct ipa_get_netgroups_state *state = tevent_req_data(req,
struct ipa_get_netgroups_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (reply_count) {
*reply_count = state->netgroups_count;
}
if (reply) {
*reply = talloc_steal(mem_ctx, state->netgroups);
}
return EOK;
}