9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek/*
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek SSSD
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek sdap_dyndns.c: LDAP specific dynamic DNS update
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek Authors:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek Copyright (C) 2013 Red Hat
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek This program is free software; you can redistribute it and/or modify
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek it under the terms of the GNU General Public License as published by
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek (at your option) any later version.
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek This program is distributed in the hope that it will be useful,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek GNU General Public License for more details.
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek You should have received a copy of the GNU General Public License
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek*/
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek#include "util/util.h"
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek#include "resolv/async_resolv.h"
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina#include "providers/backend.h"
892ddeb5190dd5c1ffa26a95142a10a0034fc5e3Pavel Březina#include "providers/be_dyndns.h"
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek#include "providers/ldap/sdap_async_private.h"
5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9Lukas Slebodnik#include "providers/ldap/sdap_dyndns.h"
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek#include "providers/ldap/sdap_id_op.h"
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek#include "providers/ldap/ldap_common.h"
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic struct tevent_req *
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_context *ev,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_id_ctx *sdap_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *iface);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_get_addrs_recv(struct tevent_req *req,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek TALLOC_CTX *mem_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sss_iface_addr **_addresses);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstruct sdap_dyndns_update_state {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_context *ev;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct be_resolv_ctx *be_res;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct dp_option *opts;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *hostname;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *realm;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *servername;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek int ttl;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sss_iface_addr *addresses;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct sss_iface_addr *dns_addrlist;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek uint8_t remove_af;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek bool update_ptr;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek bool check_diff;
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek enum be_nsupdate_auth auth_type;
76604931b11594394a05df10f8370a1b8bb3e54bPavel Reichl bool fallback_mode;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek char *update_msg;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl struct sss_iface_addr *ptr_addr_iter;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl bool del_phase;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek};
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void sdap_dyndns_update_addrs_done(struct tevent_req *subreq);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic void sdap_dyndns_dns_addrs_done(struct tevent_req *subreq);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic errno_t sdap_dyndns_addrs_diff(struct sdap_dyndns_update_state *state,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek bool *_do_update);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t sdap_dyndns_update_step(struct tevent_req *req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic errno_t sdap_dyndns_update_ptr_step(struct tevent_req *req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void sdap_dyndns_update_done(struct tevent_req *subreq);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic void sdap_dyndns_update_ptr_done(struct tevent_req *subreq);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlstatic errno_t
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlsdap_dyndns_next_ptr_record(struct sdap_dyndns_update_state *state,
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl struct tevent_req *req);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlstatic struct sss_iface_addr*
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlsdap_get_address_to_delete(struct sss_iface_addr *address_it,
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl uint8_t remove_af);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstruct tevent_req *
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_context *ev,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct be_ctx *be_ctx,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct dp_option *opts,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_id_ctx *sdap_ctx,
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek enum be_nsupdate_auth auth_type,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *ifname,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *hostname,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *realm,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const int ttl,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek bool check_diff)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *subreq;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_update_state *state;
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek const char *conf_servername;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sdap_dyndns_update_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (req == NULL) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return NULL;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->check_diff = check_diff;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state->update_ptr = dp_opt_get_bool(opts, DP_OPT_DYNDNS_UPDATE_PTR);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->hostname = hostname;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->realm = realm;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl state->servername = NULL;
76604931b11594394a05df10f8370a1b8bb3e54bPavel Reichl state->fallback_mode = false;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->ttl = ttl;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->be_res = be_ctx->be_res;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->ev = ev;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state->opts = opts;
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek state->auth_type = auth_type;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = NULL;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->del_phase = true;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
7c3cc1ee2914bc7b38a992c1af254fc76af5a1adPavel Reichl /* fallback servername is overriden by user option */
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek conf_servername = dp_opt_get_string(opts, DP_OPT_DYNDNS_SERVER);
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek if (conf_servername != NULL) {
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek state->servername = conf_servername;
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek }
8145ab51b05aa86b2f1a21b49383f55e50b0a2e3Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ifname) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Unless one family is restricted, just replace all
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek * address families during the update
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek switch (state->be_res->family_order) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek case IPV4_ONLY:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->remove_af |= DYNDNS_REMOVE_A;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek break;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek case IPV6_ONLY:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->remove_af |= DYNDNS_REMOVE_AAAA;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek break;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek case IPV4_FIRST:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek case IPV6_FIRST:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->remove_af |= (DYNDNS_REMOVE_A |
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DYNDNS_REMOVE_AAAA);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek break;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek } else {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* If the interface isn't specified, we ONLY want to have the address
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek * that's connected to the LDAP server stored, so we need to check
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek * (and later remove) both address families.
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->remove_af = (DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek subreq = sdap_dyndns_get_addrs_send(state, state->ev, sdap_ctx, ifname);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (!subreq) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = EIO;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek goto done;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_update_addrs_done, req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekdone:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_post(req, ev);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_update_addrs_done(struct tevent_req *subreq)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_update_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sdap_dyndns_get_addrs_recv(subreq, state, &state->addresses);
f55d45b931ce6c01e005ae94a69e93abda0d2f1cLukas Slebodnik talloc_zfree(subreq);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (state->check_diff || state->update_ptr) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek /* Check if we need the update at all. In case we are updating the PTR
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek * records as well, we need to know the old addresses to be able to
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek * reliably delete the PTR records */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek subreq = nsupdate_get_addrs_send(state, state->ev,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state->be_res, state->hostname);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (subreq == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Can't initiate address check\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_dns_addrs_done, req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Perform update */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sdap_dyndns_update_step(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Execution will resume in sdap_dyndns_update_done */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozeksdap_dyndns_dns_addrs_done(struct tevent_req *subreq)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_update_state *state;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek bool do_update;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = nsupdate_get_addrs_recv(subreq, state, &state->dns_addrlist, NULL);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek talloc_zfree(subreq);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not receive list of current addresses [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (state->check_diff) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = sdap_dyndns_addrs_diff(state, &do_update);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Could not check the diff between DNS "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "and current addresses [%d]: %s\n", ret, strerror(ret));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_error(req, ret);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (do_update == false) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "No DNS update needed, addresses did not change\n");
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_done(req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Detected IP addresses change, will perform an update\n");
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek /* Either we needed the addresses for updating PTR records only or
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek * the addresses have changed (or both) */
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = sdap_dyndns_update_step(req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Could not start the update [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_error(req, ret);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek}
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic errno_t
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozeksdap_dyndns_addrs_diff(struct sdap_dyndns_update_state *state, bool *_do_update)
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek{
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek errno_t ret;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek int i;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek char **str_dnslist = NULL, **str_local_list = NULL;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek char **dns_only = NULL, **local_only = NULL;
c93a3ac5ff2e037471d8d6b2e61e2578fdc09315Lukas Slebodnik bool do_update = false;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sss_iface_addr_list_as_str_list(state,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state->dns_addrlist, &str_dnslist);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Converting DNS IP addresses to strings failed: [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return ret;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = sss_iface_addr_list_as_str_list(state,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state->addresses, &str_local_list);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Converting local IP addresses to strings failed: [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Compare the lists */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = diff_string_lists(state, str_dnslist, str_local_list,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek &dns_only, &local_only, NULL);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "diff_string_lists failed: [%d]: %s\n", ret, sss_strerror(ret));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (dns_only) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek for (i=0; dns_only[i]; i++) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Address in DNS only: %s\n", dns_only[i]);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek do_update = true;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (local_only) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek for (i=0; local_only[i]; i++) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Address on localhost only: %s\n", local_only[i]);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek do_update = true;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek *_do_update = do_update;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_update_step(struct tevent_req *req)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_update_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *servername;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl const char *realm;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *subreq;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek servername = NULL;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl realm = NULL;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl if (state->fallback_mode) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek servername = state->servername;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl realm = state->realm;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl ret = be_nsupdate_create_fwd_msg(state, realm, servername,
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl state->hostname,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state->ttl, state->remove_af,
d88694443f17cb815cfd741b991ddf476908cde7Lukas Slebodnik state->addresses,
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek &state->update_msg);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Fork a child process to perform the DNS update */
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek subreq = be_nsupdate_send(state, state->ev, state->auth_type,
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek state->update_msg,
e45b81abe0aafa8a04bd64ac31a2fac63ce675b7Jakub Hrozek dp_opt_get_bool(state->opts,
e45b81abe0aafa8a04bd64ac31a2fac63ce675b7Jakub Hrozek DP_OPT_DYNDNS_FORCE_TCP));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (subreq == NULL) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EIO;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_update_done, req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_update_done(struct tevent_req *subreq)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek int child_status;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_update_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = be_nsupdate_recv(subreq, &child_status);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek talloc_zfree(subreq);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* If the update didn't succeed, we can retry using the server name */
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl if (state->fallback_mode == false
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl && WIFEXITED(child_status)
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl && WEXITSTATUS(child_status) != 0) {
76604931b11594394a05df10f8370a1b8bb3e54bPavel Reichl state->fallback_mode = true;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl "nsupdate failed, retrying.\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sdap_dyndns_update_step(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret == EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (state->update_ptr == false) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "No PTR update requested, done\n");
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_done(req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek talloc_free(state->update_msg);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* init iterator for addresses to be deleted */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = sdap_get_address_to_delete(state->dns_addrlist,
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->remove_af);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (state->ptr_addr_iter == NULL) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* init iterator for addresses to be added */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->del_phase = false;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = state->addresses;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = sdap_dyndns_update_ptr_step(req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_error(req, ret);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek /* Execution will resume in sdap_dyndns_update_ptr_done */
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek}
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlstatic bool remove_addr(int address_family, uint8_t remove_af)
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl{
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl bool ret = false;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl switch(address_family) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl case AF_INET:
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (remove_af & DYNDNS_REMOVE_A) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = true;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl break;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl case AF_INET6:
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (remove_af & DYNDNS_REMOVE_AAAA) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = true;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl break;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl default:
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n");
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = false;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return ret;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl}
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlstatic struct sss_iface_addr*
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlsdap_get_address_to_delete(struct sss_iface_addr *address_it,
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl uint8_t remove_af)
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl{
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl struct sockaddr_storage* address;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl while (address_it != NULL) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl address = sss_iface_addr_get_address(address_it);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* skip addresses that are not to be deleted */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (remove_addr(address->ss_family, remove_af)) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl break;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl address_it = sss_iface_addr_get_next(address_it);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return address_it;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl}
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic errno_t
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozeksdap_dyndns_update_ptr_step(struct tevent_req *req)
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek{
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek errno_t ret;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct sdap_dyndns_update_state *state;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek const char *servername;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl const char *realm;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct tevent_req *subreq;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl struct sockaddr_storage *address;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek servername = NULL;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl realm = NULL;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl if (state->fallback_mode == true) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek servername = state->servername;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl realm = state->realm;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl address = sss_iface_addr_get_address(state->ptr_addr_iter);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (address == NULL) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return EIO;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl ret = be_nsupdate_create_ptr_msg(state, realm, servername, state->hostname,
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl state->ttl, address, state->del_phase,
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl &state->update_msg);
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n");
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return ret;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek /* Fork a child process to perform the DNS update */
e15a9f81eb33066937710d7dee6976a3646d119cJakub Hrozek subreq = be_nsupdate_send(state, state->ev, state->auth_type,
e45b81abe0aafa8a04bd64ac31a2fac63ce675b7Jakub Hrozek state->update_msg,
e45b81abe0aafa8a04bd64ac31a2fac63ce675b7Jakub Hrozek dp_opt_get_bool(state->opts,
e45b81abe0aafa8a04bd64ac31a2fac63ce675b7Jakub Hrozek DP_OPT_DYNDNS_FORCE_TCP));
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (subreq == NULL) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return EIO;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_update_ptr_done, req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return EOK;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek}
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozekstatic void
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozeksdap_dyndns_update_ptr_done(struct tevent_req *subreq)
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek{
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek errno_t ret;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek int child_status;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct tevent_req *req;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek struct sdap_dyndns_update_state *state;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_update_state);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = be_nsupdate_recv(subreq, &child_status);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek talloc_zfree(subreq);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret != EOK) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek /* If the update didn't succeed, we can retry using the server name */
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl if (state->fallback_mode == false
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl && WIFEXITED(child_status)
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl && WEXITSTATUS(child_status) != 0) {
76604931b11594394a05df10f8370a1b8bb3e54bPavel Reichl state->fallback_mode = true;
12a1c64105ff56b39e197264fec2d9aba6b84185Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE, "nsupdate failed, retrying\n");
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek ret = sdap_dyndns_update_ptr_step(req);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek if (ret == EOK) {
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = sdap_dyndns_next_ptr_record(state, req);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (ret == EAGAIN) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek tevent_req_error(req, ret);
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek return;
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek }
38ebc764eeb7693e0c4f0894d6687e54fbba871bJakub Hrozek
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = sdap_dyndns_next_ptr_record(state, req);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (ret == EAGAIN) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_done(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlstatic errno_t
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichlsdap_dyndns_next_ptr_record(struct sdap_dyndns_update_state *state,
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl struct tevent_req *req)
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl{
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl errno_t ret;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (state->del_phase) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* iterate to next address to delete */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = sdap_get_address_to_delete(
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl sss_iface_addr_get_next(state->ptr_addr_iter), state->remove_af);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (state->ptr_addr_iter == NULL) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* init iterator for addresses to be added */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->del_phase = false;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = state->addresses;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl } else {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl /* iterate to next address to add */
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->ptr_addr_iter = sss_iface_addr_get_next(state->ptr_addr_iter);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (state->ptr_addr_iter != NULL) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl state->fallback_mode = false;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl ret = sdap_dyndns_update_ptr_step(req);
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl if (ret == EOK) {
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return EAGAIN;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl }
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl return EOK;
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl}
eeac17ebbe38f16deaa8599231cccfc97aaac85cPavel Reichl
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekerrno_t
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_update_recv(struct tevent_req *req)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek/* A request to get addresses to update with */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstruct sdap_dyndns_get_addrs_state {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_id_op* sdap_op;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sss_iface_addr *addresses;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek};
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void sdap_dyndns_get_addrs_done(struct tevent_req *subreq);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_handle *sh);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
038b9ba28a618e3e553803da632116a040b94034Pavel Reichlstatic errno_t get_ifaces_addrs(TALLOC_CTX *mem_ctx,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl const char *iface,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl struct sss_iface_addr **_result)
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl{
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl struct sss_iface_addr *result_addrs = NULL;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl struct sss_iface_addr *intf_addrs;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl TALLOC_CTX *tmp_ctx;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl char **list_of_intfs;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl int num_of_intfs;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl errno_t ret;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl int i;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl tmp_ctx = talloc_new(NULL);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl if (tmp_ctx == NULL) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret = ENOMEM;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl goto done;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl }
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret = split_on_separator(tmp_ctx, iface, ',', true, true, &list_of_intfs,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl &num_of_intfs);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl if (ret != EOK) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl "Parsing names of interfaces failed - %d:[%s].\n",
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret, sss_strerror(ret));
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl goto done;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl }
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl for (i = 0; i < num_of_intfs; i++) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret = sss_iface_addr_list_get(tmp_ctx, list_of_intfs[i], &intf_addrs);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl if (ret == EOK) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl if (result_addrs != NULL) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl /* If there is already an existing list, head of this existing
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl * list will be considered as parent talloc context for the
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl * new list.
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl */
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl talloc_steal(result_addrs, intf_addrs);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl }
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl sss_iface_addr_concatenate(&result_addrs, intf_addrs);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl } else if (ret == ENOENT) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl /* non-critical failure */
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl "Cannot get interface %s or there are no addresses "
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl "bind to it.\n", list_of_intfs[i]);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl } else {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl DEBUG(SSSDBG_OP_FAILURE,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl "Cannot get list of addresses from interface %s - %d:[%s]\n",
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl list_of_intfs[i], ret, sss_strerror(ret));
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl goto done;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl }
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl }
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret = EOK;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl *_result = talloc_steal(mem_ctx, result_addrs);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
038b9ba28a618e3e553803da632116a040b94034Pavel Reichldone:
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl talloc_free(tmp_ctx);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl return ret;
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl}
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic struct tevent_req *
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_context *ev,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_id_ctx *sdap_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek const char *iface)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *subreq;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_get_addrs_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_create(mem_ctx, &state,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_get_addrs_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (req == NULL) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return NULL;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (iface) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret = get_ifaces_addrs(state, iface, &state->addresses);
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl if (ret != EOK || state->addresses == NULL) {
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl "get_ifaces_addrs() failed: %d:[%s]\n",
038b9ba28a618e3e553803da632116a040b94034Pavel Reichl ret, sss_strerror(ret));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* We're done. Just fake an async request completion */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek goto done;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Detect DYNDNS address from LDAP connection */
dcb44c39dda9699cdd6488fd116a51ced0687de3Jakub Hrozek state->sdap_op = sdap_id_op_create(state, sdap_ctx->conn->conn_cache);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (!state->sdap_op) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = ENOMEM;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek goto done;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (!subreq) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = EIO;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek goto done;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_get_addrs_done, req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = EAGAIN;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekdone:
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret == EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_done(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_post(req, ev);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek } else if (ret != EAGAIN) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_post(req, ev);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* EAGAIN - resolution in progress */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic void
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_get_addrs_done(struct tevent_req *subreq)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno_t ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek int dp_error;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct tevent_req *req;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_get_addrs_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_get_addrs_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sdap_id_op_connect_recv(subreq, &dp_error);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek talloc_zfree(subreq);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (dp_error == DP_ERR_OFFLINE) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "No LDAP server is available, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "dynamic DNS update is skipped in offline mode.\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = ERR_DYNDNS_OFFLINE;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek } else {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to connect to LDAP server: [%d](%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = sdap_dyndns_add_ldap_conn(state, sdap_id_op_handle(state->sdap_op));
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses from LDAP connection\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_error(req, ret);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Got the address! Done! */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek tevent_req_done(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_handle *sh)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek int ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek int fd;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sockaddr_storage ss;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek socklen_t ss_len = sizeof(ss);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (sh == NULL) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EINVAL;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek /* Get the file descriptor for the primary LDAP connection */
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = get_fd_from_ldap(sh->ldap, &fd);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret != EOK) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek errno = 0;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = getsockname(fd, (struct sockaddr *) &ss, &ss_len);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (ret == -1) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get socket name\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return ret;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Connection to LDAP is neither IPv4 nor IPv6\n");
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EIO;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek }
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl ret = sss_get_dualstack_addresses(state, (struct sockaddr *) &ss,
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl &state->addresses);
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl if (ret != EOK) {
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl "sss_get_dualstack_addresses failed: %d:[%s]\n",
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl ret, sss_strerror(ret));
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl return ret;
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl }
b0a8ed519554f8896e35812e0759862c33f157fePavel Reichl
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozekstatic errno_t
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozeksdap_dyndns_get_addrs_recv(struct tevent_req *req,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek TALLOC_CTX *mem_ctx,
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sss_iface_addr **_addresses)
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek{
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek struct sdap_dyndns_get_addrs_state *state;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek state = tevent_req_data(req, struct sdap_dyndns_get_addrs_state);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek *_addresses = talloc_steal(mem_ctx, state->addresses);
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek return EOK;
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek}
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekstruct sdap_dyndns_timer_state {
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_context *ev;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_id_ctx *sdap_ctx;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct be_nsupdate_ctx *dyndns_ctx;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_id_op *sdap_op;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek};
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekstatic void sdap_dyndns_timer_conn_done(struct tevent_req *req);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekstruct tevent_req *
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozeksdap_dyndns_timer_conn_send(TALLOC_CTX *mem_ctx,
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_context *ev,
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_id_ctx *sdap_ctx,
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct be_nsupdate_ctx *dyndns_ctx)
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek{
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_dyndns_timer_state *state;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_req *req;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_req *subreq;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek errno_t ret;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sdap_dyndns_timer_state);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek if (req == NULL) {
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek return NULL;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek }
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek state->ev = ev;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek state->sdap_ctx = sdap_ctx;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek state->dyndns_ctx = dyndns_ctx;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek /* In order to prevent the connection triggering an
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek * online callback which would in turn trigger a concurrent DNS
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek * update
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek */
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek state->dyndns_ctx->timer_in_progress = true;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek /* Make sure to have a valid LDAP connection */
dcb44c39dda9699cdd6488fd116a51ced0687de3Jakub Hrozek state->sdap_op = sdap_id_op_create(state, state->sdap_ctx->conn->conn_cache);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek if (state->sdap_op == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek ret = ENOMEM;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek goto fail;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek }
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek if (subreq == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek ret = ENOMEM;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek goto fail;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek }
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_set_callback(subreq, sdap_dyndns_timer_conn_done, req);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek return req;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekfail:
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek dyndns_ctx->timer_in_progress = false;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek be_nsupdate_timer_schedule(ev, dyndns_ctx);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_error(req, ret);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_post(req, ev);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek return req;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek}
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekstatic void
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozeksdap_dyndns_timer_conn_done(struct tevent_req *subreq)
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek{
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct tevent_req);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_dyndns_timer_state *state = tevent_req_data(req,
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek struct sdap_dyndns_timer_state);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek errno_t ret;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek int dp_error;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek state->dyndns_ctx->timer_in_progress = false;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek ret = sdap_id_op_connect_recv(subreq, &dp_error);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek talloc_zfree(subreq);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek if (ret != EOK) {
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek if (dp_error == DP_ERR_OFFLINE) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "No server is available, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "dynamic DNS update is skipped in offline mode.\n");
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek /* Another timer will be scheduled when provider goes online */
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_error(req, ERR_DYNDNS_OFFLINE);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek } else {
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to connect to LDAP server: [%d](%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek /* Just schedule another dyndns retry */
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek be_nsupdate_timer_schedule(state->ev, state->dyndns_ctx);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_error(req, ERR_NETWORK_IO);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek }
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek return;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek }
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek /* All OK, schedule another refresh and let the user call its
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek * provider-specific update
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek */
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek be_nsupdate_timer_schedule(state->ev, state->dyndns_ctx);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek tevent_req_done(req);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek}
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozekerrno_t
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozeksdap_dyndns_timer_conn_recv(struct tevent_req *req)
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek{
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek return EOK;
33df734b39538eeb870b118b7feea76f90bb004bJakub Hrozek}