LCOV - code coverage report
Current view: top level - providers/ipa - ipa_hbac_rules.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 141 0.0 %
Date: 2015-10-19 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@redhat.com>
       6             : 
       7             :     Copyright (C) 2011 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 "providers/ipa/ipa_hbac_private.h"
      25             : #include "providers/ipa/ipa_hbac_rules.h"
      26             : #include "providers/ldap/sdap_async.h"
      27             : 
      28             : struct ipa_hbac_rule_state {
      29             :     struct tevent_context *ev;
      30             :     struct sdap_handle *sh;
      31             :     struct sdap_options *opts;
      32             : 
      33             :     int search_base_iter;
      34             :     struct sdap_search_base **search_bases;
      35             : 
      36             :     const char **attrs;
      37             :     char *rules_filter;
      38             :     char *cur_filter;
      39             : 
      40             :     size_t rule_count;
      41             :     struct sysdb_attrs **rules;
      42             : };
      43             : 
      44             : static errno_t
      45             : ipa_hbac_rule_info_next(struct tevent_req *req,
      46             :                         struct ipa_hbac_rule_state *state);
      47             : static void
      48             : ipa_hbac_rule_info_done(struct tevent_req *subreq);
      49             : 
      50             : struct tevent_req *
      51           0 : ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx,
      52             :                         struct tevent_context *ev,
      53             :                         struct sdap_handle *sh,
      54             :                         struct sdap_options *opts,
      55             :                         struct sdap_search_base **search_bases,
      56             :                         struct sysdb_attrs *ipa_host)
      57             : {
      58             :     errno_t ret;
      59             :     size_t i;
      60           0 :     struct tevent_req *req = NULL;
      61             :     struct ipa_hbac_rule_state *state;
      62             :     TALLOC_CTX *tmp_ctx;
      63             :     const char *host_dn;
      64             :     char *host_dn_clean;
      65             :     char *host_group_clean;
      66             :     char *rule_filter;
      67             :     const char **memberof_list;
      68             : 
      69           0 :     if (ipa_host == NULL) {
      70           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Missing host\n");
      71           0 :         return NULL;
      72             :     }
      73             : 
      74           0 :     tmp_ctx = talloc_new(mem_ctx);
      75           0 :     if (tmp_ctx == NULL) return NULL;
      76             : 
      77           0 :     ret = sysdb_attrs_get_string(ipa_host, SYSDB_ORIG_DN, &host_dn);
      78           0 :     if (ret != EOK) {
      79           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify IPA hostname\n");
      80           0 :         goto error;
      81             :     }
      82             : 
      83           0 :     ret = sss_filter_sanitize(tmp_ctx, host_dn, &host_dn_clean);
      84           0 :     if (ret != EOK) goto error;
      85             : 
      86           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_rule_state);
      87           0 :     if (req == NULL) {
      88           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n");
      89           0 :         goto error;
      90             :     }
      91             : 
      92           0 :     state->ev = ev;
      93           0 :     state->sh = sh;
      94           0 :     state->opts = opts;
      95           0 :     state->search_bases = search_bases;
      96           0 :     state->search_base_iter = 0;
      97           0 :     state->attrs = talloc_zero_array(state, const char *, 15);
      98           0 :     if (state->attrs == NULL) {
      99           0 :         ret = ENOMEM;
     100           0 :         goto immediate;
     101             :     }
     102           0 :     state->attrs[0] = OBJECTCLASS;
     103           0 :     state->attrs[1] = IPA_CN;
     104           0 :     state->attrs[2] = IPA_UNIQUE_ID;
     105           0 :     state->attrs[3] = IPA_ENABLED_FLAG;
     106           0 :     state->attrs[4] = IPA_ACCESS_RULE_TYPE;
     107           0 :     state->attrs[5] = IPA_MEMBER_USER;
     108           0 :     state->attrs[6] = IPA_USER_CATEGORY;
     109           0 :     state->attrs[7] = IPA_MEMBER_SERVICE;
     110           0 :     state->attrs[8] = IPA_SERVICE_CATEGORY;
     111           0 :     state->attrs[9] = IPA_SOURCE_HOST;
     112           0 :     state->attrs[10] = IPA_SOURCE_HOST_CATEGORY;
     113           0 :     state->attrs[11] = IPA_EXTERNAL_HOST;
     114           0 :     state->attrs[12] = IPA_MEMBER_HOST;
     115           0 :     state->attrs[13] = IPA_HOST_CATEGORY;
     116           0 :     state->attrs[14] = NULL;
     117             : 
     118           0 :     rule_filter = talloc_asprintf(tmp_ctx,
     119             :                                   "(&(objectclass=%s)"
     120             :                                   "(%s=%s)(%s=%s)"
     121             :                                   "(|(%s=%s)(%s=%s)",
     122             :                                   IPA_HBAC_RULE,
     123             :                                   IPA_ENABLED_FLAG, IPA_TRUE_VALUE,
     124             :                                   IPA_ACCESS_RULE_TYPE, IPA_HBAC_ALLOW,
     125             :                                   IPA_HOST_CATEGORY, "all",
     126             :                                   IPA_MEMBER_HOST, host_dn_clean);
     127           0 :     if (rule_filter == NULL) {
     128           0 :         ret = ENOMEM;
     129           0 :         goto immediate;
     130             :     }
     131             : 
     132             :     /* Add all parent groups of ipa_hostname to the filter */
     133           0 :     ret = sysdb_attrs_get_string_array(ipa_host, SYSDB_ORIG_MEMBEROF,
     134             :                                        tmp_ctx, &memberof_list);
     135           0 :     if (ret != EOK && ret != ENOENT) {
     136           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify.\n");
     137           0 :     } if (ret == ENOENT) {
     138             :         /* This host is not a member of any hostgroups */
     139           0 :         memberof_list = talloc_array(tmp_ctx, const char *, 1);
     140           0 :         if (memberof_list == NULL) {
     141           0 :             ret = ENOMEM;
     142           0 :             goto immediate;
     143             :         }
     144           0 :         memberof_list[0] = NULL;
     145             :     }
     146             : 
     147           0 :     for (i = 0; memberof_list[i]; i++) {
     148           0 :         ret = sss_filter_sanitize(tmp_ctx,
     149           0 :                                   memberof_list[i],
     150             :                                   &host_group_clean);
     151           0 :         if (ret != EOK) goto immediate;
     152             : 
     153           0 :         rule_filter = talloc_asprintf_append(rule_filter, "(%s=%s)",
     154             :                                              IPA_MEMBER_HOST,
     155             :                                              host_group_clean);
     156           0 :         if (rule_filter == NULL) {
     157           0 :             ret = ENOMEM;
     158           0 :             goto immediate;
     159             :         }
     160             :     }
     161             : 
     162           0 :     rule_filter = talloc_asprintf_append(rule_filter, "))");
     163           0 :     if (rule_filter == NULL) {
     164           0 :         ret = ENOMEM;
     165           0 :         goto immediate;
     166             :     }
     167           0 :     state->rules_filter = talloc_steal(state, rule_filter);
     168             : 
     169           0 :     ret = ipa_hbac_rule_info_next(req, state);
     170           0 :     if (ret == EOK) {
     171           0 :         ret = EINVAL;
     172             :     }
     173             : 
     174           0 :     if (ret != EAGAIN) {
     175           0 :         goto immediate;
     176             :     }
     177             : 
     178           0 :     talloc_free(tmp_ctx);
     179           0 :     return req;
     180             : 
     181             : immediate:
     182           0 :     if (ret == EOK) {
     183           0 :         tevent_req_done(req);
     184             :     } else {
     185           0 :         tevent_req_error(req, ret);
     186             :     }
     187           0 :     tevent_req_post(req, ev);
     188           0 :     talloc_free(tmp_ctx);
     189           0 :     return req;
     190             : 
     191             : error:
     192           0 :     talloc_free(tmp_ctx);
     193           0 :     return NULL;
     194             : }
     195             : 
     196             : static errno_t
     197           0 : ipa_hbac_rule_info_next(struct tevent_req *req,
     198             :                         struct ipa_hbac_rule_state *state)
     199             : {
     200             :     struct tevent_req *subreq;
     201             :     struct sdap_search_base *base;
     202             : 
     203           0 :     base = state->search_bases[state->search_base_iter];
     204           0 :     if (base  == NULL) {
     205           0 :         return EOK;
     206             :     }
     207             : 
     208           0 :     talloc_zfree(state->cur_filter);
     209           0 :     state->cur_filter = sdap_get_id_specific_filter(state,
     210           0 :                                                     state->rules_filter,
     211             :                                                     base->filter);
     212           0 :     if (state->cur_filter == NULL) {
     213           0 :         return ENOMEM;
     214             :     }
     215             : 
     216           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Sending request for next search base: "
     217             :                               "[%s][%d][%s]\n", base->basedn, base->scope,
     218             :                               state->cur_filter);
     219             : 
     220           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     221             :                                    base->basedn, base->scope,
     222           0 :                                    state->cur_filter, state->attrs,
     223             :                                    NULL, 0,
     224           0 :                                    dp_opt_get_int(state->opts->basic,
     225             :                                                   SDAP_ENUM_SEARCH_TIMEOUT),
     226             :                                    true);
     227           0 :     if (subreq == NULL) {
     228           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send failed.\n");
     229           0 :         return ENOMEM;
     230             :     }
     231           0 :     tevent_req_set_callback(subreq, ipa_hbac_rule_info_done, req);
     232             : 
     233           0 :     return EAGAIN;
     234             : }
     235             : 
     236             : static void
     237           0 : ipa_hbac_rule_info_done(struct tevent_req *subreq)
     238             : {
     239             :     errno_t ret;
     240           0 :     struct tevent_req *req =
     241           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     242           0 :     struct ipa_hbac_rule_state *state =
     243           0 :             tevent_req_data(req, struct ipa_hbac_rule_state);
     244             :     int i;
     245             :     size_t rule_count;
     246             :     size_t total_count;
     247             :     struct sysdb_attrs **rules;
     248             :     struct sysdb_attrs **target;
     249             : 
     250           0 :     ret = sdap_get_generic_recv(subreq, state,
     251             :                                 &rule_count,
     252             :                                 &rules);
     253           0 :     if (ret != EOK) {
     254           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve HBAC rules\n");
     255           0 :         goto fail;
     256             :     }
     257             : 
     258           0 :     if (rule_count > 0) {
     259           0 :         total_count = rule_count + state->rule_count;
     260           0 :         state->rules = talloc_realloc(state, state->rules,
     261             :                                       struct sysdb_attrs *,
     262             :                                       total_count);
     263           0 :         if (state->rules == NULL) {
     264           0 :             ret = ENOMEM;
     265           0 :             goto fail;
     266             :         }
     267             : 
     268           0 :         i = 0;
     269           0 :         while (state->rule_count < total_count) {
     270           0 :             target = &state->rules[state->rule_count];
     271           0 :             *target = talloc_steal(state->rules, rules[i]);
     272             : 
     273           0 :             state->rule_count++;
     274           0 :             i++;
     275             :         }
     276             :     }
     277             : 
     278           0 :     state->search_base_iter++;
     279           0 :     ret = ipa_hbac_rule_info_next(req, state);
     280           0 :     if (ret == EAGAIN) {
     281           0 :         return;
     282           0 :     } else if (ret != EOK) {
     283           0 :         goto fail;
     284           0 :     } else if (ret == EOK && state->rule_count == 0) {
     285           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "No rules apply to this host\n");
     286           0 :         tevent_req_error(req, ENOENT);
     287           0 :         return;
     288             :     }
     289             : 
     290             :     /* We went through all search bases and we have some results */
     291           0 :     tevent_req_done(req);
     292             : 
     293           0 :     return;
     294             : 
     295             : fail:
     296           0 :     tevent_req_error(req, ret);
     297             : }
     298             : 
     299             : errno_t
     300           0 : ipa_hbac_rule_info_recv(struct tevent_req *req,
     301             :                         TALLOC_CTX *mem_ctx,
     302             :                         size_t *rule_count,
     303             :                         struct sysdb_attrs ***rules)
     304             : {
     305           0 :     struct ipa_hbac_rule_state *state =
     306           0 :             tevent_req_data(req, struct ipa_hbac_rule_state);
     307             : 
     308           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     309             : 
     310           0 :     *rule_count = state->rule_count;
     311           0 :     *rules = talloc_steal(mem_ctx, state->rules);
     312             : 
     313           0 :     return EOK;
     314             : }

Generated by: LCOV version 1.10