ipa_netgroups.c revision 57170bd05e64559a604c1907c59728e8d9e83cd4
8900b9eb2514c07047541833286428572493a9fdStéphane Graber/*
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi SSSD
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi Async IPA Helper routines for netgroups
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi Authors:
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi Jan Zeleny <jzeleny@redhat.com>
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi Copyright (C) 2011 Red Hat
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi This program is free software; you can redistribute it and/or modify
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi it under the terms of the GNU General Public License as published by
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi the Free Software Foundation; either version 3 of the License, or
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi (at your option) any later version.
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi This program is distributed in the hope that it will be useful,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi but WITHOUT ANY WARRANTY; without even the implied warranty of
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi GNU General Public License for more details.
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi You should have received a copy of the GNU General Public License
a5ba96715d4ef264c43d4f187251de491ba198c0KATOH Yasufumi along with this program. If not, see <http://www.gnu.org/licenses/>.
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi*/
8900b9eb2514c07047541833286428572493a9fdStéphane Graber
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#include "util/util.h"
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#include "db/sysdb.h"
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#include "providers/ldap/sdap_async_private.h"
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#include "providers/ipa/ipa_id.h"
faefa7f8584a7d1567df2e6f1f9240a28a6466abStéphane Graber#include "db/sysdb.h"
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#include <ctype.h>
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#define ENTITY_NG 1
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#define ENTITY_USER 2
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi#define ENTITY_HOST 4
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistruct ipa_get_netgroups_state {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_context *ev;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sdap_options *opts;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ipa_options *ipa_opts;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sdap_handle *sh;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_ctx *sysdb;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi const char **attrs;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi int timeout;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi char *filter;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi const char *base_filter;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi size_t netgr_base_iter;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi size_t host_base_iter;
6127da6b3f5815028bee187ac98840cd94313841KATOH Yasufumi size_t user_base_iter;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi /* Entities which have been already asked for
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi * and are scheduled for inspection */
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi hash_table_t *new_netgroups;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi hash_table_t *new_users;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi hash_table_t *new_hosts;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi int current_entity;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi int entities_found;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_attrs **netgroups;
348cb247dbb92940b5684c12b43579bccba85dabKATOH Yasufumi int netgroups_count;
348cb247dbb92940b5684c12b43579bccba85dabKATOH Yasufumi};
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_ctx *ctx,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sdap_options *opts,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_attrs *attrs)
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi{
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ldb_message_element *el;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_attrs *netgroup_attrs;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi const char *name = NULL;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi int ret;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi size_t c;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_get_el(attrs,
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi opts->netgroup_map[IPA_AT_NETGROUP_NAME].sys_name,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi &el);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (el->num_values == 0) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = EINVAL;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi name = (const char *)el->values[0].data;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(SSSDBG_TRACE_INTERNAL, ("Storing netgroup %s\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi netgroup_attrs = sysdb_new_attrs(mem_ctx);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (!netgroup_attrs) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = ENOMEM;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (el->num_values == 0) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("Original DN is not available for [%s].\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi } else {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi el->values[0].data, name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_ORIG_DN,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi (const char *)el->values[0].data);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_TRIPLE, &el);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (el->num_values == 0) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("No netgroup triples for netgroup [%s].\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi } else {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi for(c = 0; c < el->num_values; c++) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_add_string(netgroup_attrs,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi SYSDB_NETGROUP_TRIPLE,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi (const char*)el->values[c].data);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_get_el(attrs,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi &el);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret != EOK) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (el->num_values == 0) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("No original members for netgroup [%s]\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi } else {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("Adding original members to netgroup [%s]\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi for(c = 0; c < el->num_values; c++) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_add_string(netgroup_attrs,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi (const char*)el->values[c].data);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_MEMBER, &el);
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi if (ret != EOK) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (el->num_values == 0) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(7, ("No members for netgroup [%s]\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi } else {
348cb247dbb92940b5684c12b43579bccba85dabKATOH Yasufumi DEBUG(7, ("Adding members to netgroup [%s]\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi for(c = 0; c < el->num_values; c++) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_NETGROUP_MEMBER,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi (const char*)el->values[c].data);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(6, ("Storing info for netgroup %s\n", name));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sysdb_add_netgroup(ctx, name, NULL, netgroup_attrs,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi dp_opt_get_int(opts->basic,
348cb247dbb92940b5684c12b43579bccba85dabKATOH Yasufumi SDAP_ENTRY_CACHE_TIMEOUT),
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi 0);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret) goto fail;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi return EOK;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
1efaeac9ae20212253bcbf7b143496fd86a3e0f5Stéphane Graberfail:
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(2, ("Failed to save netgroup %s\n", name));
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi return ret;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi}
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic errno_t ipa_netgr_next_base(struct tevent_req *req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic void ipa_get_netgroups_process(struct tevent_req *subreq);
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumistatic int ipa_netgr_process_all(struct ipa_get_netgroups_state *state);
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumistruct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct tevent_context *ev,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct sysdb_ctx *sysdb,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct sdap_options *opts,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct ipa_options *ipa_options,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct sdap_handle *sh,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi const char **attrs,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi const char *filter,
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi int timeout)
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi{
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct tevent_req *req;
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi struct ipa_get_netgroups_state *state;
4724cf84f941156273d52918704c6e584455f6b4KATOH Yasufumi int ret;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi req = tevent_req_create(memctx, &state, struct ipa_get_netgroups_state);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (!req) return NULL;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->ev = ev;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->opts = opts;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->ipa_opts = ipa_options;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->sh = sh;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->sysdb = sysdb;
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi state->attrs = attrs;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->timeout = timeout;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->base_filter = filter;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->netgr_base_iter = 0;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sss_hash_create(state, 32, &state->new_netgroups);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret != EOK) goto done;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sss_hash_create(state, 32, &state->new_users);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret != EOK) goto done;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = sss_hash_create(state, 32, &state->new_hosts);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (ret != EOK) goto done;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ret = ipa_netgr_next_base(req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumidone:
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi if (ret != EOK) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi tevent_req_error(req, ret);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi tevent_req_post(req, ev);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi return req;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi}
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic errno_t ipa_netgr_next_base(struct tevent_req *req)
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi{
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req *subreq;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ipa_get_netgroups_state *state;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sdap_search_base **netgr_bases;
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi state = tevent_req_data(req, struct ipa_get_netgroups_state);
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi netgr_bases = state->ipa_opts->id->netgroup_search_bases;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi talloc_zfree(state->filter);
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi state->filter = sdap_get_id_specific_filter(
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state,
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi state->base_filter,
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi netgr_bases[state->netgr_base_iter]->filter);
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi if (!state->filter) {
9a97d4e4bdf331bb2c2b8ed14bcefa53358c288fKATOH Yasufumi return ENOMEM;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi DEBUG(SSSDBG_TRACE_FUNC,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi ("Searching for netgroups with base [%s]\n",
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi netgr_bases[state->netgr_base_iter]->basedn));
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi subreq = sdap_get_generic_send(
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state, state->ev, state->opts, state->sh,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi netgr_bases[state->netgr_base_iter]->basedn,
dc421f3aac1f0e516c763dd156629a8ed2a7b4caKATOH Yasufumi netgr_bases[state->netgr_base_iter]->scope,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->filter, state->attrs,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->opts->netgroup_map, IPA_OPTS_NETGROUP,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi state->timeout);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi if (!subreq) {
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi return ENOMEM;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi }
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi tevent_req_set_callback(subreq, ipa_get_netgroups_process, req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi return EOK;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi}
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req *req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req *req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req *req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic void ipa_netgr_members_process(struct tevent_req *subreq);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumistatic void ipa_get_netgroups_process(struct tevent_req *subreq)
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi{
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req *req = tevent_req_callback_data(subreq,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct tevent_req);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ipa_get_netgroups_state *state = tevent_req_data(req,
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ipa_get_netgroups_state);
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi int i, ret;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ldb_message_element *ng_found;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ldb_message_element *host_found;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct ldb_message_element *user_found;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sdap_search_base **netgr_bases;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi struct sysdb_attrs **netgroups;
57da8c32f85c0255efa61ee32e260068afdaa565KATOH Yasufumi size_t netgroups_count;
const char *orig_dn;
char *dn;
char *filter;
bool fetch_members = false;
hash_key_t key;
hash_value_t value;
netgr_bases = state->ipa_opts->id->netgroup_search_bases;
ret = sdap_get_generic_recv(subreq, state, &netgroups_count, &netgroups);
talloc_zfree(subreq);
if (ret) {
goto done;
}
DEBUG(6, ("Search for netgroups, returned %d results.\n", netgroups_count));
if (netgroups_count == 0) {
/* No netgroups found in this search */
state->netgr_base_iter++;
if (netgr_bases[state->netgr_base_iter]) {
/* There are more search bases to try */
ret = ipa_netgr_next_base(req);
if (ret != EOK) {
tevent_req_error(req, ENOENT);
}
return;
}
ret = ENOENT;
goto done;
}
filter = talloc_strdup(state, "(|");
if (filter == NULL) {
ret = ENOMEM;
goto done;
}
for (i = 0; i < netgroups_count; i++) {
ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER,
&ng_found);
if (ret != EOK) goto done;
ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER_USER,
&user_found);
if (ret != EOK) goto done;
ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER_HOST,
&host_found);
if (ret != EOK) goto done;
ret = sysdb_attrs_get_string(netgroups[i], SYSDB_ORIG_DN, &orig_dn);
if (ret != EOK) {
goto done;
}
key.type = HASH_KEY_STRING;
value.type = HASH_VALUE_PTR;
key.str = discard_const(orig_dn);
value.ptr = netgroups[i];
ret = hash_enter(state->new_netgroups, &key, &value);
if (ret != HASH_SUCCESS) {
ret = ENOMEM;
goto done;
}
if (ng_found->num_values) state->entities_found |= ENTITY_NG;
if (user_found->num_values) state->entities_found |= ENTITY_USER;
if (host_found->num_values) state->entities_found |= ENTITY_HOST;
if (state->entities_found == 0) {
continue;
}
ret = sss_filter_sanitize(state, orig_dn, &dn);
if (ret != EOK) {
goto done;
}
/* Add this to the filter */
filter = talloc_asprintf_append(filter, "(%s=%s)",
state->opts->netgroup_map[IPA_AT_NETGROUP_MEMBER_OF].name,
dn);
if (filter == NULL) {
ret = ENOMEM;
goto done;
}
fetch_members = true;
}
if (!fetch_members) {
ret = ipa_netgr_process_all(state);
if (ret != EOK) {
tevent_req_error(req, ret);
} else {
tevent_req_done(req);
}
return;
}
state->filter = talloc_asprintf_append(filter, ")");
if (state->filter == NULL) {
ret = ENOMEM;
goto done;
}
if (state->entities_found & ENTITY_NG) {
state->netgr_base_iter = 0;
ret = ipa_netgr_fetch_netgroups(state, req);
if (ret != EOK) goto done;
} else if (state->entities_found & ENTITY_USER) {
ret = ipa_netgr_fetch_users(state, req);
if (ret != EOK) goto done;
} else if (state->entities_found & ENTITY_HOST) {
ret = ipa_netgr_fetch_hosts(state, req);
if (ret != EOK) goto done;
}
return;
done:
tevent_req_error(req, ret);
return;
}
static int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
struct tevent_req *req)
{
char *filter;
const char *base_filter;
struct tevent_req *subreq;
struct sdap_search_base **bases;
bases = state->ipa_opts->id->netgroup_search_bases;
if (bases[state->netgr_base_iter] == NULL) {
/* No more bases to try */
return ENOENT;
}
base_filter = bases[state->netgr_base_iter]->filter;
filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
state->filter,
base_filter?base_filter:"",
state->opts->netgroup_map[SDAP_OC_NETGROUP].name);
if (filter == NULL)
return ENOMEM;
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
bases[state->netgr_base_iter]->basedn,
bases[state->netgr_base_iter]->scope,
filter, state->attrs, state->opts->netgroup_map,
IPA_OPTS_NETGROUP, state->timeout);
state->current_entity = ENTITY_NG;
if (subreq == NULL) {
return ENOMEM;
}
tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
return EOK;
}
static int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
struct tevent_req *req)
{
const char *attrs[] = { state->opts->user_map[SDAP_AT_USER_NAME].name,
state->opts->user_map[SDAP_AT_USER_MEMBEROF].name,
"objectclass", NULL };
char *filter;
const char *base_filter;
struct tevent_req *subreq;
struct sdap_search_base **bases;
bases = state->ipa_opts->id->user_search_bases;
if (bases[state->user_base_iter] == NULL) {
return ENOENT;
}
base_filter = bases[state->user_base_iter]->filter;
filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
state->filter,
base_filter?base_filter:"",
state->opts->user_map[SDAP_OC_USER].name);
if (filter == NULL)
return ENOMEM;
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
dp_opt_get_string(state->opts->basic,
SDAP_USER_SEARCH_BASE),
LDAP_SCOPE_SUBTREE,
filter, attrs,
state->opts->user_map,
SDAP_OPTS_USER, state->timeout);
state->current_entity = ENTITY_USER;
if (subreq == NULL) {
talloc_free(attrs);
return ENOMEM;
}
tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
return EOK;
}
static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
struct tevent_req *req)
{
const char **attrs;
char *filter;
const char *base_filter;
struct tevent_req *subreq;
int ret;
struct sdap_search_base **bases;
bases = state->ipa_opts->host_search_bases;
if (bases[state->host_base_iter] == NULL) {
return ENOENT;
}
base_filter = bases[state->host_base_iter]->filter;
filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
state->filter,
base_filter?base_filter:"",
state->opts->host_map[IPA_OC_HOST].name);
if (filter == NULL)
return ENOMEM;
ret = build_attrs_from_map(state, state->opts->host_map,
IPA_OPTS_HOST, &attrs);
if (ret != EOK) {
talloc_free(filter);
return ret;
}
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
bases[state->host_base_iter]->basedn,
bases[state->host_base_iter]->scope,
filter, attrs,
state->opts->host_map,
IPA_OPTS_HOST, state->timeout);
state->current_entity = ENTITY_HOST;
if (subreq == NULL) {
talloc_free(filter);
return ENOMEM;
}
tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
return EOK;
}
static void ipa_netgr_members_process(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct ipa_get_netgroups_state *state = tevent_req_data(req,
struct ipa_get_netgroups_state);
struct sysdb_attrs **entities;
size_t count;
int ret, i;
const char *orig_dn;
char *orig_dn_lower;
hash_table_t *table;
hash_key_t key;
hash_value_t value;
int (* next_call)(struct ipa_get_netgroups_state *,
struct tevent_req *);
bool next_batch_scheduled = false;
ret = sdap_get_generic_recv(subreq, state, &count, &entities);
talloc_zfree(subreq);
if (ret) {
goto fail;
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Found %u members in current search base\n", count));
next_call = NULL;
/* While processing a batch of entities from one search base,
* schedule query for another search base if there is one
*
* If there is no other search base, another class of entities
* will be scheduled for lookup after processing of current
* batch. The order of lookup is: netgroups -> users -> hosts
*/
if (state->current_entity == ENTITY_NG) {
/* We just received a batch of netgroups */
state->netgr_base_iter++;
ret = ipa_netgr_fetch_netgroups(state, req);
table = state->new_netgroups;
/* If there is a member netgroup, we always have to
* ask for both member users and hosts
* -> now schedule users
*/
next_call = ipa_netgr_fetch_users;
} else if (state->current_entity == ENTITY_USER) {
/* We just received a batch of users */
state->user_base_iter++;
ret = ipa_netgr_fetch_users(state, req);
table = state->new_users;
if (state->entities_found & ENTITY_HOST ||
state->entities_found & ENTITY_NG) {
next_call = ipa_netgr_fetch_hosts;
}
} else if (state->current_entity == ENTITY_HOST) {
/* We just received a batch of hosts */
state->host_base_iter++;
ret = ipa_netgr_fetch_hosts(state, req);
table = state->new_hosts;
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
("Invalid entity type given for processing: %d\n",
state->current_entity));
ret = EINVAL;
goto fail;
}
if (ret == EOK) {
/* Next search base has been scheduled for inspection,
* don't try to look for other type of entities
*/
next_batch_scheduled = true;
} else if (ret != ENOENT) {
goto fail;
}
/* Process all member entites and store them in the designated hash table */
key.type = HASH_KEY_STRING;
value.type = HASH_VALUE_PTR;
for (i = 0; i < count; i++) {
ret = sysdb_attrs_get_string(entities[i], SYSDB_ORIG_DN, &orig_dn);
if (ret != EOK) {
goto fail;
}
orig_dn_lower = talloc_strdup(table, orig_dn);
if (orig_dn_lower == NULL) {
ret = ENOMEM;
goto fail;
}
/* Transform the DN to lower case.
* this is important, as the member/memberof attributes
* have the value also in lower-case
*/
key.str = orig_dn_lower;
while (*orig_dn_lower != '\0') {
*orig_dn_lower = tolower(*orig_dn_lower);
orig_dn_lower++;
}
value.ptr = entities[i];
ret = hash_enter(table, &key, &value);
if (ret != HASH_SUCCESS) {
goto fail;
}
}
if (next_batch_scheduled) {
/* The next search base is already scheduled to be searched */
return;
}
if (next_call) {
/* There is another class of members that has to be retrieved
* - schedule the lookup
*/
ret = next_call(state, req);
if (ret != EOK) goto fail;
} else {
/* All members, that could have been fetched, were fetched */
ret = ipa_netgr_process_all(state);
if (ret != EOK) goto fail;
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_users(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_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;
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 (i = 0; i < process_count; i++) {
state->group = process[i];
hash_iterate(lookup_table, extract_users, 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_NETGROUP_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_NETGROUP_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) {
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->opts,
state->netgroups[i]);
if (ret != EOK) {
goto done;
}
}
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;
}