LCOV - code coverage report
Current view: top level - providers/ipa - ipa_dyndns.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 94 0.0 %
Date: 2016-06-29 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     ipa_dyndns.c
       5             : 
       6             :     Authors:
       7             :         Stephen Gallagher <sgallagh@redhat.com>
       8             : 
       9             :     Copyright (C) 2010 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include <ctype.h>
      26             : #include "util/util.h"
      27             : #include "providers/ldap/sdap_dyndns.h"
      28             : #include "providers/ipa/ipa_common.h"
      29             : #include "providers/ipa/ipa_dyndns.h"
      30             : #include "providers/data_provider.h"
      31             : #include "providers/be_dyndns.h"
      32             : 
      33             : void ipa_dyndns_update(void *pvt);
      34             : 
      35           0 : errno_t ipa_dyndns_init(struct be_ctx *be_ctx,
      36             :                         struct ipa_options *ctx)
      37             : {
      38             :     errno_t ret;
      39             : 
      40           0 :     ctx->be_res = be_ctx->be_res;
      41           0 :     if (ctx->be_res == NULL) {
      42           0 :         DEBUG(SSSDBG_OP_FAILURE, "Resolver must be initialized in order "
      43             :               "to use the IPA dynamic DNS updates\n");
      44           0 :         return EINVAL;
      45             :     }
      46             : 
      47           0 :     ret = be_nsupdate_init_timer(ctx->dyndns_ctx, be_ctx->ev,
      48             :                                  ipa_dyndns_timer, ctx);
      49           0 :     if (ret != EOK) {
      50           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up periodic update\n");
      51           0 :         return ret;
      52             :     }
      53             : 
      54           0 :     ret = be_add_online_cb(be_ctx, be_ctx,
      55             :                            ipa_dyndns_update,
      56             :                            ctx, NULL);
      57           0 :     if (ret != EOK) {
      58           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up online callback\n");
      59           0 :         return ret;
      60             :     }
      61             : 
      62           0 :     return EOK;
      63             : }
      64             : 
      65             : struct ipa_dyndns_timer_ctx {
      66             :     struct sdap_id_op *sdap_op;
      67             :     struct tevent_context *ev;
      68             : 
      69             :     struct ipa_options *ctx;
      70             : };
      71             : 
      72             : static void ipa_dyndns_timer_connected(struct tevent_req *req);
      73             : 
      74           0 : void ipa_dyndns_timer(void *pvt)
      75             : {
      76           0 :     struct ipa_options *ctx = talloc_get_type(pvt, struct ipa_options);
      77           0 :     struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx;
      78             :     struct tevent_req *req;
      79             : 
      80           0 :     req = sdap_dyndns_timer_conn_send(ctx, sdap_ctx->be->ev, sdap_ctx,
      81             :                                       ctx->dyndns_ctx);
      82           0 :     if (req == NULL) {
      83           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
      84             :         /* Not much we can do. Just attempt to reschedule */
      85           0 :         be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx);
      86           0 :         return;
      87             :     }
      88           0 :     tevent_req_set_callback(req, ipa_dyndns_timer_connected, ctx);
      89             : }
      90             : 
      91           0 : static void ipa_dyndns_timer_connected(struct tevent_req *req)
      92             : {
      93             :     errno_t ret;
      94           0 :     struct ipa_options *ctx = tevent_req_callback_data(req,
      95             :                                                 struct ipa_options);
      96             : 
      97           0 :     ret = sdap_dyndns_timer_conn_recv(req);
      98           0 :     talloc_zfree(req);
      99           0 :     if (ret != EOK) {
     100           0 :         DEBUG(SSSDBG_OP_FAILURE,
     101             :               "Failed to connect to IPA: [%d](%s)\n",
     102             :               ret, sss_strerror(ret));
     103           0 :         return;
     104             :     }
     105             : 
     106           0 :     return ipa_dyndns_update(ctx);
     107             : }
     108             : 
     109             : static struct tevent_req *ipa_dyndns_update_send(struct ipa_options *ctx);
     110             : static errno_t ipa_dyndns_update_recv(struct tevent_req *req);
     111             : 
     112             : static void ipa_dyndns_nsupdate_done(struct tevent_req *subreq);
     113             : 
     114           0 : void ipa_dyndns_update(void *pvt)
     115             : {
     116           0 :     struct ipa_options *ctx = talloc_get_type(pvt, struct ipa_options);
     117           0 :     struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx;
     118             : 
     119             :     /* Schedule timer after provider went offline */
     120           0 :     be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx);
     121             : 
     122           0 :     struct tevent_req *req = ipa_dyndns_update_send(ctx);
     123           0 :     if (req == NULL) {
     124           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not update DNS\n");
     125           0 :         return;
     126             :     }
     127           0 :     tevent_req_set_callback(req, ipa_dyndns_nsupdate_done, NULL);
     128             : }
     129             : 
     130           0 : static void ipa_dyndns_nsupdate_done(struct tevent_req *req)
     131             : {
     132           0 :     int ret = ipa_dyndns_update_recv(req);
     133           0 :     talloc_free(req);
     134           0 :     if (ret != EOK) {
     135           0 :         DEBUG(SSSDBG_OP_FAILURE, "Updating DNS entry failed [%d]: %s\n",
     136             :               ret, sss_strerror(ret));
     137           0 :         return;
     138             :     }
     139             : 
     140           0 :     DEBUG(SSSDBG_OP_FAILURE, "DNS update finished\n");
     141             : }
     142             : 
     143             : struct ipa_dyndns_update_state {
     144             :     struct ipa_options *ipa_ctx;
     145             : };
     146             : 
     147             : static void ipa_dyndns_sdap_update_done(struct tevent_req *subreq);
     148             : 
     149             : static struct tevent_req *
     150           0 : ipa_dyndns_update_send(struct ipa_options *ctx)
     151             : {
     152             :     int ret;
     153             :     struct ipa_dyndns_update_state *state;
     154             :     struct tevent_req *req, *subreq;
     155           0 :     struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx;
     156             : 
     157           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Performing update\n");
     158             : 
     159           0 :     req = tevent_req_create(ctx, &state, struct ipa_dyndns_update_state);
     160           0 :     if (req == NULL) {
     161           0 :         return NULL;
     162             :     }
     163           0 :     state->ipa_ctx = ctx;
     164             : 
     165           0 :     if (ctx->dyndns_ctx->last_refresh + 60 > time(NULL) ||
     166           0 :         ctx->dyndns_ctx->timer_in_progress) {
     167           0 :         DEBUG(SSSDBG_FUNC_DATA, "Last periodic update ran recently or timer "
     168             :               "in progress, not scheduling another update\n");
     169           0 :         tevent_req_done(req);
     170           0 :         tevent_req_post(req, sdap_ctx->be->ev);
     171           0 :         return req;
     172             :     }
     173           0 :     state->ipa_ctx->dyndns_ctx->last_refresh = time(NULL);
     174             : 
     175           0 :     if (strncmp(ctx->service->sdap->uri,
     176             :                 "ldap://", 7) != 0) {
     177           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected format of LDAP URI.\n");
     178           0 :         ret = EIO;
     179           0 :         goto done;
     180             :     }
     181             : 
     182           0 :     subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev,
     183             :                                      sdap_ctx->be,
     184           0 :                                      ctx->dyndns_ctx->opts,
     185             :                                      sdap_ctx,
     186           0 :                                      ctx->dyndns_ctx->auth_type,
     187           0 :                                      dp_opt_get_string(ctx->dyndns_ctx->opts,
     188             :                                                        DP_OPT_DYNDNS_IFACE),
     189           0 :                                      dp_opt_get_string(ctx->basic,
     190             :                                                        IPA_HOSTNAME),
     191           0 :                                      dp_opt_get_string(ctx->basic,
     192             :                                                        IPA_KRB5_REALM),
     193           0 :                                      dp_opt_get_int(ctx->dyndns_ctx->opts,
     194             :                                                     DP_OPT_DYNDNS_TTL),
     195             :                                      true);
     196           0 :     if (!subreq) {
     197           0 :         ret = EIO;
     198           0 :         DEBUG(SSSDBG_OP_FAILURE,
     199             :               "sdap_id_op_connect_send failed: [%d](%s)\n",
     200             :                ret, sss_strerror(ret));
     201           0 :         goto done;
     202             :     }
     203           0 :     tevent_req_set_callback(subreq, ipa_dyndns_sdap_update_done, req);
     204             : 
     205           0 :     ret = EOK;
     206             : done:
     207           0 :     if (ret != EOK) {
     208           0 :         tevent_req_error(req, ret);
     209           0 :         tevent_req_post(req, sdap_ctx->be->ev);
     210             :     }
     211           0 :     return req;
     212             : }
     213             : 
     214           0 : static void ipa_dyndns_sdap_update_done(struct tevent_req *subreq)
     215             : {
     216           0 :     struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
     217             :     errno_t ret;
     218             : 
     219           0 :     ret = sdap_dyndns_update_recv(subreq);
     220           0 :     talloc_zfree(subreq);
     221           0 :     if (ret != EOK) {
     222           0 :         DEBUG(SSSDBG_OP_FAILURE,
     223             :               "Dynamic DNS update failed [%d]: %s\n", ret, sss_strerror(ret));
     224           0 :         tevent_req_error(req, ret);
     225           0 :         return;
     226             :     }
     227             : 
     228           0 :     tevent_req_done(req);
     229             : }
     230             : 
     231           0 : static errno_t ipa_dyndns_update_recv(struct tevent_req *req)
     232             : {
     233           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     234             : 
     235           0 :     return EOK;
     236             : }

Generated by: LCOV version 1.10