ipa_hbac_hosts.c revision c935271de3b99d35112e0faf854cbfa9dfaa104a
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik/*
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik SSSD
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik Authors:
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik Stephen Gallagher <sgallagh@redhat.com>
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik Copyright (C) 2011 Red Hat
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik This program is free software; you can redistribute it and/or modify
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik it under the terms of the GNU General Public License as published by
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik the Free Software Foundation; either version 3 of the License, or
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik (at your option) any later version.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik This program is distributed in the hope that it will be useful,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik but WITHOUT ANY WARRANTY; without even the implied warranty of
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik GNU General Public License for more details.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik You should have received a copy of the GNU General Public License
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik along with this program. If not, see <http://www.gnu.org/licenses/>.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik*/
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik#include "util/util.h"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik#include "db/sysdb.h"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik#include "providers/ipa/ipa_hbac_private.h"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik#include "providers/ldap/sdap_async.h"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstruct ipa_hbac_host_state {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct tevent_context *ev;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sysdb_ctx *sysdb;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_handle *sh;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_options *opts;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik const char **attrs;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_search_base **search_bases;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik int search_base_iter;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik char *cur_filter;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik char *host_filter;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik bool support_srchost;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik const char *hostname;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik /* Return values */
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik size_t host_count;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sysdb_attrs **hosts;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik size_t hostgroup_count;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sysdb_attrs **hostgroups;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_attr_map_info *hostgroup_map;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik};
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik#define HOSTGROUP_MAP_ATTRS_COUNT 5
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic struct sdap_attr_map hostgroup_map[] = {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik {"objectclass", "ipahostgroup", "hostgroup", NULL},
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik {"name_attr", IPA_CN, IPA_CN, NULL},
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik {"member", IPA_MEMBER, SYSDB_ORIG_MEMBER, NULL},
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik {"memberof", IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, NULL},
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik {"ipa_id", IPA_UNIQUE_ID, IPA_UNIQUE_ID, NULL}
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik};
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic void
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_host_info_done(struct tevent_req *subreq);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic void
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_hostgroup_info_done(struct tevent_req *subreq);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic errno_t
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_host_info_next(struct tevent_req *req,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct ipa_hbac_host_state *state);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic errno_t
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_hostgroup_info_next(struct tevent_req *req,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct ipa_hbac_host_state *state);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstruct tevent_req *
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_host_info_send(TALLOC_CTX *mem_ctx,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct tevent_context *ev,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sysdb_ctx *sysdb,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_handle *sh,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_options *opts,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik bool support_srchost,
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen const char *hostname,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_search_base **search_bases)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik{
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik errno_t ret;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct ipa_hbac_host_state *state;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct tevent_req *req;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_host_state);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (req == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return NULL;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->ev = ev;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->sysdb = sysdb;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->sh = sh;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->opts = opts;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->support_srchost = support_srchost;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->hostname = hostname;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->search_bases = search_bases;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->search_base_iter = 0;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->cur_filter = NULL;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (support_srchost) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik IPA_HOST);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik } else {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (hostname == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = EINVAL;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik goto immediate;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik IPA_HOST, IPA_HOST_FQDN, hostname);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (state->host_filter == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = ENOMEM;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik goto immediate;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs = talloc_array(state, const char *, 8);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (state->attrs == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik DEBUG(1, ("Failed to allocate host attribute list.\n"));
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = ENOMEM;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik goto immediate;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[0] = "objectClass";
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[1] = IPA_HOST_SERVERHOSTNAME;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[2] = IPA_HOST_FQDN;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[3] = IPA_UNIQUE_ID;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[4] = IPA_MEMBER;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[5] = IPA_MEMBEROF;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[6] = IPA_CN;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs[7] = NULL;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = ipa_hbac_host_info_next(req, state);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (ret == EOK) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik DEBUG(SSSDBG_CRIT_FAILURE, ("No host search base configured?\n"));
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = EINVAL;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (ret != EAGAIN) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik goto immediate;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return req;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikimmediate:
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (ret == EOK) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_done(req);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik } else {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_error(req, ret);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_post(req, ev);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return req;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik}
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic errno_t ipa_hbac_host_info_next(struct tevent_req *req,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct ipa_hbac_host_state *state)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik{
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct sdap_search_base *base;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct tevent_req *subreq;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik base = state->search_bases[state->search_base_iter];
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (base == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return EOK;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik talloc_zfree(state->cur_filter);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->cur_filter = sdap_get_id_specific_filter(state, state->host_filter,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik base->filter);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (state->cur_filter == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return ENOMEM;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik subreq = sdap_get_generic_send(state, state->ev, state->opts,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->sh, base->basedn,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik base->scope, state->cur_filter,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik state->attrs, NULL, 0,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dp_opt_get_int(state->opts->basic,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik SDAP_ENUM_SEARCH_TIMEOUT));
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (subreq == NULL) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting host info\n"));
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik talloc_zfree(state->cur_filter);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return EIO;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_set_callback(subreq, ipa_hbac_host_info_done, req);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return EAGAIN;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik}
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic void
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikipa_hbac_host_info_done(struct tevent_req *subreq)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik{
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik errno_t ret;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct tevent_req *req =
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_callback_data(subreq, struct tevent_req);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik struct ipa_hbac_host_state *state =
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_data(req, struct ipa_hbac_host_state);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik const char *host_dn;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik int i;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik ret = sdap_get_generic_recv(subreq, state,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik &state->host_count,
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik &state->hosts);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik talloc_zfree(subreq);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (ret != EOK) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik tevent_req_error(req, ret);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen if (state->host_count == 0) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->search_base_iter++;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik ret = ipa_hbac_host_info_next(req, state);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (ret == EOK) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik /* No more search bases to try */
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ENOENT);
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen } else if (ret != EAGAIN) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ret);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF,
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->host_count,
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->hosts);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (ret != EOK) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik DEBUG(1, ("Could not replace attribute names\n"));
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ret);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen }
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik /* Complete the map */
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik for (i = 0; i < HOSTGROUP_MAP_ATTRS_COUNT; i++) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik /* These are allocated on the state, so the next time they'll
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik * have to be allocated again
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik */
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik hostgroup_map[i].name = talloc_strdup(state,
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik hostgroup_map[i].def_name);
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen if (hostgroup_map[i].name == NULL) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ret);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik /* Look up host groups */
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (state->support_srchost) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik talloc_zfree(state->host_filter);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik IPA_HOSTGROUP);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (state->host_filter == NULL) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ENOMEM);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->search_base_iter = 0;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik ret = ipa_hbac_hostgroup_info_next(req, state);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (ret == EOK) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik DEBUG(SSSDBG_CRIT_FAILURE, ("No host search base configured?\n"));
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, EINVAL);
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik } else if (ret != EAGAIN) {
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen tevent_req_error(req, ret);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik } else {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->hostgroup_map = talloc_zero(state, struct sdap_attr_map_info);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (state->hostgroup_map == NULL) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ENOMEM);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->hostgroup_map->map = hostgroup_map;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik state->hostgroup_map->num_attrs = HOSTGROUP_MAP_ATTRS_COUNT;
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik ret = sysdb_attrs_get_string(state->hosts[0], SYSDB_ORIG_DN, &host_dn);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik if (ret != EOK) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik tevent_req_error(req, ret);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return;
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik }
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh,
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik host_dn, IPA_MEMBEROF, state->attrs,
1, state->hostgroup_map,
dp_opt_get_int(state->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT));
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting host info\n"));
tevent_req_error(req, EIO);
return;
}
}
tevent_req_set_callback(subreq, ipa_hbac_hostgroup_info_done, req);
}
static errno_t ipa_hbac_hostgroup_info_next(struct tevent_req *req,
struct ipa_hbac_host_state *state)
{
struct sdap_search_base *base;
struct tevent_req *subreq;
base = state->search_bases[state->search_base_iter];
if (base == NULL) {
return EOK;
}
talloc_zfree(state->cur_filter);
state->cur_filter = sdap_get_id_specific_filter(state, state->host_filter,
base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
base->basedn, base->scope,
state->cur_filter, state->attrs, hostgroup_map,
HOSTGROUP_MAP_ATTRS_COUNT,
dp_opt_get_int(state->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT));
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting hostgroup info\n"));
talloc_zfree(state->cur_filter);
return EIO;
}
tevent_req_set_callback(subreq, ipa_hbac_hostgroup_info_done, req);
return EAGAIN;
}
static void
ipa_hbac_hostgroup_info_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req =
tevent_req_callback_data(subreq, struct tevent_req);
struct ipa_hbac_host_state *state =
tevent_req_data(req, struct ipa_hbac_host_state);
size_t hostgroups_total;
size_t hostgroup_count;
struct sysdb_attrs **hostgroups;
struct sdap_deref_attrs **deref_result;
const char *hostgroup_name;
const char *hostgroup_dn;
int i, j;
if (state->support_srchost) {
ret = sdap_get_generic_recv(subreq, state,
&hostgroup_count,
&hostgroups);
talloc_zfree(subreq);
/* Merge the two arrays */
if (hostgroup_count > 0) {
hostgroups_total = hostgroup_count + state->hostgroup_count;
state->hostgroups = talloc_realloc(state, state->hostgroups,
struct sysdb_attrs *,
hostgroups_total);
if (state->hostgroups == NULL) {
tevent_req_error(req, ENOMEM);
return;
}
i = 0;
while(state->hostgroup_count < hostgroups_total) {
state->hostgroups[state->hostgroup_count] = hostgroups[i];
state->hostgroup_count++;
i++;
}
}
/* Now look in the next base */
state->search_base_iter++;
ret = ipa_hbac_hostgroup_info_next(req, state);
if (ret != EOK && ret != EAGAIN) {
tevent_req_error(req, ret);
}
if (ret != EOK) {
/* Only continue if no error occurred
* and no req was created */
return;
}
} else {
ret = sdap_deref_search_recv(subreq, state,
&state->hostgroup_count,
&deref_result);
talloc_zfree(subreq);
if (ret != EOK) goto done;
if (state->hostgroup_count == 0) {
DEBUG(SSSDBG_FUNC_DATA, ("No host groups were dereferenced\n"));
} else {
state->hostgroups = talloc_zero_array(state, struct sysdb_attrs *,
state->hostgroup_count);
if (state->hostgroups == NULL) {
ret = ENOMEM;
goto done;
}
j = 0;
for (i = 0; i < state->hostgroup_count; i++) {
ret = sysdb_attrs_get_string(deref_result[i]->attrs,
SYSDB_ORIG_DN, &hostgroup_dn);
if (ret != EOK) goto done;
if (!sss_ldap_dn_in_search_bases(state, hostgroup_dn,
state->search_bases,
NULL)) {
continue;
}
ret = sysdb_attrs_get_string(deref_result[i]->attrs,
IPA_CN, &hostgroup_name);
if (ret != EOK) goto done;
DEBUG(SSSDBG_FUNC_DATA, ("Dereferenced host group: %s\n",
hostgroup_name));
state->hostgroups[j] = talloc_steal(state->hostgroups,
deref_result[i]->attrs);
j++;
}
state->hostgroup_count = j;
}
}
done:
if (ret == EOK) {
tevent_req_done(req);
} else {
DEBUG(3, ("Error [%d][%s]\n", ret, strerror(ret)));
tevent_req_error(req, ret);
}
}
errno_t
ipa_hbac_host_info_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *host_count,
struct sysdb_attrs ***hosts,
size_t *hostgroup_count,
struct sysdb_attrs ***hostgroups)
{
size_t c;
struct ipa_hbac_host_state *state =
tevent_req_data(req, struct ipa_hbac_host_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
*host_count = state->host_count;
*hosts = talloc_steal(mem_ctx, state->hosts);
for (c = 0; c < state->host_count; c++) {
/* Guarantee the memory heirarchy of the list */
talloc_steal(state->hosts, state->hosts[c]);
}
*hostgroup_count = state->hostgroup_count;
*hostgroups = talloc_steal(mem_ctx, state->hostgroups);
return EOK;
}
/*
* Functions to convert sysdb_attrs to the hbac_rule format
*/
static errno_t hbac_host_attrs_to_rule(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
const char *rule_name,
struct sysdb_attrs *rule_attrs,
const char *category_attr,
const char *member_attr,
size_t *host_count,
struct hbac_rule_element **hosts)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
struct hbac_rule_element *new_hosts;
const char *attrs[] = { IPA_HOST_FQDN, IPA_CN, NULL };
struct ldb_message_element *el;
size_t num_hosts = 0;
size_t num_hostgroups = 0;
size_t i;
char *member_dn;
char *filter;
size_t count;
struct ldb_message **msgs;
const char *name;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) return ENOMEM;
new_hosts = talloc_zero(tmp_ctx, struct hbac_rule_element);
if (new_hosts == NULL) {
ret = ENOMEM;
goto done;
}
/* First check for host category */
ret = hbac_get_category(rule_attrs, category_attr, &new_hosts->category);
if (ret != EOK) {
DEBUG(1, ("Could not identify host categories\n"));
goto done;
}
if (new_hosts->category & HBAC_CATEGORY_ALL) {
/* Short-cut to the exit */
ret = EOK;
goto done;
}
/* Get the list of DNs from the member_attr */
ret = sysdb_attrs_get_el(rule_attrs, member_attr, &el);
if (ret != EOK && ret != ENOENT) {
DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
goto done;
}
if (ret == ENOENT || el->num_values == 0) {
el->num_values = 0;
DEBUG(4, ("No host specified, rule will never apply.\n"));
}
/* Assume maximum size; We'll trim it later */
new_hosts->names = talloc_array(new_hosts,
const char *,
el->num_values +1);
if (new_hosts->names == NULL) {
ret = ENOMEM;
goto done;
}
new_hosts->groups = talloc_array(new_hosts,
const char *,
el->num_values + 1);
if (new_hosts->groups == NULL) {
ret = ENOMEM;
goto done;
}
for (i = 0; i < el->num_values; i++) {
ret = sss_filter_sanitize(tmp_ctx,
(const char *)el->values[i].data,
&member_dn);
if (ret != EOK) goto done;
filter = talloc_asprintf(member_dn, "(%s=%s)",
SYSDB_ORIG_DN, member_dn);
if (filter == NULL) {
ret = ENOMEM;
goto done;
}
/* First check if this is a specific host */
ret = sysdb_search_custom(tmp_ctx, sysdb, filter,
HBAC_HOSTS_SUBDIR, attrs,
&count, &msgs);
if (ret != EOK && ret != ENOENT) goto done;
if (ret == EOK && count == 0) {
ret = ENOENT;
}
if (ret == EOK) {
if (count > 1) {
DEBUG(1, ("Original DN matched multiple hosts. Skipping \n"));
talloc_zfree(member_dn);
continue;
}
/* Original DN matched a single host. Get the hostname */
name = ldb_msg_find_attr_as_string(msgs[0],
IPA_HOST_FQDN,
NULL);
if (name == NULL) {
DEBUG(1, ("FQDN is missing!\n"));
ret = EFAULT;
goto done;
}
new_hosts->names[num_hosts] = talloc_strdup(new_hosts->names,
name);
if (new_hosts->names[num_hosts] == NULL) {
ret = ENOMEM;
goto done;
}
DEBUG(8, ("Added host [%s] to rule [%s]\n",
name, rule_name));
num_hosts++;
} else { /* ret == ENOENT */
/* Check if this is a hostgroup */
ret = sysdb_search_custom(tmp_ctx, sysdb, filter,
HBAC_HOSTGROUPS_SUBDIR, attrs,
&count, &msgs);
if (ret != EOK && ret != ENOENT) goto done;
if (ret == EOK && count == 0) {
ret = ENOENT;
}
if (ret == EOK) {
if (count > 1) {
DEBUG(1, ("Original DN matched multiple hostgroups. "
"Skipping\n"));
talloc_zfree(member_dn);
continue;
}
/* Original DN matched a single group. Get the groupname */
name = ldb_msg_find_attr_as_string(msgs[0], IPA_CN, NULL);
if (name == NULL) {
DEBUG(1, ("Hostgroup name is missing!\n"));
ret = EFAULT;
goto done;
}
new_hosts->groups[num_hostgroups] =
talloc_strdup(new_hosts->groups, name);
if (new_hosts->groups[num_hostgroups] == NULL) {
ret = ENOMEM;
goto done;
}
DEBUG(8, ("Added hostgroup [%s] to rule [%s]\n",
name, rule_name));
num_hostgroups++;
} else { /* ret == ENOENT */
/* Neither a host nor a hostgroup? Skip it */
DEBUG(1, ("[%s] does not map to either a host or hostgroup. "
"Skipping\n", member_dn));
}
}
talloc_zfree(member_dn);
}
new_hosts->names[num_hosts] = NULL;
new_hosts->groups[num_hostgroups] = NULL;
/* Shrink the arrays down to their real sizes */
new_hosts->names = talloc_realloc(new_hosts, new_hosts->names,
const char *, num_hosts + 1);
if (new_hosts->names == NULL) {
ret = ENOMEM;
goto done;
}
new_hosts->groups = talloc_realloc(new_hosts, new_hosts->groups,
const char *, num_hostgroups + 1);
if (new_hosts->groups == NULL) {
ret = ENOMEM;
goto done;
}
ret = EOK;
done:
if (ret == EOK) {
*hosts = talloc_steal(mem_ctx, new_hosts);
if (host_count) *host_count = num_hosts;
}
talloc_free(tmp_ctx);
return ret;
}
errno_t
hbac_thost_attrs_to_rule(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
const char *rule_name,
struct sysdb_attrs *rule_attrs,
struct hbac_rule_element **thosts)
{
DEBUG(7, ("Processing target hosts for rule [%s]\n", rule_name));
return hbac_host_attrs_to_rule(mem_ctx, sysdb,
rule_name, rule_attrs,
IPA_HOST_CATEGORY, IPA_MEMBER_HOST,
NULL, thosts);
}
errno_t
hbac_shost_attrs_to_rule(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
const char *rule_name,
struct sysdb_attrs *rule_attrs,
bool support_srchost,
struct hbac_rule_element **source_hosts)
{
errno_t ret;
size_t host_count;
TALLOC_CTX *tmp_ctx;
size_t idx;
struct ldb_message_element *el;
struct hbac_rule_element *shosts;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) return ENOMEM;
DEBUG(SSSDBG_TRACE_FUNC, ("Processing source hosts for rule [%s]\n", rule_name));
if (!support_srchost) {
DEBUG(SSSDBG_TRACE_INTERNAL, ("Source hosts disabled, setting ALL\n"));
shosts = talloc_zero(tmp_ctx, struct hbac_rule_element);
if (shosts == NULL) {
ret = ENOMEM;
goto done;
}
shosts->category = HBAC_CATEGORY_ALL;
ret = EOK;
goto done;
}
ret = hbac_host_attrs_to_rule(tmp_ctx, sysdb,
rule_name, rule_attrs,
IPA_SOURCE_HOST_CATEGORY, IPA_SOURCE_HOST,
&host_count, &shosts);
if (ret != EOK) {
goto done;
}
if (shosts->category & HBAC_CATEGORY_ALL) {
/* All hosts (including external) are
* allowed.
*/
goto done;
}
/* Include external (non-IPA-managed) source hosts */
ret = sysdb_attrs_get_el(rule_attrs, IPA_EXTERNAL_HOST, &el);
if (ret != EOK && ret != ENOENT) goto done;
if (ret == EOK && el->num_values == 0) ret = ENOENT;
if (ret != ENOENT) {
shosts->names = talloc_realloc(shosts, shosts->names, const char *,
host_count + el->num_values + 1);
if (shosts->names == NULL) {
ret = ENOMEM;
goto done;
}
for (idx = host_count; idx < host_count + el->num_values; idx++) {
shosts->names[idx] =
talloc_strdup(shosts->names,
(const char *)el->values[idx - host_count].data);
if (shosts->names[idx] == NULL) {
ret = ENOMEM;
goto done;
}
DEBUG(8, ("Added external source host [%s] to rule [%s]\n",
shosts->names[idx], rule_name));
}
shosts->names[idx] = NULL;
}
ret = EOK;
done:
if (ret == EOK) {
*source_hosts = talloc_steal(mem_ctx, shosts);
}
talloc_free(tmp_ctx);
return ret;
}
errno_t
get_ipa_hostgroupname(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
const char *host_dn,
char **hostgroupname)
{
errno_t ret;
struct ldb_dn *dn;
const char *rdn_name;
const char *hostgroup_comp_name;
const char *account_comp_name;
const struct ldb_val *rdn_val;
const struct ldb_val *hostgroup_comp_val;
const struct ldb_val *account_comp_val;
/* This is an IPA-specific hack. It may not
* work for non-IPA servers and will need to
* be changed if SSSD ever supports HBAC on
* a non-IPA server.
*/
*hostgroupname = NULL;
dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), host_dn);
if (dn == NULL) {
ret = ENOMEM;
goto done;
}
if (!ldb_dn_validate(dn)) {
ret = EINVAL;
goto done;
}
if (ldb_dn_get_comp_num(dn) < 4) {
/* RDN, hostgroups, accounts, and at least one DC= */
/* If it's fewer, it's not a group DN */
ret = ENOENT;
goto done;
}
/* If the RDN name is 'cn' */
rdn_name = ldb_dn_get_rdn_name(dn);
if (rdn_name == NULL) {
/* Shouldn't happen if ldb_dn_validate()
* passed, but we'll be careful.
*/
ret = EINVAL;
goto done;
}
if (strcasecmp("cn", rdn_name) != 0) {
/* RDN has the wrong attribute name.
* It's not a host.
*/
ret = ENOENT;
goto done;
}
/* and the second component is "cn=hostgroups" */
hostgroup_comp_name = ldb_dn_get_component_name(dn, 1);
if (strcasecmp("cn", hostgroup_comp_name) != 0) {
/* The second component name is not "cn" */
ret = ENOENT;
goto done;
}
hostgroup_comp_val = ldb_dn_get_component_val(dn, 1);
if (strncasecmp("hostgroups",
(const char *) hostgroup_comp_val->data,
hostgroup_comp_val->length) != 0) {
/* The second component value is not "hostgroups" */
ret = ENOENT;
goto done;
}
/* and the third component is "accounts" */
account_comp_name = ldb_dn_get_component_name(dn, 2);
if (strcasecmp("cn", account_comp_name) != 0) {
/* The third component name is not "cn" */
ret = ENOENT;
goto done;
}
account_comp_val = ldb_dn_get_component_val(dn, 2);
if (strncasecmp("accounts",
(const char *) account_comp_val->data,
account_comp_val->length) != 0) {
/* The third component value is not "accounts" */
ret = ENOENT;
goto done;
}
/* Then the value of the RDN is the group name */
rdn_val = ldb_dn_get_rdn_val(dn);
*hostgroupname = talloc_strndup(mem_ctx,
(const char *)rdn_val->data,
rdn_val->length);
if (*hostgroupname == NULL) {
ret = ENOMEM;
goto done;
}
ret = EOK;
done:
talloc_free(dn);
return ret;
}