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

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jan Cholasta <jcholast@redhat.com>
       4             : 
       5             :     Copyright (C) 2012 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "util/util.h"
      22             : #include "util/crypto/sss_crypto.h"
      23             : #include "db/sysdb_ssh.h"
      24             : #include "providers/ldap/ldap_common.h"
      25             : #include "providers/ipa/ipa_common.h"
      26             : #include "providers/ipa/ipa_hostid.h"
      27             : #include "providers/ipa/ipa_hosts.h"
      28             : 
      29             : struct hosts_get_state {
      30             :     struct tevent_context *ev;
      31             :     struct ipa_hostid_ctx *ctx;
      32             :     struct sdap_id_op *op;
      33             :     struct sss_domain_info *domain;
      34             :     const char *name;
      35             :     const char *alias;
      36             : 
      37             :     size_t count;
      38             :     struct sysdb_attrs **hosts;
      39             :     int dp_error;
      40             : };
      41             : 
      42             : static errno_t
      43             : hosts_get_retry(struct tevent_req *req);
      44             : static void
      45             : hosts_get_connect_done(struct tevent_req *subreq);
      46             : static void
      47             : hosts_get_done(struct tevent_req *subreq);
      48             : 
      49             : struct tevent_req *
      50           0 : hosts_get_send(TALLOC_CTX *memctx,
      51             :                struct tevent_context *ev,
      52             :                struct ipa_hostid_ctx *hostid_ctx,
      53             :                const char *name,
      54             :                const char *alias)
      55             : {
      56             :     struct tevent_req *req;
      57             :     struct hosts_get_state *state;
      58             :     struct sdap_id_ctx *ctx;
      59             :     errno_t ret;
      60             : 
      61           0 :     ctx = hostid_ctx->sdap_id_ctx;
      62             : 
      63           0 :     req = tevent_req_create(memctx, &state, struct hosts_get_state);
      64           0 :     if (!req) return NULL;
      65             : 
      66           0 :     state->ev = ev;
      67           0 :     state->ctx = hostid_ctx;
      68           0 :     state->dp_error = DP_ERR_FATAL;
      69             : 
      70           0 :     state->op = sdap_id_op_create(state, ctx->conn->conn_cache);
      71           0 :     if (!state->op) {
      72           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
      73           0 :         ret = ENOMEM;
      74           0 :         goto fail;
      75             :     }
      76             : 
      77           0 :     state->domain = ctx->be->domain;
      78           0 :     state->name = name;
      79           0 :     state->alias = alias;
      80             : 
      81           0 :     ret = hosts_get_retry(req);
      82           0 :     if (ret != EOK) {
      83           0 :         goto fail;
      84             :     }
      85             : 
      86           0 :     return req;
      87             : 
      88             : fail:
      89           0 :     tevent_req_error(req, ret);
      90           0 :     tevent_req_post(req, ev);
      91           0 :     return req;
      92             : }
      93             : 
      94             : static errno_t
      95           0 : hosts_get_retry(struct tevent_req *req)
      96             : {
      97           0 :     struct hosts_get_state *state = tevent_req_data(req,
      98             :                                                     struct hosts_get_state);
      99             :     struct tevent_req *subreq;
     100           0 :     errno_t ret = EOK;
     101             : 
     102           0 :     subreq = sdap_id_op_connect_send(state->op, state, &ret);
     103           0 :     if (!subreq) {
     104           0 :         return ret;
     105             :     }
     106             : 
     107           0 :     tevent_req_set_callback(subreq, hosts_get_connect_done, req);
     108           0 :     return EOK;
     109             : }
     110             : 
     111             : static void
     112           0 : hosts_get_connect_done(struct tevent_req *subreq)
     113             : {
     114           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     115             :                                                       struct tevent_req);
     116           0 :     struct hosts_get_state *state = tevent_req_data(req,
     117             :                                                     struct hosts_get_state);
     118           0 :     int dp_error = DP_ERR_FATAL;
     119             :     errno_t ret;
     120             : 
     121           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     122           0 :     talloc_zfree(subreq);
     123             : 
     124           0 :     if (ret != EOK) {
     125           0 :         state->dp_error = dp_error;
     126           0 :         tevent_req_error(req, ret);
     127           0 :         return;
     128             :     }
     129             : 
     130           0 :     subreq = ipa_host_info_send(state, state->ev,
     131             :                                 sdap_id_op_handle(state->op),
     132           0 :                                 state->ctx->sdap_id_ctx->opts, state->name,
     133           0 :                                 state->ctx->ipa_opts->host_map, NULL,
     134           0 :                                 state->ctx->host_search_bases);
     135           0 :     if (!subreq) {
     136           0 :         tevent_req_error(req, ENOMEM);
     137           0 :         return;
     138             :     }
     139           0 :     tevent_req_set_callback(subreq, hosts_get_done, req);
     140             : }
     141             : 
     142             : static void
     143           0 : hosts_get_done(struct tevent_req *subreq)
     144             : {
     145           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     146             :                                                       struct tevent_req);
     147           0 :     struct hosts_get_state *state = tevent_req_data(req,
     148             :                                                     struct hosts_get_state);
     149           0 :     int dp_error = DP_ERR_FATAL;
     150             :     errno_t ret;
     151             :     struct sysdb_attrs *attrs;
     152           0 :     time_t now = time(NULL);
     153             : 
     154           0 :     ret = ipa_host_info_recv(subreq, state,
     155             :                              &state->count, &state->hosts,
     156             :                              NULL, NULL);
     157           0 :     talloc_zfree(subreq);
     158             : 
     159           0 :     ret = sdap_id_op_done(state->op, ret, &dp_error);
     160           0 :     if (dp_error == DP_ERR_OK && ret != EOK) {
     161             :         /* retry */
     162           0 :         ret = hosts_get_retry(req);
     163           0 :         if (ret != EOK) {
     164           0 :             goto done;
     165             :         }
     166           0 :         return;
     167             :     }
     168             : 
     169           0 :     if (ret != EOK && ret != ENOENT) {
     170           0 :         goto done;
     171             :     }
     172             : 
     173           0 :     if (state->count == 0) {
     174           0 :         DEBUG(SSSDBG_OP_FAILURE,
     175             :               "No host with name [%s] found.\n", state->name);
     176             : 
     177           0 :         ret = sysdb_delete_ssh_host(state->domain, state->name);
     178           0 :         if (ret != EOK && ret != ENOENT) {
     179           0 :             goto done;
     180             :         }
     181             : 
     182           0 :         ret = EINVAL;
     183           0 :         goto done;
     184             :     }
     185             : 
     186           0 :     if (state->count > 1) {
     187           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     188             :               "Found more than one host with name [%s].\n", state->name);
     189           0 :         ret = EINVAL;
     190           0 :         goto done;
     191             :     }
     192             : 
     193           0 :     attrs = sysdb_new_attrs(state);
     194           0 :     if (!attrs) {
     195           0 :         ret = ENOMEM;
     196           0 :         goto done;
     197             :     }
     198             : 
     199             :     /* we are interested only in the host keys */
     200           0 :     ret = sysdb_attrs_copy_values(state->hosts[0], attrs, SYSDB_SSH_PUBKEY);
     201           0 :     if (ret != EOK) {
     202           0 :         goto done;
     203             :     }
     204             : 
     205           0 :     ret = sysdb_store_ssh_host(state->domain, state->name, state->alias,
     206           0 :                                state->domain->ssh_host_timeout, now, attrs);
     207           0 :     if (ret != EOK) {
     208           0 :         goto done;
     209             :     }
     210             : 
     211           0 :     dp_error = DP_ERR_OK;
     212             : 
     213             : done:
     214           0 :     state->dp_error = dp_error;
     215           0 :     if (ret == EOK) {
     216           0 :         tevent_req_done(req);
     217             :     } else {
     218           0 :         tevent_req_error(req, ret);
     219             :     }
     220             : }
     221             : 
     222             : static errno_t
     223           0 : hosts_get_recv(struct tevent_req *req,
     224             :                int *dp_error_out)
     225             : {
     226           0 :     struct hosts_get_state *state = tevent_req_data(req,
     227             :                                                     struct hosts_get_state);
     228             : 
     229           0 :     if (dp_error_out) {
     230           0 :         *dp_error_out = state->dp_error;
     231             :     }
     232             : 
     233           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     234             : 
     235           0 :     return EOK;
     236             : }
     237             : 
     238             : struct ipa_hostid_handler_state {
     239             :     struct dp_reply_std reply;
     240             : };
     241             : 
     242             : static void ipa_hostid_handler_done(struct tevent_req *subreq);
     243             : 
     244             : struct tevent_req *
     245           0 : ipa_hostid_handler_send(TALLOC_CTX *mem_ctx,
     246             :                        struct ipa_hostid_ctx *hostid_ctx,
     247             :                        struct dp_hostid_data *data,
     248             :                        struct dp_req_params *params)
     249             : {
     250             :     struct ipa_hostid_handler_state *state;
     251             :     struct tevent_req *subreq;
     252             :     struct tevent_req *req;
     253             :     errno_t ret;
     254             : 
     255           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_hostid_handler_state);
     256           0 :     if (req == NULL) {
     257           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     258           0 :         return NULL;
     259             :     }
     260             : 
     261           0 :     subreq = hosts_get_send(state, params->ev, hostid_ctx,
     262             :                             data->name, data->alias);
     263           0 :     if (subreq == NULL) {
     264           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request\n");
     265           0 :         ret = ENOMEM;
     266           0 :         goto immediately;
     267             :     }
     268             : 
     269           0 :     tevent_req_set_callback(subreq, ipa_hostid_handler_done, req);
     270             : 
     271           0 :     return req;
     272             : 
     273             : immediately:
     274           0 :     dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
     275             : 
     276             :     /* TODO For backward compatibility we always return EOK to DP now. */
     277           0 :     tevent_req_done(req);
     278           0 :     tevent_req_post(req, params->ev);
     279             : 
     280           0 :     return req;
     281             : }
     282             : 
     283           0 : static void ipa_hostid_handler_done(struct tevent_req *subreq)
     284             : {
     285             :     struct ipa_hostid_handler_state *state;
     286             :     struct tevent_req *req;
     287             :     int dp_error;
     288             :     errno_t ret;
     289             : 
     290           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     291           0 :     state = tevent_req_data(req, struct ipa_hostid_handler_state);
     292             : 
     293           0 :     ret = hosts_get_recv(subreq, &dp_error);
     294           0 :     talloc_zfree(subreq);
     295             : 
     296             :     /* TODO For backward compatibility we always return EOK to DP now. */
     297           0 :     dp_reply_std_set(&state->reply, dp_error, ret, NULL);
     298           0 :     tevent_req_done(req);
     299           0 : }
     300             : 
     301             : errno_t
     302           0 : ipa_hostid_handler_recv(TALLOC_CTX *mem_ctx,
     303             :                        struct tevent_req *req,
     304             :                        struct dp_reply_std *data)
     305             : {
     306           0 :     struct ipa_hostid_handler_state *state = NULL;
     307             : 
     308           0 :     state = tevent_req_data(req, struct ipa_hostid_handler_state);
     309             : 
     310           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     311             : 
     312           0 :     *data = state->reply;
     313             : 
     314           0 :     return EOK;
     315             : }

Generated by: LCOV version 1.10