60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev/*
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev SSSD
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev Authors:
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev Jan Zeleny <jzeleny@redhat.com>
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev Copyright (C) 2012 Red Hat
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev This program is free software; you can redistribute it and/or modify
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev it under the terms of the GNU General Public License as published by
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev the Free Software Foundation; either version 3 of the License, or
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev (at your option) any later version.
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev This program is distributed in the hope that it will be useful,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev but WITHOUT ANY WARRANTY; without even the implied warranty of
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev GNU General Public License for more details.
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev You should have received a copy of the GNU General Public License
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev along with this program. If not, see <http://www.gnu.org/licenses/>.
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev*/
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev#include "util/util.h"
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev#include "providers/ldap/sdap_async_private.h"
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev#include "providers/ldap/ldap_common.h"
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstruct sdap_host_state {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct tevent_context *ev;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_handle *sh;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_options *opts;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev const char **attrs;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_attr_map *host_map;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_search_base **search_bases;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev int search_base_iter;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev char *cur_filter;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev char *host_filter;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev const char *hostname;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev /* Return values */
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev size_t host_count;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sysdb_attrs **hosts;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev};
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstatic void
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevsdap_host_info_done(struct tevent_req *subreq);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstatic errno_t
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevsdap_host_info_next(struct tevent_req *req,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_host_state *state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev/**
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev * hostname == NULL -> look up all hosts / host groups
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev * hostname != NULL -> look up only given host and groups
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev * it's member of
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev */
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstruct tevent_req *
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevsdap_host_info_send(TALLOC_CTX *mem_ctx,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct tevent_context *ev,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_handle *sh,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_options *opts,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev const char *hostname,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_attr_map *host_map,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_search_base **search_bases)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev errno_t ret;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_host_state *state;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct tevent_req *req;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev req = tevent_req_create(mem_ctx, &state, struct sdap_host_state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (req == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return NULL;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->ev = ev;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->sh = sh;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->opts = opts;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->hostname = hostname;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->search_bases = search_bases;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->search_base_iter = 0;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->cur_filter = NULL;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->host_map = host_map;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = build_attrs_from_map(state, host_map, SDAP_OPTS_HOST,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev NULL, &state->attrs, NULL);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret != EOK) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev goto immediate;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (hostname == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev host_map[SDAP_OC_HOST].name);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev } else {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev host_map[SDAP_OC_HOST].name,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev host_map[SDAP_AT_HOST_FQDN].name,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev hostname);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (state->host_filter == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = ENOMEM;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev goto immediate;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = sdap_host_info_next(req, state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret == EOK) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n");
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = EINVAL;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret != EAGAIN) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev goto immediate;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return req;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevimmediate:
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret == EOK) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_done(req);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev } else {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_error(req, ret);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_post(req, ev);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return req;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev}
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstatic errno_t sdap_host_info_next(struct tevent_req *req,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_host_state *state)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_search_base *base;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct tevent_req *subreq;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev base = state->search_bases[state->search_base_iter];
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (base == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return EOK;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev talloc_zfree(state->cur_filter);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->cur_filter = sdap_combine_filters(state, state->host_filter,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev base->filter);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (state->cur_filter == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return ENOMEM;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev subreq = sdap_get_generic_send(state, state->ev, state->opts,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->sh, base->basedn,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev base->scope, state->cur_filter,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->attrs, state->host_map,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev SDAP_OPTS_HOST,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev dp_opt_get_int(state->opts->basic,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev SDAP_ENUM_SEARCH_TIMEOUT),
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev true);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (subreq == NULL) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n");
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev talloc_zfree(state->cur_filter);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return EIO;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_set_callback(subreq, sdap_host_info_done, req);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return EAGAIN;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev}
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstatic void
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevsdap_host_info_done(struct tevent_req *subreq)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev errno_t ret;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_host_state *state = tevent_req_data(req, struct sdap_host_state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = sdap_get_generic_recv(subreq, state,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev &state->host_count,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev &state->hosts);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev talloc_zfree(subreq);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret != EOK) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_error(req, ret);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (state->host_count == 0) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev state->search_base_iter++;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ret = sdap_host_info_next(req, state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (ret == EOK) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev /* No more search bases to try */
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_error(req, ENOENT);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev } else if (ret != EAGAIN) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_error(req, ret);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev /* Nothing else to do, just complete the req */
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev tevent_req_done(req);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev}
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Veneverrno_t sdap_host_info_recv(struct tevent_req *req,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev TALLOC_CTX *mem_ctx,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev size_t *host_count,
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sysdb_attrs ***hosts)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct sdap_host_state *state = tevent_req_data(req, struct sdap_host_state);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev TEVENT_REQ_RETURN_ON_ERROR(req);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev *host_count = state->host_count;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev *hosts = talloc_steal(mem_ctx, state->hosts);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return EOK;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev}