LCOV - code coverage report
Current view: top level - providers/ipa - ipa_idmap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 154 42.2 %
Date: 2016-06-29 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Sumit Bose <sbose@redhat.com>
       6             : 
       7             :     Copyright (C) 2013 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             : 
      24             : #include "util/util.h"
      25             : #include "providers/ldap/sdap_idmap.h"
      26             : #include "providers/ipa/ipa_common.h"
      27             : #include "util/util_sss_idmap.h"
      28             : 
      29           1 : static errno_t ipa_idmap_check_posix_child(struct sdap_idmap_ctx *idmap_ctx,
      30             :                                            const char *dom_name,
      31             :                                            const char *dom_sid_str,
      32             :                                            size_t range_count,
      33             :                                            struct range_info **range_list)
      34             : {
      35             :     bool has_algorithmic_mapping;
      36             :     enum idmap_error_code err;
      37             :     struct sss_domain_info *dom;
      38             :     struct sss_domain_info *forest_root;
      39             :     size_t c;
      40             :     struct sss_idmap_range range;
      41             :     struct range_info *r;
      42             :     char *range_id;
      43             :     TALLOC_CTX *tmp_ctx;
      44           1 :     bool found = false;
      45             :     int ret;
      46             : 
      47           1 :     err = sss_idmap_domain_has_algorithmic_mapping(idmap_ctx->map, dom_sid_str,
      48             :                                                    &has_algorithmic_mapping);
      49           1 :     if (err == IDMAP_SUCCESS) {
      50           1 :         DEBUG(SSSDBG_TRACE_ALL,
      51             :               "Idmap of domain [%s] already known, nothing to do.\n",
      52             :                 dom_sid_str);
      53           1 :         return EOK;
      54             :     } else {
      55           0 :         err = sss_idmap_domain_by_name_has_algorithmic_mapping(idmap_ctx->map,
      56             :                                                       dom_name,
      57             :                                                       &has_algorithmic_mapping);
      58           0 :         if (err == IDMAP_SUCCESS) {
      59           0 :             DEBUG(SSSDBG_TRACE_ALL,
      60             :                   "Idmap of domain [%s] already known, nothing to do.\n",
      61             :                     dom_sid_str);
      62           0 :             return EOK;
      63             :         }
      64             :     }
      65           0 :     DEBUG(SSSDBG_TRACE_ALL, "Trying to add idmap for domain [%s].\n",
      66             :                              dom_sid_str);
      67             : 
      68           0 :     if (err != IDMAP_SID_UNKNOWN && err != IDMAP_NAME_UNKNOWN) {
      69           0 :         DEBUG(SSSDBG_OP_FAILURE,
      70             :               "sss_idmap_domain_has_algorithmic_mapping failed.\n");
      71           0 :         return EINVAL;
      72             :     }
      73             : 
      74           0 :     dom = find_domain_by_sid(idmap_ctx->id_ctx->be->domain, dom_sid_str);
      75           0 :     if (dom == NULL) {
      76           0 :         DEBUG(SSSDBG_OP_FAILURE,
      77             :               "find_domain_by_sid failed with SID [%s].\n", dom_sid_str);
      78           0 :         return EINVAL;
      79             :     }
      80             : 
      81           0 :     if (dom->forest == NULL) {
      82           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "No forest available for domain [%s].\n",
      83             :                                      dom_sid_str);
      84           0 :         return EINVAL;
      85             :     }
      86             : 
      87           0 :     forest_root = find_domain_by_name(idmap_ctx->id_ctx->be->domain,
      88           0 :                                       dom->forest, true);
      89           0 :     if (forest_root == NULL) {
      90           0 :         DEBUG(SSSDBG_OP_FAILURE,
      91             :               "find_domain_by_name failed to find forest root [%s].\n",
      92             :                dom->forest);
      93           0 :         return ENOENT;
      94             :     }
      95             : 
      96           0 :     if (forest_root->domain_id == NULL) {
      97           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Forest root [%s] does not have a SID.\n",
      98             :                                      dom->forest);
      99           0 :         return EINVAL;
     100             :     }
     101             : 
     102           0 :     tmp_ctx = talloc_new(NULL);
     103           0 :     if (tmp_ctx == NULL) {
     104           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     105           0 :         return ENOMEM;
     106             :     }
     107             : 
     108           0 :     for (c = 0; c < range_count; c++) {
     109           0 :         r = range_list[c];
     110           0 :         if (r->trusted_dom_sid != NULL
     111           0 :                 && strcmp(r->trusted_dom_sid, forest_root->domain_id) == 0) {
     112             : 
     113           0 :             if (r->range_type == NULL
     114           0 :                     || strcmp(r->range_type, IPA_RANGE_AD_TRUST_POSIX) != 0) {
     115           0 :                 DEBUG(SSSDBG_MINOR_FAILURE,
     116             :                       "Forest root does not have range type [%s].\n",
     117             :                        IPA_RANGE_AD_TRUST_POSIX);
     118           0 :                 ret = EINVAL;
     119           0 :                 goto done;
     120             :             }
     121             : 
     122           0 :             range.min = r->base_id;
     123           0 :             range.max = r->base_id + r->id_range_size -1;
     124           0 :             range_id = talloc_asprintf(tmp_ctx, "%s-%s", dom_sid_str, r->name);
     125           0 :             if (range_id == NULL) {
     126           0 :                 DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     127           0 :                 ret = ENOMEM;
     128           0 :                 goto done;
     129             :             }
     130             : 
     131           0 :             err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid_str,
     132             :                                           &range, range_id, 0, true);
     133           0 :             if (err != IDMAP_SUCCESS && err != IDMAP_COLLISION) {
     134           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     135             :                       "Could not add range [%s] to ID map\n", range_id);
     136           0 :                 ret = EIO;
     137           0 :                 goto done;
     138             :             }
     139             : 
     140           0 :             found = true;
     141             :         }
     142             :     }
     143             : 
     144           0 :     if (!found) {
     145           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "No idrange found for forest root [%s].\n",
     146             :                                      forest_root->domain_id);
     147           0 :         ret = ENOENT;
     148           0 :         goto done;
     149             :     }
     150             : 
     151           0 :     ret = EOK;
     152             : 
     153             : done:
     154           0 :     talloc_free(tmp_ctx);
     155             : 
     156           0 :     return ret;
     157             : }
     158             : 
     159           5 : errno_t get_idmap_data_from_range(struct range_info *r, char *domain_name,
     160             :                                   char **_name, char **_sid, uint32_t *_rid,
     161             :                                   struct sss_idmap_range *_range,
     162             :                                   bool *_external_mapping)
     163             : {
     164           5 :     if (r->range_type == NULL) {
     165             :         /* Older IPA servers might not have the range_type attribute, but
     166             :          * only support local ranges and trusts with algorithmic mapping. */
     167             : 
     168           1 :         if (r->trusted_dom_sid == NULL && r->secondary_base_rid != 0) {
     169             :             /* local IPA domain */
     170           1 :             *_rid = 0;
     171           1 :             *_external_mapping = true;
     172           1 :             *_name = domain_name;
     173           1 :             *_sid = NULL;
     174           0 :         } else if (r->trusted_dom_sid != NULL
     175           0 :                 && r->secondary_base_rid == 0) {
     176             :             /* trusted domain */
     177           0 :             *_rid = r->base_rid;
     178           0 :             *_external_mapping = false;
     179           0 :             *_name = r->trusted_dom_sid;
     180           0 :             *_sid = r->trusted_dom_sid;
     181             :         } else {
     182           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Cannot determine range type, " \
     183             :                                         "for id range [%s].\n",
     184             :                                         r->name);
     185           0 :             return EINVAL;
     186             :         }
     187             :     } else {
     188           4 :         if (strcmp(r->range_type, IPA_RANGE_LOCAL) == 0) {
     189           1 :             *_rid = 0;
     190           1 :             *_external_mapping = true;
     191           1 :             *_name = domain_name;
     192           1 :             *_sid = NULL;
     193           3 :         } else if (strcmp(r->range_type, IPA_RANGE_AD_TRUST_POSIX) == 0) {
     194           0 :             *_rid = 0;
     195           0 :             *_external_mapping = true;
     196           0 :             *_name = r->trusted_dom_sid;
     197           0 :             *_sid = r->trusted_dom_sid;
     198           3 :         } else if (strcmp(r->range_type, IPA_RANGE_AD_TRUST) == 0) {
     199           3 :             *_rid = r->base_rid;
     200           3 :             *_external_mapping = false;
     201           3 :             *_name = r->trusted_dom_sid;
     202           3 :             *_sid = r->trusted_dom_sid;
     203             :         } else {
     204           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Range type [%s] of id range " \
     205             :                                         "[%s] not supported.\n", \
     206             :                                         r->range_type, r->name);
     207           0 :             return EINVAL;
     208             :         }
     209             :     }
     210             : 
     211           5 :     _range->min = r->base_id;
     212           5 :     _range->max = r->base_id + r->id_range_size -1;
     213             : 
     214           5 :     return EOK;
     215             : }
     216             : 
     217           3 : errno_t ipa_idmap_get_ranges_from_sysdb(struct sdap_idmap_ctx *idmap_ctx,
     218             :                                         const char *dom_name,
     219             :                                         const char *dom_sid_str,
     220             :                                         bool allow_collisions)
     221             : {
     222             :     int ret;
     223             :     size_t range_count;
     224             :     struct range_info **range_list;
     225             :     TALLOC_CTX *tmp_ctx;
     226             :     size_t c;
     227             :     enum idmap_error_code err;
     228             :     struct sss_idmap_range range;
     229             :     uint32_t rid;
     230             :     bool external_mapping;
     231             :     char *name;
     232             :     char *sid;
     233             : 
     234           3 :     tmp_ctx = talloc_new(NULL);
     235           3 :     if (tmp_ctx == NULL) {
     236           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     237           0 :         return ENOMEM;
     238             :     }
     239             : 
     240           3 :     ret = sysdb_get_ranges(tmp_ctx, idmap_ctx->id_ctx->be->domain->sysdb,
     241             :                            &range_count, &range_list);
     242           3 :     if (ret != EOK) {
     243           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_ranges failed.\n");
     244           0 :         goto done;
     245             :     }
     246             : 
     247           5 :     for (c = 0; c < range_count; c++) {
     248           3 :         ret = get_idmap_data_from_range(range_list[c],
     249           3 :                                         idmap_ctx->id_ctx->be->domain->name,
     250             :                                         &name, &sid, &rid, &range,
     251             :                                         &external_mapping);
     252           3 :         if (ret != EOK) {
     253           0 :             DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed for " \
     254             :                                      "id range [%s], skipping.\n",
     255             :                                      range_list[c]->name);
     256           0 :             continue;
     257             :         }
     258             : 
     259           6 :         err = sss_idmap_add_domain_ex(idmap_ctx->map, name, sid, &range,
     260           3 :                                       range_list[c]->name, rid,
     261             :                                       external_mapping);
     262           3 :         if (err != IDMAP_SUCCESS) {
     263           2 :             if (!allow_collisions || err != IDMAP_COLLISION) {
     264           1 :                 DEBUG(SSSDBG_CRIT_FAILURE, "Could not add range [%s] to ID map\n",
     265             :                                            range_list[c]->name);
     266           1 :                 ret = EIO;
     267           1 :                 goto done;
     268             :             }
     269             :         }
     270             :     }
     271             : 
     272           2 :     if (dom_name != NULL || dom_sid_str != NULL) {
     273           1 :         ret = ipa_idmap_check_posix_child(idmap_ctx, dom_name, dom_sid_str,
     274             :                                           range_count, range_list);
     275           1 :         if (ret != EOK) {
     276           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_check_posix_child failed.\n");
     277           0 :             goto done;
     278             :         }
     279             :     }
     280             : 
     281           2 :     ret = EOK;
     282             : 
     283             : done:
     284           3 :     talloc_free(tmp_ctx);
     285             : 
     286           3 :     return ret;
     287             : }
     288             : 
     289           0 : errno_t ipa_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx,
     290             :                                   const char *dom_name,
     291             :                                   const char *dom_sid_str)
     292             : {
     293           0 :     return ipa_idmap_get_ranges_from_sysdb(idmap_ctx, dom_name, dom_sid_str,
     294             :                                            true);
     295             : }
     296             : 
     297           1 : errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx,
     298             :                        struct sdap_id_ctx *id_ctx,
     299             :                        struct sdap_idmap_ctx **_idmap_ctx)
     300             : {
     301             :     errno_t ret;
     302             :     TALLOC_CTX *tmp_ctx;
     303             :     enum idmap_error_code err;
     304           1 :     struct sdap_idmap_ctx *idmap_ctx = NULL;
     305             : 
     306           1 :     tmp_ctx = talloc_new(NULL);
     307           1 :     if (!tmp_ctx) return ENOMEM;
     308             : 
     309           1 :     idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
     310           1 :     if (!idmap_ctx) {
     311           0 :         ret = ENOMEM;
     312           0 :         goto done;
     313             :     }
     314           1 :     idmap_ctx->id_ctx = id_ctx;
     315           1 :     idmap_ctx->find_new_domain = ipa_idmap_find_new_domain;
     316             : 
     317             :     /* Initialize the map */
     318           1 :     err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
     319             :                          sss_idmap_talloc_free,
     320             :                          &idmap_ctx->map);
     321           1 :     if (err != IDMAP_SUCCESS) {
     322           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     323             :               "Could not initialize the ID map: [%s]\n",
     324             :                idmap_error_string(err));
     325           0 :         if (err == IDMAP_OUT_OF_MEMORY) {
     326           0 :             ret = ENOMEM;
     327             :         } else {
     328           0 :             ret = EINVAL;
     329             :         }
     330           0 :         goto done;
     331             :     }
     332             : 
     333           1 :     ret = ipa_idmap_get_ranges_from_sysdb(idmap_ctx, NULL, NULL, false);
     334           1 :     if (ret != EOK) {
     335           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_get_ranges_from_sysdb failed.\n");
     336           0 :         goto done;
     337             :     }
     338             : 
     339           1 :     *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
     340           1 :     ret = EOK;
     341             : 
     342             : done:
     343           1 :     talloc_free(tmp_ctx);
     344           1 :     return ret;
     345             : }

Generated by: LCOV version 1.10