LCOV - code coverage report
Current view: top level - providers/ipa - ipa_hbac_common.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 350 0.0 %
Date: 2016-06-29 Functions: 0 11 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 "providers/ipa/ipa_hbac_private.h"
      24             : #include "providers/ipa/ipa_common.h"
      25             : 
      26             : static errno_t
      27           0 : ipa_hbac_save_list(struct sss_domain_info *domain,
      28             :                    bool delete_subdir, const char *subdir,
      29             :                    const char *naming_attribute, size_t count,
      30             :                    struct sysdb_attrs **list)
      31             : {
      32             :     int ret;
      33             :     size_t c;
      34             :     struct ldb_dn *base_dn;
      35             :     const char *object_name;
      36             :     struct ldb_message_element *el;
      37             :     TALLOC_CTX *tmp_ctx;
      38             : 
      39           0 :     tmp_ctx = talloc_new(NULL);
      40           0 :     if (tmp_ctx == NULL) {
      41           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
      42           0 :         return ENOMEM;
      43             :     }
      44             : 
      45           0 :     if (delete_subdir) {
      46           0 :         base_dn = sysdb_custom_subtree_dn(tmp_ctx, domain, subdir);
      47           0 :         if (base_dn == NULL) {
      48           0 :             ret = ENOMEM;
      49           0 :             goto done;
      50             :         }
      51             : 
      52           0 :         ret = sysdb_delete_recursive(domain->sysdb, base_dn, true);
      53           0 :         if (ret != EOK) {
      54           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_delete_recursive failed.\n");
      55           0 :             goto done;
      56             :         }
      57             :     }
      58             : 
      59           0 :     for (c = 0; c < count; c++) {
      60           0 :         ret = sysdb_attrs_get_el(list[c], naming_attribute, &el);
      61           0 :         if (ret != EOK) {
      62           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n");
      63           0 :             goto done;
      64             :         }
      65           0 :         if (el->num_values == 0) {
      66           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "[%s] not found.\n", naming_attribute);
      67           0 :             ret = EINVAL;
      68           0 :             goto done;
      69             :         }
      70           0 :         object_name = talloc_strndup(tmp_ctx, (const char *)el->values[0].data,
      71           0 :                                      el->values[0].length);
      72           0 :         if (object_name == NULL) {
      73           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
      74           0 :             ret = ENOMEM;
      75           0 :             goto done;
      76             :         }
      77           0 :         DEBUG(SSSDBG_TRACE_ALL, "Object name: [%s].\n", object_name);
      78             : 
      79           0 :         ret = sysdb_store_custom(domain, object_name, subdir, list[c]);
      80           0 :         if (ret != EOK) {
      81           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_store_custom failed.\n");
      82           0 :             goto done;
      83             :         }
      84             :     }
      85             : 
      86           0 :     ret = EOK;
      87             : 
      88             : done:
      89           0 :     talloc_free(tmp_ctx);
      90           0 :     return ret;
      91             : }
      92             : 
      93             : errno_t
      94           0 : ipa_hbac_sysdb_save(struct sss_domain_info *domain,
      95             :                     const char *primary_subdir, const char *attr_name,
      96             :                     size_t primary_count, struct sysdb_attrs **primary,
      97             :                     const char *group_subdir, const char *groupattr_name,
      98             :                     size_t group_count, struct sysdb_attrs **groups)
      99             : {
     100             :     errno_t ret, sret;
     101           0 :     bool in_transaction = false;
     102             : 
     103           0 :     if ((primary_count == 0 || primary == NULL)
     104           0 :         || (group_count > 0 && groups == NULL)) {
     105             :         /* There always has to be at least one
     106             :          * primary entry.
     107             :          */
     108           0 :         return EINVAL;
     109             :     }
     110             : 
     111             :     /* Save the entries and groups to the cache */
     112           0 :     ret = sysdb_transaction_start(domain->sysdb);
     113           0 :     if (ret != EOK) {
     114           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
     115           0 :         goto done;
     116             :     };
     117           0 :     in_transaction = true;
     118             : 
     119             :     /* First, save the specific entries */
     120           0 :     ret = ipa_hbac_save_list(domain, true, primary_subdir,
     121             :                              attr_name, primary_count, primary);
     122           0 :     if (ret != EOK) {
     123           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not save %s. [%d][%s]\n",
     124             :                   primary_subdir, ret, strerror(ret));
     125           0 :         goto done;
     126             :     }
     127             : 
     128             :     /* Second, save the groups */
     129           0 :     if (group_count > 0) {
     130           0 :         ret = ipa_hbac_save_list(domain, true, group_subdir,
     131             :                                  groupattr_name, group_count, groups);
     132           0 :         if (ret != EOK) {
     133           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Could not save %s. [%d][%s]\n",
     134             :                       group_subdir, ret, strerror(ret));
     135           0 :             goto done;
     136             :         }
     137             :     }
     138             : 
     139           0 :     ret = sysdb_transaction_commit(domain->sysdb);
     140           0 :     if (ret != EOK) {
     141           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
     142           0 :         goto done;
     143             :     }
     144           0 :     in_transaction = false;
     145             : 
     146             : done:
     147           0 :     if (in_transaction) {
     148           0 :         sret = sysdb_transaction_cancel(domain->sysdb);
     149           0 :         if (sret != EOK) {
     150           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "Could not cancel sysdb transaction\n");
     151             :         }
     152             :     }
     153             : 
     154           0 :     if (ret != EOK) {
     155           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Error [%d][%s]\n", ret, strerror(ret));
     156             :     }
     157           0 :     return ret;
     158             : }
     159             : 
     160             : errno_t
     161           0 : replace_attribute_name(const char *old_name,
     162             :                        const char *new_name, const size_t count,
     163             :                        struct sysdb_attrs **list)
     164             : {
     165             :     int ret;
     166             :     int i;
     167             : 
     168           0 :     for (i = 0; i < count; i++) {
     169           0 :         ret = sysdb_attrs_replace_name(list[i], old_name, new_name);
     170           0 :         if (ret != EOK) {
     171           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_replace_name failed.\n");
     172           0 :             return ret;
     173             :         }
     174             :     }
     175             : 
     176           0 :     return EOK;
     177             : }
     178             : 
     179             : static errno_t
     180           0 : create_empty_grouplist(struct hbac_request_element *el)
     181             : {
     182           0 :     el->groups = talloc_array(el, const char *, 1);
     183           0 :     if (!el->groups) return ENOMEM;
     184             : 
     185           0 :     el->groups[0] = NULL;
     186           0 :     return EOK;
     187             : }
     188             : 
     189             : /********************************************
     190             :  * Functions for handling conversion to the *
     191             :  * HBAC evaluator format                    *
     192             :  ********************************************/
     193             : 
     194             : static errno_t
     195             : hbac_attrs_to_rule(TALLOC_CTX *mem_ctx,
     196             :                    struct hbac_ctx *hbac_ctx,
     197             :                    size_t index,
     198             :                    struct hbac_rule **rule);
     199             : 
     200             : static errno_t
     201             : hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx,
     202             :                          struct hbac_ctx *hbac_ctx,
     203             :                          struct hbac_eval_req **request);
     204             : 
     205             : errno_t
     206           0 : hbac_ctx_to_rules(TALLOC_CTX *mem_ctx,
     207             :                   struct hbac_ctx *hbac_ctx,
     208             :                   struct hbac_rule ***rules,
     209             :                   struct hbac_eval_req **request)
     210             : {
     211             :     errno_t ret;
     212             :     struct hbac_rule **new_rules;
     213           0 :     struct hbac_eval_req *new_request = NULL;
     214             :     size_t i;
     215           0 :     TALLOC_CTX *tmp_ctx = NULL;
     216             : 
     217           0 :     if (!rules || !request) return EINVAL;
     218             : 
     219           0 :     tmp_ctx = talloc_new(mem_ctx);
     220           0 :     if (tmp_ctx == NULL) return ENOMEM;
     221             : 
     222             :     /* First create an array of rules */
     223           0 :     new_rules = talloc_array(tmp_ctx, struct hbac_rule *,
     224             :                              hbac_ctx->rule_count + 1);
     225           0 :     if (new_rules == NULL) {
     226           0 :         ret = ENOMEM;
     227           0 :         goto done;
     228             :     }
     229             : 
     230             :     /* Create each rule one at a time */
     231           0 :     for (i = 0; i < hbac_ctx->rule_count ; i++) {
     232           0 :         ret = hbac_attrs_to_rule(new_rules, hbac_ctx, i, &(new_rules[i]));
     233           0 :         if (ret == EPERM) {
     234           0 :             goto done;
     235           0 :         } else if (ret != EOK) {
     236           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct rules\n");
     237           0 :             goto done;
     238             :         }
     239             :     }
     240           0 :     new_rules[i] = NULL;
     241             : 
     242             :     /* Create the eval request */
     243           0 :     ret = hbac_ctx_to_eval_request(tmp_ctx, hbac_ctx, &new_request);
     244           0 :     if (ret != EOK) {
     245           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct eval request\n");
     246           0 :         goto done;
     247             :     }
     248             : 
     249           0 :     *rules = talloc_steal(mem_ctx, new_rules);
     250           0 :     *request = talloc_steal(mem_ctx, new_request);
     251           0 :     ret = EOK;
     252             : 
     253             : done:
     254           0 :     talloc_free(tmp_ctx);
     255           0 :     return ret;
     256             : }
     257             : 
     258             : static errno_t
     259           0 : hbac_attrs_to_rule(TALLOC_CTX *mem_ctx,
     260             :                    struct hbac_ctx *hbac_ctx,
     261             :                    size_t idx,
     262             :                    struct hbac_rule **rule)
     263             : {
     264             :     errno_t ret;
     265             :     struct hbac_rule *new_rule;
     266             :     struct ldb_message_element *el;
     267             :     const char *rule_type;
     268             : 
     269           0 :     new_rule = talloc_zero(mem_ctx, struct hbac_rule);
     270           0 :     if (new_rule == NULL) return ENOMEM;
     271             : 
     272           0 :     ret = sysdb_attrs_get_el(hbac_ctx->rules[idx],
     273             :                              IPA_CN, &el);
     274           0 :     if (ret != EOK || el->num_values == 0) {
     275           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "rule has no name, assuming '(none)'.\n");
     276           0 :         new_rule->name = talloc_strdup(new_rule, "(none)");
     277             :     } else {
     278           0 :         new_rule->name = talloc_strndup(new_rule,
     279           0 :                                         (const char*) el->values[0].data,
     280           0 :                                         el->values[0].length);
     281             :     }
     282             : 
     283           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Processing rule [%s]\n", new_rule->name);
     284             : 
     285           0 :     ret = sysdb_attrs_get_bool(hbac_ctx->rules[idx], IPA_ENABLED_FLAG,
     286             :                                &new_rule->enabled);
     287           0 :     if (ret != EOK) goto done;
     288             : 
     289           0 :     if (!new_rule->enabled) {
     290           0 :         ret = EOK;
     291           0 :         goto done;
     292             :     }
     293             : 
     294           0 :     ret = sysdb_attrs_get_string(hbac_ctx->rules[idx],
     295             :                                  IPA_ACCESS_RULE_TYPE,
     296             :                                  &rule_type);
     297           0 :     if (ret != EOK) goto done;
     298             : 
     299           0 :     if (strcasecmp(rule_type, IPA_HBAC_ALLOW) != 0) {
     300           0 :         DEBUG(SSSDBG_TRACE_LIBS,
     301             :               "Rule [%s] is not an ALLOW rule\n", new_rule->name);
     302           0 :         ret = EPERM;
     303           0 :         goto done;
     304             :     }
     305             : 
     306             :     /* Get the users */
     307           0 :     ret = hbac_user_attrs_to_rule(new_rule, hbac_ctx->be_ctx->domain,
     308             :                                   new_rule->name,
     309           0 :                                   hbac_ctx->rules[idx],
     310             :                                   &new_rule->users);
     311           0 :     if (ret != EOK) {
     312           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse users for rule [%s]\n",
     313             :                   new_rule->name);
     314           0 :         goto done;
     315             :     }
     316             : 
     317             :     /* Get the services */
     318           0 :     ret = hbac_service_attrs_to_rule(new_rule, hbac_ctx->be_ctx->domain,
     319             :                                      new_rule->name,
     320           0 :                                      hbac_ctx->rules[idx],
     321             :                                      &new_rule->services);
     322           0 :     if (ret != EOK) {
     323           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse services for rule [%s]\n",
     324             :                   new_rule->name);
     325           0 :         goto done;
     326             :     }
     327             : 
     328             :     /* Get the target hosts */
     329           0 :     ret = hbac_thost_attrs_to_rule(new_rule, hbac_ctx->be_ctx->domain,
     330             :                                    new_rule->name,
     331           0 :                                    hbac_ctx->rules[idx],
     332             :                                    &new_rule->targethosts);
     333           0 :     if (ret != EOK) {
     334           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     335             :               "Could not parse target hosts for rule [%s]\n",
     336             :                   new_rule->name);
     337           0 :         goto done;
     338             :     }
     339             : 
     340             :     /* Get the source hosts */
     341             : 
     342           0 :     ret = hbac_shost_attrs_to_rule(new_rule, hbac_ctx->be_ctx->domain,
     343             :                                    new_rule->name,
     344           0 :                                    hbac_ctx->rules[idx],
     345           0 :                                    dp_opt_get_bool(hbac_ctx->ipa_options,
     346             :                                                    IPA_HBAC_SUPPORT_SRCHOST),
     347             :                                    &new_rule->srchosts);
     348           0 :     if (ret != EOK) {
     349           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     350             :               "Could not parse source hosts for rule [%s]\n",
     351             :                   new_rule->name);
     352           0 :         goto done;
     353             :     }
     354             : 
     355           0 :     *rule = new_rule;
     356           0 :     ret = EOK;
     357             : 
     358             : done:
     359           0 :     if (ret != EOK) talloc_free(new_rule);
     360           0 :     return ret;
     361             : }
     362             : 
     363             : errno_t
     364           0 : hbac_get_category(struct sysdb_attrs *attrs,
     365             :                   const char *category_attr,
     366             :                   uint32_t *_categories)
     367             : {
     368             :     errno_t ret;
     369             :     size_t i;
     370           0 :     uint32_t cats = HBAC_CATEGORY_NULL;
     371             :     const char **categories;
     372             : 
     373           0 :     TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     374           0 :     if (tmp_ctx == NULL) return ENOMEM;
     375             : 
     376           0 :     ret = sysdb_attrs_get_string_array(attrs, category_attr,
     377             :                                        tmp_ctx, &categories);
     378           0 :     if (ret != EOK && ret != ENOENT) goto done;
     379             : 
     380           0 :     if (ret != ENOENT) {
     381           0 :         for (i = 0; categories[i]; i++) {
     382           0 :             if (strcasecmp("all", categories[i]) == 0) {
     383           0 :                 DEBUG(SSSDBG_FUNC_DATA, "Category is set to 'all'.\n");
     384           0 :                 cats |= HBAC_CATEGORY_ALL;
     385           0 :                 continue;
     386             :             }
     387           0 :             DEBUG(SSSDBG_TRACE_ALL, "Unsupported user category [%s].\n",
     388             :                       categories[i]);
     389             :         }
     390             :     }
     391             : 
     392           0 :     *_categories = cats;
     393           0 :     ret = EOK;
     394             : 
     395             : done:
     396           0 :     talloc_free(tmp_ctx);
     397           0 :     return ret;
     398             : }
     399             : 
     400             : static errno_t
     401             : hbac_eval_user_element(TALLOC_CTX *mem_ctx,
     402             :                        struct sss_domain_info *domain,
     403             :                        const char *username,
     404             :                        struct hbac_request_element **user_element);
     405             : 
     406             : static errno_t
     407             : hbac_eval_service_element(TALLOC_CTX *mem_ctx,
     408             :                           struct sss_domain_info *domain,
     409             :                           const char *servicename,
     410             :                           struct hbac_request_element **svc_element);
     411             : 
     412             : static errno_t
     413             : hbac_eval_host_element(TALLOC_CTX *mem_ctx,
     414             :                        struct sss_domain_info *domain,
     415             :                        const char *hostname,
     416             :                        struct hbac_request_element **host_element);
     417             : 
     418             : static errno_t
     419           0 : hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx,
     420             :                          struct hbac_ctx *hbac_ctx,
     421             :                          struct hbac_eval_req **request)
     422             : {
     423             :     errno_t ret;
     424           0 :     struct pam_data *pd = hbac_ctx->pd;
     425             :     TALLOC_CTX *tmp_ctx;
     426             :     struct hbac_eval_req *eval_req;
     427           0 :     struct sss_domain_info *domain = hbac_ctx->be_ctx->domain;
     428             :     const char *rhost;
     429             :     const char *thost;
     430             :     struct sss_domain_info *user_dom;
     431             : 
     432           0 :     tmp_ctx = talloc_new(mem_ctx);
     433           0 :     if (tmp_ctx == NULL) return ENOMEM;
     434             : 
     435           0 :     eval_req = talloc_zero(tmp_ctx, struct hbac_eval_req);
     436           0 :     if (eval_req == NULL) {
     437           0 :         ret = ENOMEM;
     438           0 :         goto done;
     439             :     }
     440             : 
     441           0 :     eval_req->request_time = time(NULL);
     442             : 
     443             :     /* Get user the user name and groups,
     444             :      * take care of subdomain users as well */
     445           0 :     if (strcasecmp(pd->domain, domain->name) != 0) {
     446           0 :         user_dom = find_domain_by_name(domain, pd->domain, true);
     447           0 :         if (user_dom == NULL) {
     448           0 :             DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n");
     449           0 :             ret = ENOMEM;
     450           0 :             goto done;
     451             :         }
     452           0 :         ret = hbac_eval_user_element(eval_req, user_dom, pd->user,
     453             :                                      &eval_req->user);
     454             :     } else {
     455           0 :         ret = hbac_eval_user_element(eval_req, domain, pd->user,
     456             :                                      &eval_req->user);
     457             :     }
     458           0 :     if (ret != EOK) goto done;
     459             : 
     460             :     /* Get the PAM service and service groups */
     461           0 :     ret = hbac_eval_service_element(eval_req, domain, pd->service,
     462             :                                     &eval_req->service);
     463           0 :     if (ret != EOK) goto done;
     464             : 
     465             :     /* Get the source host */
     466           0 :     if (pd->rhost == NULL || pd->rhost[0] == '\0') {
     467             :             /* If we haven't been passed an rhost,
     468             :              * the rhost is unknown. This will fail
     469             :              * to match any rule requiring the
     470             :              * source host.
     471             :              */
     472           0 :         rhost = NULL;
     473             :     } else {
     474           0 :         rhost = pd->rhost;
     475             :     }
     476             : 
     477           0 :     ret = hbac_eval_host_element(eval_req, domain, rhost,
     478             :                                  &eval_req->srchost);
     479           0 :     if (ret != EOK) goto done;
     480             : 
     481             :     /* The target host is always the current machine */
     482           0 :     thost = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME);
     483           0 :     if (thost == NULL) {
     484           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     485             :               "Missing ipa_hostname, this should never happen.\n");
     486           0 :         ret = EINVAL;
     487           0 :         goto done;
     488             :     }
     489             : 
     490           0 :     ret = hbac_eval_host_element(eval_req, domain, thost,
     491             :                                  &eval_req->targethost);
     492           0 :     if (ret != EOK) goto done;
     493             : 
     494           0 :     *request = talloc_steal(mem_ctx, eval_req);
     495             : 
     496           0 :     ret = EOK;
     497             : 
     498             : done:
     499           0 :     talloc_free(tmp_ctx);
     500           0 :     return ret;
     501             : }
     502             : 
     503             : static errno_t
     504           0 : hbac_eval_user_element(TALLOC_CTX *mem_ctx,
     505             :                        struct sss_domain_info *domain,
     506             :                        const char *username,
     507             :                        struct hbac_request_element **user_element)
     508             : {
     509             :     errno_t ret;
     510             :     unsigned int i;
     511           0 :     unsigned int num_groups = 0;
     512             :     TALLOC_CTX *tmp_ctx;
     513             :     const char *member_dn;
     514             :     struct hbac_request_element *users;
     515             :     struct ldb_message *msg;
     516             :     struct ldb_message_element *el;
     517           0 :     const char *attrs[] = { SYSDB_ORIG_MEMBEROF, NULL };
     518             : 
     519           0 :     tmp_ctx = talloc_new(mem_ctx);
     520           0 :     if (tmp_ctx == NULL) return ENOMEM;
     521             : 
     522           0 :     users = talloc_zero(tmp_ctx, struct hbac_request_element);
     523           0 :     if (users == NULL) {
     524           0 :         ret = ENOMEM;
     525           0 :         goto done;
     526             :     }
     527             : 
     528           0 :     users->name = username;
     529             : 
     530             :     /* Read the originalMemberOf attribute
     531             :      * This will give us the list of both POSIX and
     532             :      * non-POSIX groups that this user belongs to.
     533             :      */
     534           0 :     ret = sysdb_search_user_by_name(tmp_ctx, domain, users->name,
     535             :                                     attrs, &msg);
     536           0 :     if (ret != EOK) {
     537           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     538             :               "Could not determine user memberships for [%s]\n",
     539             :                   users->name);
     540           0 :         goto done;
     541             :     }
     542             : 
     543           0 :     el = ldb_msg_find_element(msg, SYSDB_ORIG_MEMBEROF);
     544           0 :     if (el == NULL || el->num_values == 0) {
     545           0 :         DEBUG(SSSDBG_TRACE_LIBS, "No groups for [%s]\n", users->name);
     546           0 :         ret = create_empty_grouplist(users);
     547           0 :         goto done;
     548             :     }
     549           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     550             :           "[%d] groups for [%s]\n", el->num_values, users->name);
     551             : 
     552           0 :     users->groups = talloc_array(users, const char *, el->num_values + 1);
     553           0 :     if (users->groups == NULL) {
     554           0 :         ret = ENOMEM;
     555           0 :         goto done;
     556             :     }
     557             : 
     558           0 :     for (i = 0; i < el->num_values; i++) {
     559           0 :         member_dn = (const char *)el->values[i].data;
     560             : 
     561           0 :         ret = get_ipa_groupname(users->groups, domain->sysdb, member_dn,
     562           0 :                                 &users->groups[num_groups]);
     563           0 :         if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) {
     564           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     565             :                     "Skipping malformed entry [%s]\n", member_dn);
     566           0 :             continue;
     567           0 :         } else if (ret == EOK) {
     568           0 :             DEBUG(SSSDBG_TRACE_LIBS, "Added group [%s] for user [%s]\n",
     569             :                       users->groups[num_groups], users->name);
     570           0 :             num_groups++;
     571           0 :             continue;
     572             :         }
     573             :         /* Skip entries that are not groups */
     574           0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
     575             :               "Skipping non-group memberOf [%s]\n", member_dn);
     576             :     }
     577           0 :     users->groups[num_groups] = NULL;
     578             : 
     579           0 :     if (num_groups < el->num_values) {
     580             :         /* Shrink the array memory */
     581           0 :         users->groups = talloc_realloc(users, users->groups, const char *,
     582             :                                        num_groups+1);
     583           0 :         if (users->groups == NULL) {
     584           0 :             ret = ENOMEM;
     585           0 :             goto done;
     586             :         }
     587             :     }
     588             : 
     589           0 :     ret = EOK;
     590             : done:
     591           0 :     if (ret == EOK) {
     592           0 :         *user_element = talloc_steal(mem_ctx, users);
     593             :     }
     594           0 :     talloc_free(tmp_ctx);
     595           0 :     return ret;
     596             : }
     597             : 
     598             : static errno_t
     599           0 : hbac_eval_service_element(TALLOC_CTX *mem_ctx,
     600             :                           struct sss_domain_info *domain,
     601             :                           const char *servicename,
     602             :                           struct hbac_request_element **svc_element)
     603             : {
     604             :     errno_t ret;
     605             :     size_t i, j, count;
     606             :     TALLOC_CTX *tmp_ctx;
     607             :     struct hbac_request_element *svc;
     608             :     struct ldb_message **msgs;
     609             :     struct ldb_message_element *el;
     610             :     struct ldb_dn *svc_dn;
     611           0 :     const char *memberof_attrs[] = { SYSDB_ORIG_MEMBEROF, NULL };
     612             :     char *name;
     613             : 
     614           0 :     tmp_ctx = talloc_new(mem_ctx);
     615           0 :     if (tmp_ctx == NULL) return ENOMEM;
     616             : 
     617           0 :     svc = talloc_zero(tmp_ctx, struct hbac_request_element);
     618           0 :     if (svc == NULL) {
     619           0 :         ret = ENOMEM;
     620           0 :         goto done;
     621             :     }
     622             : 
     623           0 :     svc->name = servicename;
     624             : 
     625           0 :     svc_dn = sysdb_custom_dn(tmp_ctx, domain, svc->name, HBAC_SERVICES_SUBDIR);
     626           0 :     if (svc_dn == NULL) {
     627           0 :         ret = ENOMEM;
     628           0 :         goto done;
     629             :     }
     630             : 
     631             :     /* Look up the service to get its originalMemberOf entries */
     632           0 :     ret = sysdb_search_entry(tmp_ctx, domain->sysdb, svc_dn,
     633             :                              LDB_SCOPE_BASE, NULL,
     634             :                              memberof_attrs,
     635             :                              &count, &msgs);
     636           0 :     if (ret == ENOENT || count == 0) {
     637             :         /* We won't be able to identify any groups
     638             :          * This rule will only match the name or
     639             :          * a service category of ALL
     640             :          */
     641           0 :         ret = create_empty_grouplist(svc);
     642           0 :         goto done;
     643           0 :     } else if (ret != EOK) {
     644           0 :         goto done;
     645           0 :     } else if (count > 1) {
     646           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for a BASE search!\n");
     647           0 :         ret = EIO;
     648           0 :         goto done;
     649             :     }
     650             : 
     651           0 :     el = ldb_msg_find_element(msgs[0], SYSDB_ORIG_MEMBEROF);
     652           0 :     if (!el) {
     653             :         /* Service is not a member of any groups
     654             :          * This rule will only match the name or
     655             :          * a service category of ALL
     656             :          */
     657           0 :         ret = create_empty_grouplist(svc);
     658           0 :         goto done;
     659             :     }
     660             : 
     661             : 
     662           0 :     svc->groups = talloc_array(svc, const char *, el->num_values + 1);
     663           0 :     if (svc->groups == NULL) {
     664           0 :         ret = ENOMEM;
     665           0 :         goto done;
     666             :     }
     667             : 
     668           0 :     for (i = j = 0; i < el->num_values; i++) {
     669           0 :         ret = get_ipa_servicegroupname(tmp_ctx, domain->sysdb,
     670           0 :                                        (const char *)el->values[i].data,
     671             :                                        &name);
     672           0 :         if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) {
     673           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n",
     674             :                                         (const char *)el->values[i].data);
     675           0 :             continue;
     676             :         }
     677             : 
     678             :         /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a
     679             :          * service group. We'll just ignore those (could be
     680             :          * HBAC rules)
     681             :          */
     682             : 
     683           0 :         if (ret == EOK) {
     684           0 :             svc->groups[j] = talloc_steal(svc->groups, name);
     685           0 :             j++;
     686             :         }
     687             :     }
     688           0 :     svc->groups[j] = NULL;
     689             : 
     690           0 :     ret = EOK;
     691             : 
     692             : done:
     693           0 :     if (ret == EOK) {
     694           0 :         *svc_element = talloc_steal(mem_ctx, svc);
     695             :     }
     696           0 :     talloc_free(tmp_ctx);
     697           0 :     return ret;
     698             : }
     699             : 
     700             : static errno_t
     701           0 : hbac_eval_host_element(TALLOC_CTX *mem_ctx,
     702             :                        struct sss_domain_info *domain,
     703             :                        const char *hostname,
     704             :                        struct hbac_request_element **host_element)
     705             : {
     706             :     errno_t ret;
     707             :     size_t i, j, count;
     708             :     TALLOC_CTX *tmp_ctx;
     709             :     struct hbac_request_element *host;
     710             :     struct ldb_message **msgs;
     711             :     struct ldb_message_element *el;
     712             :     struct ldb_dn *host_dn;
     713           0 :     const char *memberof_attrs[] = { SYSDB_ORIG_MEMBEROF, NULL };
     714             :     char *name;
     715             : 
     716           0 :     tmp_ctx = talloc_new(mem_ctx);
     717           0 :     if (tmp_ctx == NULL) return ENOMEM;
     718             : 
     719           0 :     host = talloc_zero(tmp_ctx, struct hbac_request_element);
     720           0 :     if (host == NULL) {
     721           0 :         ret = ENOMEM;
     722           0 :         goto done;
     723             :     }
     724             : 
     725           0 :     host->name = hostname;
     726             : 
     727           0 :     if (host->name == NULL) {
     728             :         /* We don't know the host (probably an rhost)
     729             :          * So we can't determine it's groups either.
     730             :          */
     731           0 :         ret = create_empty_grouplist(host);
     732           0 :         goto done;
     733             :     }
     734             : 
     735           0 :     host_dn = sysdb_custom_dn(tmp_ctx, domain, host->name, HBAC_HOSTS_SUBDIR);
     736           0 :     if (host_dn == NULL) {
     737           0 :         ret = ENOMEM;
     738           0 :         goto done;
     739             :     }
     740             : 
     741             :     /* Look up the host to get its originalMemberOf entries */
     742           0 :     ret = sysdb_search_entry(tmp_ctx, domain->sysdb, host_dn,
     743             :                              LDB_SCOPE_BASE, NULL,
     744             :                              memberof_attrs,
     745             :                              &count, &msgs);
     746           0 :     if (ret == ENOENT || count == 0) {
     747             :         /* We won't be able to identify any groups
     748             :          * This rule will only match the name or
     749             :          * a host category of ALL
     750             :          */
     751           0 :         ret = create_empty_grouplist(host);
     752           0 :         goto done;
     753           0 :     } else if (ret != EOK) {
     754           0 :         goto done;
     755           0 :     } else if (count > 1) {
     756           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for a BASE search!\n");
     757           0 :         ret = EIO;
     758           0 :         goto done;
     759             :     }
     760             : 
     761           0 :     el = ldb_msg_find_element(msgs[0], SYSDB_ORIG_MEMBEROF);
     762           0 :     if (!el) {
     763             :         /* Host is not a member of any groups
     764             :          * This rule will only match the name or
     765             :          * a host category of ALL
     766             :          */
     767           0 :         ret = create_empty_grouplist(host);
     768           0 :         goto done;
     769             :     }
     770             : 
     771             : 
     772           0 :     host->groups = talloc_array(host, const char *, el->num_values + 1);
     773           0 :     if (host->groups == NULL) {
     774           0 :         ret = ENOMEM;
     775           0 :         goto done;
     776             :     }
     777             : 
     778           0 :     for (i = j = 0; i < el->num_values; i++) {
     779           0 :         ret = get_ipa_hostgroupname(tmp_ctx, domain->sysdb,
     780           0 :                                     (const char *)el->values[i].data,
     781             :                                     &name);
     782           0 :         if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) {
     783           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n",
     784             :                                         (const char *)el->values[i].data);
     785           0 :             continue;
     786             :         }
     787             : 
     788             :         /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a
     789             :          * host group. We'll just ignore those (could be
     790             :          * HBAC rules)
     791             :          */
     792             : 
     793           0 :         if (ret == EOK) {
     794           0 :             host->groups[j] = talloc_steal(host->groups, name);
     795           0 :             j++;
     796             :         }
     797             :     }
     798           0 :     host->groups[j] = NULL;
     799             : 
     800           0 :     ret = EOK;
     801             : 
     802             : done:
     803           0 :     if (ret == EOK) {
     804           0 :         *host_element = talloc_steal(mem_ctx, host);
     805             :     }
     806           0 :     talloc_free(tmp_ctx);
     807           0 :     return ret;
     808             : }

Generated by: LCOV version 1.10