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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Jan Zeleny <jzeleny@redhat.com>
       6             : 
       7             :     Copyright (C) 2012 Red Hat
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "util/util.h"
      24             : #include "db/sysdb.h"
      25             : #include "providers/ldap/sdap_async.h"
      26             : #include "providers/ipa/ipa_hosts.h"
      27             : #include "providers/ipa/ipa_common.h"
      28             : 
      29             : struct ipa_host_state {
      30             :     struct tevent_context *ev;
      31             :     struct sysdb_ctx *sysdb;
      32             :     struct sdap_handle *sh;
      33             :     struct sdap_options *opts;
      34             :     const char **attrs;
      35             :     struct sdap_attr_map *host_map;
      36             :     struct sdap_attr_map *hostgroup_map;
      37             : 
      38             :     struct sdap_search_base **search_bases;
      39             :     int search_base_iter;
      40             : 
      41             :     char *cur_filter;
      42             :     char *host_filter;
      43             : 
      44             :     const char *hostname;
      45             : 
      46             :     /* Return values */
      47             :     size_t host_count;
      48             :     struct sysdb_attrs **hosts;
      49             : 
      50             :     size_t hostgroup_count;
      51             :     struct sysdb_attrs **hostgroups;
      52             :     struct sdap_attr_map_info *ipa_hostgroup_map;
      53             : };
      54             : 
      55             : static void
      56             : ipa_host_info_done(struct tevent_req *subreq);
      57             : 
      58             : static void
      59             : ipa_hostgroup_info_done(struct tevent_req *subreq);
      60             : 
      61             : static errno_t
      62             : ipa_host_info_next(struct tevent_req *req,
      63             :                         struct ipa_host_state *state);
      64             : static errno_t
      65             : ipa_hostgroup_info_next(struct tevent_req *req,
      66             :                              struct ipa_host_state *state);
      67             : 
      68             : /**
      69             :  * hostname == NULL -> look up all hosts / host groups
      70             :  * hostname != NULL -> look up only given host and groups
      71             :  *                     it's member of
      72             :  * hostgroup_map == NULL -> skip looking up hostgroups
      73             :  */
      74             : struct tevent_req *
      75           0 : ipa_host_info_send(TALLOC_CTX *mem_ctx,
      76             :                    struct tevent_context *ev,
      77             :                    struct sdap_handle *sh,
      78             :                    struct sdap_options *opts,
      79             :                    const char *hostname,
      80             :                    struct sdap_attr_map *host_map,
      81             :                    struct sdap_attr_map *hostgroup_map,
      82             :                    struct sdap_search_base **search_bases)
      83             : {
      84             :     errno_t ret;
      85             :     struct ipa_host_state *state;
      86             :     struct tevent_req *req;
      87             : 
      88           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_host_state);
      89           0 :     if (req == NULL) {
      90           0 :         return NULL;
      91             :     }
      92             : 
      93           0 :     state->ev = ev;
      94           0 :     state->sh = sh;
      95           0 :     state->opts = opts;
      96           0 :     state->hostname = hostname;
      97           0 :     state->search_bases = search_bases;
      98           0 :     state->search_base_iter = 0;
      99           0 :     state->cur_filter = NULL;
     100           0 :     state->host_map = host_map;
     101           0 :     state->hostgroup_map = hostgroup_map;
     102             : 
     103           0 :     ret = build_attrs_from_map(state, host_map, IPA_OPTS_HOST,
     104           0 :                                NULL, &state->attrs, NULL);
     105           0 :     if (ret != EOK) {
     106           0 :         goto immediate;
     107             :     }
     108             : 
     109           0 :     if (hostname == NULL) {
     110           0 :         state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
     111             :                                              host_map[IPA_OC_HOST].name);
     112             :     } else {
     113           0 :         state->host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",
     114             :                                              host_map[IPA_OC_HOST].name,
     115           0 :                                              host_map[IPA_AT_HOST_FQDN].name,
     116             :                                              hostname);
     117             :     }
     118           0 :     if (state->host_filter == NULL) {
     119           0 :         ret = ENOMEM;
     120           0 :         goto immediate;
     121             :     }
     122             : 
     123           0 :     ret = ipa_host_info_next(req, state);
     124           0 :     if (ret == EOK) {
     125           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n");
     126           0 :         ret = EINVAL;
     127             :     }
     128             : 
     129           0 :     if (ret != EAGAIN) {
     130           0 :         goto immediate;
     131             :     }
     132             : 
     133           0 :     return req;
     134             : 
     135             : immediate:
     136           0 :     if (ret == EOK) {
     137           0 :         tevent_req_done(req);
     138             :     } else {
     139           0 :         tevent_req_error(req, ret);
     140             :     }
     141           0 :     tevent_req_post(req, ev);
     142           0 :     return req;
     143             : }
     144             : 
     145           0 : static errno_t ipa_host_info_next(struct tevent_req *req,
     146             :                                        struct ipa_host_state *state)
     147             : {
     148             :     struct sdap_search_base *base;
     149             :     struct tevent_req *subreq;
     150             : 
     151           0 :     base = state->search_bases[state->search_base_iter];
     152           0 :     if (base == NULL) {
     153           0 :         return EOK;
     154             :     }
     155             : 
     156           0 :     talloc_zfree(state->cur_filter);
     157           0 :     state->cur_filter = sdap_combine_filters(state, state->host_filter,
     158             :                                              base->filter);
     159           0 :     if (state->cur_filter == NULL) {
     160           0 :         return ENOMEM;
     161             :     }
     162             : 
     163           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts,
     164             :                                    state->sh, base->basedn,
     165           0 :                                    base->scope, state->cur_filter,
     166             :                                    state->attrs, state->host_map,
     167             :                                    IPA_OPTS_HOST,
     168           0 :                                    dp_opt_get_int(state->opts->basic,
     169             :                                                   SDAP_ENUM_SEARCH_TIMEOUT),
     170             :                                    true);
     171           0 :     if (subreq == NULL) {
     172           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n");
     173           0 :         talloc_zfree(state->cur_filter);
     174           0 :         return EIO;
     175             :     }
     176           0 :     tevent_req_set_callback(subreq, ipa_host_info_done, req);
     177             : 
     178           0 :     return EAGAIN;
     179             : }
     180             : 
     181             : static void
     182           0 : ipa_host_info_done(struct tevent_req *subreq)
     183             : {
     184             :     errno_t ret;
     185           0 :     struct tevent_req *req =
     186           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     187           0 :     struct ipa_host_state *state =
     188           0 :             tevent_req_data(req, struct ipa_host_state);
     189             :     const char *host_dn;
     190             : 
     191           0 :     ret = sdap_get_generic_recv(subreq, state,
     192             :                                 &state->host_count,
     193             :                                 &state->hosts);
     194           0 :     talloc_zfree(subreq);
     195           0 :     if (ret != EOK) {
     196           0 :         tevent_req_error(req, ret);
     197           0 :         return;
     198             :     }
     199             : 
     200           0 :     if (state->host_count == 0) {
     201           0 :         state->search_base_iter++;
     202           0 :         ret = ipa_host_info_next(req, state);
     203           0 :         if (ret == EOK) {
     204             :             /* No more search bases to try */
     205           0 :             tevent_req_error(req, ENOENT);
     206           0 :         } else if (ret != EAGAIN) {
     207           0 :             tevent_req_error(req, ret);
     208             :         }
     209           0 :         return;
     210             :     }
     211             : 
     212           0 :     if (state->hostgroup_map) {
     213           0 :         talloc_free(state->attrs);
     214           0 :         ret = build_attrs_from_map(state, state->hostgroup_map,
     215             :                                    IPA_OPTS_HOSTGROUP, NULL,
     216             :                                    &state->attrs, NULL);
     217           0 :         if (ret != EOK) {
     218           0 :             tevent_req_error(req, ret);
     219           0 :             return;
     220             :         }
     221             : 
     222             :         /* Look up host groups */
     223           0 :         if (state->hostname == NULL) {
     224           0 :             talloc_zfree(state->host_filter);
     225           0 :             state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
     226           0 :                                     state->hostgroup_map[IPA_OC_HOSTGROUP].name);
     227           0 :             if (state->host_filter == NULL) {
     228           0 :                 tevent_req_error(req, ENOMEM);
     229           0 :                 return;
     230             :             }
     231           0 :             state->search_base_iter = 0;
     232             : 
     233           0 :             ret = ipa_hostgroup_info_next(req, state);
     234           0 :             if (ret == EOK) {
     235           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n");
     236           0 :                 tevent_req_error(req, EINVAL);
     237           0 :                 return;
     238           0 :             } else if (ret != EAGAIN) {
     239           0 :                 tevent_req_error(req, ret);
     240           0 :                 return;
     241             :             }
     242             :         } else {
     243           0 :             state->ipa_hostgroup_map = talloc_zero(state, struct sdap_attr_map_info);
     244           0 :             if (state->ipa_hostgroup_map == NULL) {
     245           0 :                 tevent_req_error(req, ENOMEM);
     246           0 :                 return;
     247             :             }
     248           0 :             state->ipa_hostgroup_map->map = state->hostgroup_map;
     249           0 :             state->ipa_hostgroup_map->num_attrs = IPA_OPTS_HOSTGROUP;
     250             : 
     251           0 :             ret = sysdb_attrs_get_string(state->hosts[0], SYSDB_ORIG_DN, &host_dn);
     252           0 :             if (ret != EOK) {
     253           0 :                 tevent_req_error(req, ret);
     254           0 :                 return;
     255             :             }
     256             : 
     257           0 :             if (!sdap_has_deref_support(state->sh, state->opts)) {
     258           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "Server does not support deref\n");
     259           0 :                 tevent_req_error(req, EIO);
     260           0 :                 return;
     261             :             }
     262             : 
     263           0 :             subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh,
     264             :                                             host_dn,
     265           0 :                                             state->hostgroup_map[IPA_AT_HOSTGROUP_MEMBER_OF].name,
     266             :                                             state->attrs,
     267             :                                             1, state->ipa_hostgroup_map,
     268           0 :                                             dp_opt_get_int(state->opts->basic,
     269             :                                                            SDAP_ENUM_SEARCH_TIMEOUT));
     270           0 :             if (subreq == NULL) {
     271           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n");
     272           0 :                 tevent_req_error(req, EIO);
     273           0 :                 return;
     274             :             }
     275           0 :             tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req);
     276             :         }
     277             :     } else {
     278             :         /* Nothing else to do, just complete the req */
     279           0 :         tevent_req_done(req);
     280             :     }
     281             : }
     282             : 
     283           0 : static errno_t ipa_hostgroup_info_next(struct tevent_req *req,
     284             :                                             struct ipa_host_state *state)
     285             : {
     286             :     struct sdap_search_base *base;
     287             :     struct tevent_req *subreq;
     288             : 
     289           0 :     base = state->search_bases[state->search_base_iter];
     290           0 :     if (base == NULL) {
     291           0 :         return EOK;
     292             :     }
     293             : 
     294           0 :     talloc_zfree(state->cur_filter);
     295           0 :     state->cur_filter = sdap_combine_filters(state, state->host_filter,
     296             :                                              base->filter);
     297           0 :     if (state->cur_filter == NULL) {
     298           0 :         return ENOMEM;
     299             :     }
     300             : 
     301           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     302             :                                    base->basedn, base->scope,
     303           0 :                                    state->cur_filter, state->attrs,
     304             :                                    state->hostgroup_map,
     305             :                                    IPA_OPTS_HOSTGROUP,
     306           0 :                                    dp_opt_get_int(state->opts->basic,
     307             :                                                   SDAP_ENUM_SEARCH_TIMEOUT),
     308             :                                    true);
     309           0 :     if (subreq == NULL) {
     310           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting hostgroup info\n");
     311           0 :         talloc_zfree(state->cur_filter);
     312           0 :         return EIO;
     313             :     }
     314           0 :     tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req);
     315             : 
     316           0 :     return EAGAIN;
     317             : }
     318             : 
     319             : static void
     320           0 : ipa_hostgroup_info_done(struct tevent_req *subreq)
     321             : {
     322             :     errno_t ret;
     323           0 :     struct tevent_req *req =
     324           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     325           0 :     struct ipa_host_state *state =
     326           0 :             tevent_req_data(req, struct ipa_host_state);
     327             : 
     328             :     size_t hostgroups_total;
     329             :     size_t hostgroup_count;
     330             :     struct sysdb_attrs **hostgroups;
     331             :     struct sdap_deref_attrs **deref_result;
     332             :     const char *hostgroup_name;
     333             :     const char *hostgroup_dn;
     334             :     int i, j;
     335             : 
     336           0 :     if (state->hostname == NULL) {
     337           0 :         ret = sdap_get_generic_recv(subreq, state,
     338             :                                     &hostgroup_count,
     339             :                                     &hostgroups);
     340           0 :         talloc_zfree(subreq);
     341           0 :         if (ret != EOK) {
     342           0 :             DEBUG(SSSDBG_OP_FAILURE,
     343             :                   "sdap_get_generic_recv failed: [%d]\n", ret);
     344           0 :             tevent_req_error(req, ret);
     345           0 :             return;
     346             :         }
     347             : 
     348             :         /* Merge the two arrays */
     349           0 :         if (hostgroup_count > 0) {
     350           0 :             hostgroups_total = hostgroup_count + state->hostgroup_count;
     351           0 :             state->hostgroups = talloc_realloc(state, state->hostgroups,
     352             :                                                struct sysdb_attrs *,
     353             :                                                hostgroups_total);
     354           0 :             if (state->hostgroups == NULL) {
     355           0 :                 tevent_req_error(req, ENOMEM);
     356           0 :                 return;
     357             :             }
     358             : 
     359           0 :             i = 0;
     360           0 :             while(state->hostgroup_count < hostgroups_total) {
     361           0 :                 state->hostgroups[state->hostgroup_count] =
     362           0 :                     talloc_steal(state->hostgroups, hostgroups[i]);
     363           0 :                 state->hostgroup_count++;
     364           0 :                 i++;
     365             :             }
     366             :         }
     367             : 
     368             :         /* Now look in the next base */
     369           0 :         state->search_base_iter++;
     370           0 :         ret = ipa_hostgroup_info_next(req, state);
     371           0 :         if (ret != EOK && ret != EAGAIN) {
     372           0 :             tevent_req_error(req, ret);
     373             :         }
     374             : 
     375           0 :         if (ret != EOK) {
     376             :             /* Only continue if no error occurred
     377             :              * and no req was created */
     378           0 :             return;
     379             :         }
     380             :     } else {
     381           0 :         ret = sdap_deref_search_recv(subreq, state,
     382             :                                      &state->hostgroup_count,
     383             :                                      &deref_result);
     384           0 :         talloc_zfree(subreq);
     385           0 :         if (ret != EOK) goto done;
     386             : 
     387           0 :         if (state->hostgroup_count == 0) {
     388           0 :             DEBUG(SSSDBG_FUNC_DATA, "No host groups were dereferenced\n");
     389             :         } else {
     390           0 :             state->hostgroups = talloc_zero_array(state, struct sysdb_attrs *,
     391             :                                                   state->hostgroup_count);
     392           0 :             if (state->hostgroups == NULL) {
     393           0 :                 ret = ENOMEM;
     394           0 :                 goto done;
     395             :             }
     396             : 
     397           0 :             j = 0;
     398           0 :             for (i = 0; i < state->hostgroup_count; i++) {
     399           0 :                 ret = sysdb_attrs_get_string(deref_result[i]->attrs,
     400             :                                              SYSDB_ORIG_DN, &hostgroup_dn);
     401           0 :                 if (ret != EOK) goto done;
     402             : 
     403           0 :                 if (!sss_ldap_dn_in_search_bases(state, hostgroup_dn,
     404             :                                                  state->search_bases,
     405             :                                                  NULL)) {
     406           0 :                     continue;
     407             :                 }
     408             : 
     409           0 :                 ret = sysdb_attrs_get_string(deref_result[i]->attrs,
     410           0 :                              state->hostgroup_map[IPA_AT_HOSTGROUP_NAME].sys_name,
     411             :                              &hostgroup_name);
     412           0 :                 if (ret != EOK) goto done;
     413             : 
     414           0 :                 DEBUG(SSSDBG_FUNC_DATA, "Dereferenced host group: %s\n",
     415             :                                         hostgroup_name);
     416           0 :                 state->hostgroups[j] = talloc_steal(state->hostgroups,
     417             :                                                     deref_result[i]->attrs);
     418           0 :                 j++;
     419             :             }
     420           0 :             state->hostgroup_count = j;
     421             :         }
     422             :     }
     423             : 
     424             : done:
     425           0 :     if (ret == EOK) {
     426           0 :         tevent_req_done(req);
     427             :     } else {
     428           0 :         DEBUG(SSSDBG_OP_FAILURE, "Error [%d][%s]\n", ret, strerror(ret));
     429           0 :         tevent_req_error(req, ret);
     430             :     }
     431             : }
     432             : 
     433           0 : errno_t ipa_host_info_recv(struct tevent_req *req,
     434             :                            TALLOC_CTX *mem_ctx,
     435             :                            size_t *host_count,
     436             :                            struct sysdb_attrs ***hosts,
     437             :                            size_t *hostgroup_count,
     438             :                            struct sysdb_attrs ***hostgroups)
     439             : {
     440             :     size_t c;
     441           0 :     struct ipa_host_state *state =
     442           0 :             tevent_req_data(req, struct ipa_host_state);
     443             : 
     444           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     445             : 
     446           0 :     *host_count = state->host_count;
     447           0 :     *hosts = talloc_steal(mem_ctx, state->hosts);
     448           0 :     for (c = 0; c < state->host_count; c++) {
     449             :         /* Guarantee the memory heirarchy of the list */
     450           0 :         talloc_steal(state->hosts, state->hosts[c]);
     451             :     }
     452             : 
     453           0 :     if (hostgroup_count) *hostgroup_count = state->hostgroup_count;
     454           0 :     if (hostgroups) *hostgroups = talloc_steal(mem_ctx, state->hostgroups);
     455             : 
     456           0 :     return EOK;
     457             : }

Generated by: LCOV version 1.10