91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina/*
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina Authors:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina Pavel Březina <pbrezina@redhat.com>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina Copyright (C) 2013 Red Hat
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina This program is free software; you can redistribute it and/or modify
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina it under the terms of the GNU General Public License as published by
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina the Free Software Foundation; either version 3 of the License, or
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina (at your option) any later version.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina This program is distributed in the hope that it will be useful,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina GNU General Public License for more details.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina You should have received a copy of the GNU General Public License
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina*/
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include <string.h>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include <talloc.h>
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina#include <tevent.h>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include <ndr.h>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include <ndr/ndr_nbt.h>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "util/util.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "util/sss_ldap.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "resolv/async_resolv.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/backend.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/ad/ad_srv.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/ad/ad_common.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/fail_over.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/fail_over_srv.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/ldap/sdap.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "providers/ldap/sdap_async.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#include "db/sysdb.h"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina#define AD_SITE_DOMAIN_FMT "%s._sites.%s"
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic errno_t ad_sort_servers_by_dns(TALLOC_CTX *mem_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info **_srv,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t num)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *out = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *srv = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info in_domain[num];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info out_domain[num];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t srv_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t in_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t out_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t i, j;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (_srv == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EINVAL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina srv = *_srv;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (num <= 1) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out = talloc_zero_array(mem_ctx, struct fo_server_info, num);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (out == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* When several servers share priority, we will prefer the one that
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * is located in the same domain as client (e.g. child domain instead
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * of forest root) but obey their weight. We will use the fact that
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * the servers are already sorted by priority. */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina for (i = 0; i < num; i++) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (is_host_in_domain(srv[i].host, domain)) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* this is a preferred server, push it to the in domain list */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina in_domain[in_index] = srv[i];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina in_index++;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* this is a normal server, push it to the out domain list */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out_domain[out_index] = srv[i];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out_index++;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (i + 1 == num || srv[i].priority != srv[i + 1].priority) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* priority has changed or we have reached the end of the srv list,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * we will merge the list into final list and start over with
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * next priority */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina for (j = 0; j < in_index; j++) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out[srv_index] = in_domain[j];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_steal(out, out[srv_index].host);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina srv_index++;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina for (j = 0; j < out_index; j++) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out[srv_index] = out_domain[j];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_steal(out, out[srv_index].host);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina srv_index++;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina in_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina out_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina talloc_free(*_srv);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina *_srv = out;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return EOK;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina}
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastruct ad_get_dc_servers_state {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct fo_server_info *servers;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina size_t num_servers;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina};
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastatic void ad_get_dc_servers_done(struct tevent_req *subreq);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastatic struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_context *ev,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct resolv_ctx *resolv_ctx,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina const char *discovery_domain,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina const char *site)
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina{
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct ad_get_dc_servers_state *state = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_req *req = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_req *subreq = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina const char **domains = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina errno_t ret;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina req = tevent_req_create(mem_ctx, &state,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct ad_get_dc_servers_state);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (req == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina domains = talloc_zero_array(state, const char *, 3);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (domains == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOMEM;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto immediately;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (site == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain "
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina "%s\n", discovery_domain);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina domains[0] = talloc_strdup(domains, discovery_domain);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (domains[0] == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOMEM;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto immediately;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina } else {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain "
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina "%s and site %s\n", discovery_domain, site);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina domains[0] = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina site, discovery_domain);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (domains[0] == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOMEM;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto immediately;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina domains[1] = talloc_strdup(domains, discovery_domain);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (domains[1] == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOMEM;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto immediately;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina subreq = fo_discover_srv_send(state, ev, resolv_ctx,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina "ldap", FO_PROTO_TCP, domains);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (subreq == NULL) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOMEM;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto immediately;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_set_callback(subreq, ad_get_dc_servers_done, req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return req;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinaimmediately:
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_error(req, ret);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_post(req, ev);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return req;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina}
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastatic void ad_get_dc_servers_done(struct tevent_req *subreq)
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina{
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct ad_get_dc_servers_state *state = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_req *req = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina char *domain = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina errno_t ret;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina state = tevent_req_data(req, struct ad_get_dc_servers_state);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = fo_discover_srv_recv(state, subreq, &domain, NULL,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina &state->servers, &state->num_servers);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina talloc_zfree(subreq);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (ret != EOK) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto done;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Found %zu domain controllers in domain %s\n",
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina state->num_servers, domain);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinadone:
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (ret != EOK) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_error(req, ret);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_done(req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina}
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastatic int ad_get_dc_servers_recv(TALLOC_CTX *mem_ctx,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_req *req,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct fo_server_info **_dcs,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina size_t *_num_dcs)
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina{
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct ad_get_dc_servers_state *state = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina state = tevent_req_data(req, struct ad_get_dc_servers_state);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina *_dcs = talloc_steal(mem_ctx, state->servers);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina *_num_dcs = state->num_servers;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return EOK;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina}
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastruct ad_get_client_site_state {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_context *ev;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct be_resolv_ctx *be_res;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina enum host_database *host_db;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct sdap_options *opts;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina const char *ad_domain;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct fo_server_info *dcs;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina size_t num_dcs;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina size_t dc_index;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct fo_server_info dc;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct sdap_handle *sh;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina char *site;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina char *forest;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina};
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic errno_t ad_get_client_site_next_dc(struct tevent_req *req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_get_client_site_connect_done(struct tevent_req *subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_get_client_site_done(struct tevent_req *subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastruct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_context *ev,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct be_resolv_ctx *be_res,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina enum host_database *host_db,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct sdap_options *opts,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *ad_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *dcs,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t num_dcs)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_get_client_site_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *req = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina req = tevent_req_create(mem_ctx, &state,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_get_client_site_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (req == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (be_res == NULL || host_db == NULL || opts == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EINVAL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ev = ev;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->be_res = be_res;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->host_db = host_db;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->opts = opts;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ad_domain = ad_domain;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->dcs = dcs;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->num_dcs = num_dcs;
f194bd0fa75f87ac29dc08c3aeca9aa86311bfc5Fabiano Fidêncio
f194bd0fa75f87ac29dc08c3aeca9aa86311bfc5Fabiano Fidêncio state->dc_index = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ad_get_client_site_next_dc(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret == EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOENT;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else if (ret != EAGAIN) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return req;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaimmediately:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret == EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_done(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_error(req, ret);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_post(req, ev);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return req;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic errno_t ad_get_client_site_next_dc(struct tevent_req *req)
f194bd0fa75f87ac29dc08c3aeca9aa86311bfc5Fabiano Fidêncio{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_get_client_site_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *subreq = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state = tevent_req_data(req, struct ad_get_client_site_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (state->dc_index >= state->num_dcs) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->dc = state->dcs[state->dc_index];
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina subreq = sdap_connect_host_send(state, state->ev, state->opts,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->be_res->resolv,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->be_res->family_order,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina state->host_db, "ldap", state->dc.host,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->dc.port, false);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (subreq == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_set_callback(subreq, ad_get_client_site_connect_done, req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->dc_index++;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EAGAIN;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinadone:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_get_client_site_connect_done(struct tevent_req *subreq)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_get_client_site_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *req = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina static const char *attrs[] = {AD_AT_NETLOGON, NULL};
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina char *filter = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina char *ntver = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state = tevent_req_data(req, struct ad_get_client_site_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = sdap_connect_host_recv(state, subreq, &state->sh);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_zfree(subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_MINOR_FAILURE, "Unable to connect to domain controller "
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina "[%s:%d]\n", state->dc.host, state->dc.port);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ad_get_client_site_next_dc(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret == EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOENT;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ntver = sss_ldap_encode_ndr_uint32(state, NETLOGON_NT_VERSION_5EX |
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina NETLOGON_NT_VERSION_WITH_CLOSEST_SITE);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ntver == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina filter = talloc_asprintf(state, "(&(%s=%s)(%s=%s))",
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina AD_AT_DNS_DOMAIN, state->ad_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina AD_AT_NT_VERSION, ntver);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (filter == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina "", LDAP_SCOPE_BASE, filter,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina attrs, NULL, 0,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina dp_opt_get_int(state->opts->basic,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina SDAP_SEARCH_TIMEOUT),
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina false);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (subreq == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_set_callback(subreq, ad_get_client_site_done, req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EAGAIN;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinadone:
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (ret == EOK) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_done(req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina } else if (ret != EAGAIN) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina tevent_req_error(req, ret);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina return;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina}
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinastatic void ad_get_client_site_done(struct tevent_req *subreq)
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina{
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct ad_get_client_site_state *state = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct tevent_req *req = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina struct sysdb_attrs **reply = NULL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina size_t reply_count;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina errno_t ret;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina state = tevent_req_data(req, struct ad_get_client_site_state);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina talloc_zfree(subreq);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina /* we're done with this LDAP, close connection */
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina talloc_zfree(state->sh);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_OP_FAILURE, "Unable to get netlogon information\n");
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ad_get_client_site_next_dc(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret == EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOENT;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (reply_count == 0) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_OP_FAILURE, "No netlogon information retrieved\n");
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = ENOENT;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina goto done;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina }
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = netlogon_get_domain_info(state, reply[0], true, NULL, &state->site,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina &state->forest);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (ret != EOK) {
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve site name [%d]: %s\n",
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret, strerror(ret));
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOENT;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Found site: %s\n", state->site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Found forest: %s\n", state->forest);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinadone:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_error(req, ret);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_done(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaint ad_get_client_site_recv(TALLOC_CTX *mem_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *req,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char **_site,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char **_forest)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_get_client_site_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state = tevent_req_data(req, struct ad_get_client_site_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina *_site = talloc_steal(mem_ctx, state->site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina *_forest = talloc_steal(mem_ctx, state->forest);
b9941359b3181c42f415530d5ccad0f4664d85faLukas Slebodnik
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastruct ad_srv_plugin_ctx {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct be_ctx *be_ctx;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct be_resolv_ctx *be_res;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina enum host_database *host_dbs;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct sdap_options *opts;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *hostname;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *ad_domain;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *ad_site_override;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *current_site;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina};
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastruct ad_srv_plugin_ctx *
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct be_ctx *be_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct be_resolv_ctx *be_res,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina enum host_database *host_dbs,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct sdap_options *opts,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *hostname,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *ad_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *ad_site_override)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_ctx *ctx = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx = talloc_zero(mem_ctx, struct ad_srv_plugin_ctx);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->be_ctx = be_ctx;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->be_res = be_res;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->host_dbs = host_dbs;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->opts = opts;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->hostname = talloc_strdup(ctx, hostname);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx->hostname == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto fail;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->ad_domain = talloc_strdup(ctx, ad_domain);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx->ad_domain == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto fail;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ad_site_override != NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->ad_site_override = talloc_strdup(ctx, ad_site_override);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx->ad_site_override == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto fail;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->current_site = talloc_strdup(ctx, ad_site_override);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx->current_site == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto fail;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = sysdb_get_site(ctx, be_ctx->domain, &ctx->current_site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* Not fatal. */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_MINOR_FAILURE,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina "Unable to get current site from cache [%d]: %s\n",
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret, sss_strerror(ret));
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->current_site = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return ctx;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinafail:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_free(ctx);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic errno_t
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *new_site)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *site;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (new_site == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx->current_site != NULL && strcmp(ctx->current_site, new_site) == 0) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina site = talloc_strdup(ctx, new_site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (site == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_zfree(ctx->current_site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx->current_site = site;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = sysdb_set_site(ctx->be_ctx->domain, ctx->current_site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* Not fatal. */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information "
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina "[%d]: %s\n", ret, sss_strerror(ret));
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return EOK;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastruct ad_srv_plugin_state {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_context *ev;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_ctx *ctx;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *service;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *protocol;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *discovery_domain;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *site;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina char *dns_domain;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina uint32_t ttl;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *forest;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *primary_servers;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t num_primary_servers;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *backup_servers;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t num_backup_servers;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina};
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_srv_plugin_dcs_done(struct tevent_req *subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_srv_plugin_site_done(struct tevent_req *subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_srv_plugin_servers_done(struct tevent_req *subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina/* 1. Do a DNS lookup to find any DC in domain
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * _ldap._tcp.domain.name
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * 2. Send a CLDAP ping to the found DC to get the desirable site
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * 3. Do a DNS lookup to find SRV in the site (a)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * _service._protocol.site-name._sites.domain.name
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * 4. Do a DNS lookup to find global SRV records (b)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * _service._protocol.domain.name
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * 5. If the site is found, use (a) as primary and (b) as backup servers,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * otherwise use (b) as primary servers
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastruct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_context *ev,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *service,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *protocol,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina const char *discovery_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina void *pvt)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_ctx *ctx = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *req = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *subreq = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina req = tevent_req_create(mem_ctx, &state,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (req == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ctx = talloc_get_type(pvt, struct ad_srv_plugin_ctx);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ctx == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EINVAL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ev = ev;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ctx = ctx;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->service = talloc_strdup(state, service);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (state->service == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->protocol = talloc_strdup(state, protocol);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (state->protocol == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (discovery_domain != NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->discovery_domain = talloc_strdup(state, discovery_domain);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->discovery_domain = talloc_strdup(state, ctx->ad_domain);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (state->discovery_domain == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "About to find domain controllers\n");
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->discovery_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ctx->current_site);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (subreq == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto immediately;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_set_callback(subreq, ad_srv_plugin_dcs_done, req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return req;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaimmediately:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_error(req, ret);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_post(req, ev);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina return req;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina}
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinastatic void ad_srv_plugin_dcs_done(struct tevent_req *subreq)
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina{
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct ad_srv_plugin_state *state = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct tevent_req *req = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina struct fo_server_info *dcs = NULL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina size_t num_dcs = 0;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina errno_t ret;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state = tevent_req_data(req, struct ad_srv_plugin_state);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ad_get_dc_servers_recv(state, subreq, &dcs, &num_dcs);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina talloc_zfree(subreq);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret != EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "About to locate suitable site\n");
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina subreq = ad_get_client_site_send(state, state->ev,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ctx->be_res,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ctx->host_dbs,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->ctx->opts,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina state->discovery_domain,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina dcs, num_dcs);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (subreq == NULL) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = ENOMEM;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina goto done;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina }
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_set_callback(subreq, ad_srv_plugin_site_done, req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EAGAIN;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinadone:
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (ret == EOK) {
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina tevent_req_done(req);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina } else if (ret != EAGAIN) {
tevent_req_error(req, ret);
}
return;
}
static void ad_srv_plugin_site_done(struct tevent_req *subreq)
{
struct ad_srv_plugin_state *state = NULL;
struct tevent_req *req = NULL;
const char *primary_domain = NULL;
const char *backup_domain = NULL;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_srv_plugin_state);
ret = ad_get_client_site_recv(state, subreq, &state->site, &state->forest);
talloc_zfree(subreq);
/* Ignore AD site found by dns discovery if specific site is set in
* configuration file. */
if (state->ctx->ad_site_override != NULL) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Ignoring AD site found by DNS discovery: '%s', "
"using configured value: '%s' instead.\n",
state->site, state->ctx->ad_site_override);
state->site = state->ctx->ad_site_override;
if (state->forest == NULL) {
DEBUG(SSSDBG_TRACE_FUNC, "Missing forest information, using %s\n",
state->discovery_domain);
state->forest = state->discovery_domain;
}
ret = EOK;
}
primary_domain = state->discovery_domain;
backup_domain = NULL;
if (ret == EOK) {
/* Remember current site so it can be used during next lookup so
* we can contact directory controllers within a known reachable
* site first. */
ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n",
ret, sss_strerror(ret));
goto done;
}
if (strcmp(state->service, "gc") == 0) {
if (state->forest != NULL) {
if (state->site != NULL) {
primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
state->site,
state->forest);
if (primary_domain == NULL) {
ret = ENOMEM;
goto done;
}
backup_domain = state->forest;
} else {
primary_domain = state->forest;
backup_domain = NULL;
}
}
} else {
if (state->site != NULL) {
primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
state->site,
state->discovery_domain);
if (primary_domain == NULL) {
ret = ENOMEM;
goto done;
}
backup_domain = state->discovery_domain;
}
}
} else if (ret != ENOENT && ret != EOK) {
goto done;
}
DEBUG(SSSDBG_TRACE_FUNC, "About to discover primary and "
"backup servers\n");
subreq = fo_discover_servers_send(state, state->ev,
state->ctx->be_res->resolv,
state->service, state->protocol,
primary_domain, backup_domain);
if (subreq == NULL) {
ret = ENOMEM;
goto done;
}
tevent_req_set_callback(subreq, ad_srv_plugin_servers_done, req);
ret = EAGAIN;
done:
if (ret == EOK) {
tevent_req_done(req);
} else if (ret != EAGAIN) {
tevent_req_error(req, ret);
}
return;
}
static void ad_srv_plugin_servers_done(struct tevent_req *subreq)
{
struct ad_srv_plugin_state *state = NULL;
struct tevent_req *req = NULL;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_srv_plugin_state);
ret = fo_discover_servers_recv(state, subreq, &state->dns_domain,
&state->ttl,
&state->primary_servers,
&state->num_primary_servers,
&state->backup_servers,
&state->num_backup_servers);
talloc_zfree(subreq);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
DEBUG(SSSDBG_TRACE_FUNC, "Got %zu primary and %zu backup servers\n",
state->num_primary_servers, state->num_backup_servers);
ret = ad_sort_servers_by_dns(state, state->discovery_domain,
&state->primary_servers,
state->num_primary_servers);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Unable to sort primary servers by DNS"
"[%d]: %s\n", ret, sss_strerror(ret));
/* continue */
}
ret = ad_sort_servers_by_dns(state, state->discovery_domain,
&state->backup_servers,
state->num_backup_servers);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Unable to sort backup servers by DNS"
"[%d]: %s\n", ret, sss_strerror(ret));
/* continue */
}
tevent_req_done(req);
}
errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
char **_dns_domain,
uint32_t *_ttl,
struct fo_server_info **_primary_servers,
size_t *_num_primary_servers,
struct fo_server_info **_backup_servers,
size_t *_num_backup_servers)
{
struct ad_srv_plugin_state *state = NULL;
state = tevent_req_data(req, struct ad_srv_plugin_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (_primary_servers) {
*_primary_servers = talloc_steal(mem_ctx, state->primary_servers);
}
if (_num_primary_servers) {
*_num_primary_servers = state->num_primary_servers;
}
if (_backup_servers) {
*_backup_servers = talloc_steal(mem_ctx, state->backup_servers);
}
if (_num_backup_servers) {
*_num_backup_servers = state->num_backup_servers;
}
if (_dns_domain) {
*_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
}
if (_ttl) {
*_ttl = state->ttl;
}
return EOK;
}