LCOV - code coverage report
Current view: top level - providers/ldap - sdap_idmap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 79 252 31.3 %
Date: 2016-06-29 Functions: 4 8 50.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@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 "util/dlinklist.h"
      25             : #include "util/murmurhash3.h"
      26             : #include "providers/ldap/sdap_idmap.h"
      27             : #include "util/util_sss_idmap.h"
      28             : 
      29             : static errno_t
      30           9 : sdap_idmap_get_configured_external_range(struct sdap_idmap_ctx *idmap_ctx,
      31             :                                          struct sss_idmap_range *range)
      32             : {
      33             :     int int_id;
      34             :     struct sdap_id_ctx *id_ctx;
      35             :     uint32_t min;
      36             :     uint32_t max;
      37             : 
      38           9 :     if (idmap_ctx == NULL) {
      39           0 :         return EINVAL;
      40             :     }
      41             : 
      42           9 :     id_ctx = idmap_ctx->id_ctx;
      43             : 
      44           9 :     int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MIN_ID);
      45           9 :     if (int_id < 0) {
      46           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "ldap_min_id must be greater than 0.\n");
      47           0 :         return EINVAL;
      48             :     }
      49           9 :     min = int_id;
      50             : 
      51           9 :     int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MAX_ID);
      52           9 :     if (int_id < 0) {
      53           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "ldap_max_id must be greater than 0.\n");
      54           0 :         return EINVAL;
      55             :     }
      56           9 :     max = int_id;
      57             : 
      58           9 :     if ((min == 0 && max != 0) || (min != 0 && max == 0)) {
      59           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "Both ldap_min_id and ldap_max_id " \
      60             :                                      "either must be 0 (not set) " \
      61             :                                      "or positive integers.\n");
      62           0 :         return EINVAL;
      63             :     }
      64             : 
      65           9 :     if (min == 0 && max == 0) {
      66             :         /* ldap_min_id and ldap_max_id not set, using min_id and max_id */
      67           9 :         min = id_ctx->be->domain->id_min;
      68           9 :         max = id_ctx->be->domain->id_max;
      69           9 :         if (max == 0) {
      70           9 :             max = UINT32_MAX;
      71             :         }
      72             :     }
      73             : 
      74           9 :     range->min = min;
      75           9 :     range->max =max;
      76             : 
      77           9 :     return EOK;
      78             : }
      79             : 
      80             : static errno_t
      81           9 : sdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
      82             : {
      83             :     int ret;
      84             :     struct sss_idmap_range range;
      85             :     struct sdap_id_ctx *id_ctx;
      86             :     enum idmap_error_code err;
      87             : 
      88           9 :     ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range);
      89           9 :     if (ret != EOK) {
      90           0 :         DEBUG(SSSDBG_OP_FAILURE,
      91             :               "sdap_idmap_get_configured_external_range failed.\n");
      92           0 :         return ret;
      93             :     }
      94             : 
      95           9 :     id_ctx = idmap_ctx->id_ctx;
      96             : 
      97           9 :     err = sss_idmap_add_auto_domain_ex(idmap_ctx->map,
      98           9 :                                        id_ctx->be->domain->name,
      99           9 :                                        id_ctx->be->domain->domain_id, &range,
     100             :                                        NULL, 0, true, NULL, NULL);
     101           9 :     if (err != IDMAP_SUCCESS) {
     102           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     103             :               "Could not add domain [%s] to the map: [%d]\n",
     104             :                id_ctx->be->domain->name, err);
     105           0 :         return EIO;
     106             :     }
     107             : 
     108           9 :     return EOK;
     109             : }
     110             : 
     111           0 : errno_t sdap_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx,
     112             :                                    const char *dom_name,
     113             :                                    const char *dom_sid_str)
     114             : {
     115             :     int ret;
     116             : 
     117           0 :     ret = sdap_idmap_add_domain(idmap_ctx,
     118             :                                 dom_name, dom_sid_str,
     119             :                                 -1);
     120           0 :     if (ret != EOK) {
     121           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     122             :               "Could not add new domain [%s]\n", dom_name);
     123           0 :         return ret;
     124             :     }
     125             : 
     126           0 :     return EOK;
     127             : }
     128             : 
     129             : errno_t
     130           9 : sdap_idmap_init(TALLOC_CTX *mem_ctx,
     131             :                 struct sdap_id_ctx *id_ctx,
     132             :                 struct sdap_idmap_ctx **_idmap_ctx)
     133             : {
     134             :     errno_t ret;
     135             :     TALLOC_CTX *tmp_ctx;
     136             :     enum idmap_error_code err;
     137             :     size_t i;
     138             :     struct ldb_result *res;
     139             :     const char *dom_name;
     140             :     const char *sid_str;
     141             :     id_t slice_num;
     142             :     id_t idmap_lower;
     143             :     id_t idmap_upper;
     144             :     id_t rangesize;
     145             :     bool autorid_mode;
     146             :     int extra_slice_init;
     147           9 :     struct sdap_idmap_ctx *idmap_ctx = NULL;
     148             : 
     149           9 :     tmp_ctx = talloc_new(NULL);
     150           9 :     if (!tmp_ctx) return ENOMEM;
     151             : 
     152           9 :     idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
     153           9 :     if (!idmap_ctx) {
     154           0 :         ret = ENOMEM;
     155           0 :         goto done;
     156             :     }
     157           9 :     idmap_ctx->id_ctx = id_ctx;
     158           9 :     idmap_ctx->find_new_domain = sdap_idmap_find_new_domain;
     159             : 
     160           9 :     idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
     161             :                                  SDAP_IDMAP_LOWER);
     162           9 :     idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
     163             :                                  SDAP_IDMAP_UPPER);
     164           9 :     rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
     165             :                                SDAP_IDMAP_RANGESIZE);
     166           9 :     autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
     167             :                                    SDAP_IDMAP_AUTORID_COMPAT);
     168           9 :     extra_slice_init = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
     169             :                                      SDAP_IDMAP_EXTRA_SLICE_INIT);
     170             : 
     171             :     /* Validate that the values make sense */
     172           9 :     if (rangesize <= 0
     173           9 :             || idmap_upper <= idmap_lower
     174           9 :             || (idmap_upper-idmap_lower) < rangesize)
     175             :     {
     176           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     177             :               "Invalid settings for range selection: "
     178             :                "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n",
     179             :                idmap_lower, idmap_upper, rangesize);
     180           0 :         ret = EINVAL;
     181           0 :         goto done;
     182             :     }
     183             : 
     184           9 :     if (((idmap_upper - idmap_lower) % rangesize) != 0) {
     185           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
     186             :               "Range size does not divide evenly. Uppermost range will "
     187             :                "not be used\n");
     188             :     }
     189             : 
     190             :     /* Initialize the map */
     191           9 :     err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
     192             :                          sss_idmap_talloc_free,
     193             :                          &idmap_ctx->map);
     194           9 :     if (err != IDMAP_SUCCESS) {
     195           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     196             :               "Could not initialize the ID map: [%s]\n",
     197             :                idmap_error_string(err));
     198           0 :         if (err == IDMAP_OUT_OF_MEMORY) {
     199           0 :             ret = ENOMEM;
     200             :         } else {
     201           0 :             ret = EINVAL;
     202             :         }
     203           0 :         goto done;
     204             :     }
     205             : 
     206           9 :     err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
     207           9 :     err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
     208           9 :     err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
     209           9 :     err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
     210           9 :     err |= sss_idmap_ctx_set_extra_slice_init(idmap_ctx->map, extra_slice_init);
     211           9 :     if (err != IDMAP_SUCCESS) {
     212             :         /* This should never happen */
     213           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n");
     214           0 :         ret = EIO;
     215           0 :         goto done;
     216             :     }
     217             : 
     218             : 
     219             :     /* Setup range for externally managed IDs, i.e. IDs are read from the
     220             :      * ldap_user_uid_number and ldap_group_gid_number attributes. */
     221           9 :     if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
     222           9 :         ret = sdap_idmap_add_configured_external_range(idmap_ctx);
     223           9 :         if (ret != EOK) {
     224           0 :             DEBUG(SSSDBG_OP_FAILURE,
     225             :                   "sdap_idmap_add_configured_external_range failed.\n");
     226           0 :             goto done;
     227             :         }
     228             :     }
     229             : 
     230             :     /* Read in any existing mappings from the cache */
     231           9 :     ret = sysdb_idmap_get_mappings(tmp_ctx, id_ctx->be->domain, &res);
     232           9 :     if (ret != EOK && ret != ENOENT) {
     233           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     234             :               "Could not read ID mappings from the cache: [%s]\n",
     235             :                strerror(ret));
     236           0 :         goto done;
     237             :     }
     238             : 
     239           9 :     if (ret == EOK) {
     240           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
     241             :               "Initializing [%d] domains for ID-mapping\n", res->count);
     242             : 
     243           0 :         for (i = 0; i < res->count; i++) {
     244           0 :             dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
     245             :                                                    SYSDB_NAME,
     246             :                                                    NULL);
     247           0 :             if (!dom_name) {
     248             :                 /* This should never happen */
     249           0 :                 ret = EINVAL;
     250           0 :                 goto done;
     251             :             }
     252             : 
     253           0 :             sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
     254             :                                                   SYSDB_IDMAP_SID_ATTR,
     255             :                                                   NULL);
     256           0 :             if (!sid_str) {
     257             :                 /* This should never happen */
     258           0 :                 ret = EINVAL;
     259           0 :                 goto done;
     260             :             }
     261             : 
     262           0 :             slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
     263             :                                                  SYSDB_IDMAP_SLICE_ATTR,
     264             :                                                  -1);
     265           0 :             if (slice_num == -1) {
     266             :                 /* This should never happen */
     267           0 :                 ret = EINVAL;
     268           0 :                 goto done;
     269             :             }
     270             : 
     271           0 :             ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
     272             :                                         sid_str, slice_num);
     273           0 :             if (ret != EOK) {
     274           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     275             :                       "Could not add domain [%s][%s][%"SPRIid"] "
     276             :                        "to ID map: [%s]\n",
     277             :                        dom_name, sid_str, slice_num, strerror(ret));
     278           0 :                 goto done;
     279             :             }
     280             :         }
     281             :     } else {
     282             :         /* This is the first time we're setting up id-mapping
     283             :          * Store the default domain as slice 0
     284             :          */
     285           9 :         dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
     286           9 :         if (!dom_name) {
     287             :             /* If it's not explicitly specified, use the SSSD domain name */
     288           9 :             dom_name = idmap_ctx->id_ctx->be->domain->name;
     289           9 :             ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
     290             :                                     SDAP_IDMAP_DEFAULT_DOMAIN,
     291             :                                     dom_name);
     292           9 :             if (ret != EOK) goto done;
     293             :         }
     294             : 
     295           9 :         sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
     296           9 :         if (sid_str) {
     297           0 :             struct sss_domain_info *domain = idmap_ctx->id_ctx->be->domain;
     298           0 :             domain->domain_id = talloc_strdup(domain, sid_str);
     299           0 :             if (domain->domain_id == NULL) {
     300           0 :                 ret = ENOMEM;
     301           0 :                 goto done;
     302             :             }
     303             : 
     304             :             /* Set the default domain as slice 0 */
     305           0 :             ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
     306             :                                         sid_str, 0);
     307           0 :             if (ret != EOK) {
     308           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     309             :                       "Could not add domain [%s][%s][%u] to ID map: [%s]\n",
     310             :                        dom_name, sid_str, 0, strerror(ret));
     311           0 :                 goto done;
     312             :             }
     313             :         } else {
     314           9 :             if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
     315             :                 /* In autorid compatibility mode, we MUST have a slice 0 */
     316           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     317             :                       "WARNING: Autorid compatibility mode selected, "
     318             :                        "but %s is not set. UID/GID values may differ "
     319             :                        "between clients.\n",
     320             :                        idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name);
     321             :             }
     322             :             /* Otherwise, we'll just fall back to hash values as they are seen */
     323             :         }
     324             :     }
     325             : 
     326           9 :     *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
     327           9 :     ret = EOK;
     328             : 
     329             : done:
     330           9 :     talloc_free(tmp_ctx);
     331           9 :     return ret;
     332             : }
     333             : 
     334             : errno_t
     335           0 : sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
     336             :                       const char *dom_name,
     337             :                       const char *dom_sid,
     338             :                       id_t slice)
     339             : {
     340             :     errno_t ret;
     341             :     struct sss_idmap_range range;
     342             :     enum idmap_error_code err;
     343             :     id_t idmap_upper;
     344           0 :     bool external_mapping = true;
     345             : 
     346           0 :     ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper);
     347           0 :     if (ret != IDMAP_SUCCESS) {
     348           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     349             :               "Failed to get upper bound of available ID range.\n");
     350           0 :         ret = EIO;
     351           0 :         goto done;
     352             :     }
     353             : 
     354           0 :     if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
     355           0 :         external_mapping = false;
     356           0 :         ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range);
     357           0 :         if (ret != IDMAP_SUCCESS) {
     358           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     359             :                   "Failed to calculate range for domain [%s]: [%d]\n", dom_name,
     360             :                    ret);
     361           0 :             ret = EIO;
     362           0 :             goto done;
     363             :         }
     364           0 :         DEBUG(SSSDBG_TRACE_LIBS,
     365             :               "Adding domain [%s] as slice [%"SPRIid"]\n", dom_sid, slice);
     366             : 
     367           0 :         if (range.max > idmap_upper) {
     368             :             /* This should never happen */
     369           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     370             :                   "BUG: Range maximum exceeds the global maximum: "
     371             :                    "%u > %"SPRIid"\n", range.max, idmap_upper);
     372           0 :             ret = EINVAL;
     373           0 :             goto done;
     374             :         }
     375             :     } else {
     376           0 :         ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range);
     377           0 :         if (ret != EOK) {
     378           0 :             DEBUG(SSSDBG_OP_FAILURE,
     379             :                   "sdap_idmap_get_configured_external_range failed.\n");
     380           0 :             return ret;
     381             :         }
     382             :     }
     383             : 
     384             :     /* Add this domain to the map */
     385           0 :     err = sss_idmap_add_auto_domain_ex(idmap_ctx->map, dom_name, dom_sid,
     386             :                                        &range, NULL, 0, external_mapping,
     387             :                                        NULL, NULL);
     388           0 :     if (err != IDMAP_SUCCESS) {
     389           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     390             :               "Could not add domain [%s] to the map: [%d]\n",
     391             :                dom_name, err);
     392           0 :         ret = EIO;
     393           0 :         goto done;
     394             :     }
     395             : 
     396             :     /* If algorithmic mapping is used add this domain to the SYSDB cache so it
     397             :      * will survive reboot */
     398           0 :     if (!external_mapping) {
     399           0 :         ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain,
     400             :                                         dom_name, dom_sid,
     401             :                                         slice);
     402           0 :         if (ret != EOK) {
     403           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_idmap_store_mapping failed.\n");
     404           0 :             goto done;
     405             :         }
     406             :     }
     407             : 
     408             : done:
     409           0 :     return ret;
     410             : }
     411             : 
     412             : errno_t
     413           0 : sdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx,
     414             :                                    const char *object_sid,
     415             :                                    char **dom_sid_str)
     416             : {
     417             :     const char *p;
     418             :     long long a;
     419             :     size_t c;
     420             :     char *endptr;
     421             : 
     422           0 :     if (object_sid == NULL
     423           0 :             || strncmp(object_sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
     424           0 :         return EINVAL;
     425             :     }
     426             : 
     427           0 :     p = object_sid + DOM_SID_PREFIX_LEN;
     428           0 :     c = 0;
     429             : 
     430             :     do {
     431           0 :         errno = 0;
     432           0 :         a = strtoull(p, &endptr, 10);
     433           0 :         if (errno != 0 || a > UINT32_MAX) {
     434           0 :             return EINVAL;
     435             :         }
     436             : 
     437           0 :         if (*endptr == '-') {
     438           0 :             p = endptr + 1;
     439             :         } else {
     440           0 :             return EINVAL;
     441             :         }
     442           0 :         c++;
     443           0 :     } while(c < 3);
     444             : 
     445             :     /* If we made it here, we are now one character past
     446             :      * the last hyphen in the object-sid.
     447             :      * Copy the dom-sid substring.
     448             :      */
     449           0 :     *dom_sid_str = talloc_strndup(mem_ctx, object_sid,
     450           0 :                                   (endptr-object_sid));
     451           0 :     if (!*dom_sid_str) return ENOMEM;
     452             : 
     453           0 :     return EOK;
     454             : }
     455             : 
     456             : errno_t
     457           0 : sdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx,
     458             :                        const char *sid_str,
     459             :                        id_t *id)
     460             : {
     461             :     errno_t ret;
     462             :     enum idmap_error_code err;
     463           0 :     char *dom_sid_str = NULL;
     464             : 
     465             :     /* Convert the SID into a UNIX ID */
     466           0 :     err = sss_idmap_sid_to_unix(idmap_ctx->map,
     467             :                                 sid_str,
     468             :                                 (uint32_t *)id);
     469           0 :     switch (err) {
     470             :     case IDMAP_SUCCESS:
     471           0 :         break;
     472             :     case IDMAP_NO_DOMAIN:
     473             :         /* This is the first time we've seen this domain
     474             :          * Create a new domain for it. We'll use the dom-sid
     475             :          * as the domain name for now, since we don't have
     476             :          * any way to get the real name.
     477             :          */
     478           0 :         ret = sdap_idmap_get_dom_sid_from_object(NULL, sid_str,
     479             :                                                  &dom_sid_str);
     480           0 :         if (ret != EOK) {
     481           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     482             :                   "Could not parse domain SID from [%s]\n", sid_str);
     483           0 :             goto done;
     484             :         }
     485             : 
     486           0 :         ret = idmap_ctx->find_new_domain(idmap_ctx, dom_sid_str, dom_sid_str);
     487           0 :         if (ret != EOK) {
     488           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     489             :                   "Could not add new domain for sid [%s]\n", sid_str);
     490           0 :             goto done;
     491             :         }
     492             : 
     493             :         /* Now try converting to a UNIX ID again */
     494           0 :         err = sss_idmap_sid_to_unix(idmap_ctx->map,
     495             :                                     sid_str,
     496             :                                     (uint32_t *)id);
     497           0 :         if (err != IDMAP_SUCCESS) {
     498           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     499             :                   "Could not convert objectSID [%s] to a UNIX ID\n",
     500             :                    sid_str);
     501           0 :             ret = EIO;
     502           0 :             goto done;
     503             :         }
     504           0 :         break;
     505             :     case IDMAP_BUILTIN_SID:
     506           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     507             :               "Object SID [%s] is a built-in one.\n", sid_str);
     508             :         /* ENOTSUP indicates built-in SID */
     509           0 :         ret = ENOTSUP;
     510           0 :         goto done;
     511             :         break;
     512             :     case IDMAP_NO_RANGE:
     513           0 :         DEBUG(SSSDBG_IMPORTANT_INFO,
     514             :               "Object SID [%s] has a RID that is larger than the "
     515             :               "ldap_idmap_range_size. See the \"ID MAPPING\" section of "
     516             :               "sssd-ad(5) for an explanation of how to resolve this issue.\n",
     517             :               sid_str);
     518             :         /* Fall through intentionally */
     519             :     default:
     520           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     521             :               "Could not convert objectSID [%s] to a UNIX ID\n",
     522             :                sid_str);
     523           0 :         ret = EIO;
     524           0 :         goto done;
     525             :     }
     526             : 
     527           0 :     ret = EOK;
     528             : 
     529             : done:
     530           0 :     talloc_free(dom_sid_str);
     531           0 :     return ret;
     532             : }
     533             : 
     534          19 : bool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx,
     535             :                                                const char *dom_name,
     536             :                                                const char *dom_sid)
     537             : {
     538             :     enum idmap_error_code err;
     539             :     bool has_algorithmic_mapping;
     540             :     char *new_dom_sid;
     541             :     int ret;
     542          19 :     TALLOC_CTX *tmp_ctx = NULL;
     543             : 
     544          19 :     if (dp_opt_get_bool(ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)
     545           0 :         && dp_target_enabled(ctx->id_ctx->be->provider, "ldap", DPT_ID)) {
     546           0 :         return true;
     547             :     }
     548             : 
     549          19 :     err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
     550             :                                                    &has_algorithmic_mapping);
     551          19 :     switch (err){
     552             :     case IDMAP_SUCCESS:
     553           0 :         return has_algorithmic_mapping;
     554             :     case IDMAP_SID_INVALID: /* FALLTHROUGH */
     555             :     case IDMAP_SID_UNKNOWN: /* FALLTHROUGH */
     556             :     case IDMAP_NO_DOMAIN:   /* FALLTHROUGH */
     557             :         /* continue with idmap_domain_by_name */
     558          19 :         break;
     559             :     default:
     560           0 :         return false;
     561             :     }
     562             : 
     563          19 :     err = sss_idmap_domain_by_name_has_algorithmic_mapping(ctx->map,
     564             :                                                   dom_name,
     565             :                                                   &has_algorithmic_mapping);
     566          19 :     if (err == IDMAP_SUCCESS) {
     567          19 :         return has_algorithmic_mapping;
     568           0 :     } else if (err != IDMAP_NAME_UNKNOWN && err != IDMAP_NO_DOMAIN) {
     569           0 :         return false;
     570             :     }
     571             : 
     572             :     /* If there is no SID, e.g. IPA without enabled trust support, we cannot
     573             :      * have algorithmic mapping */
     574           0 :     if (dom_sid == NULL) {
     575           0 :         return false;
     576             :     }
     577             : 
     578             :     /* This is the first time we've seen this domain
     579             :      * Create a new domain for it. We'll use the dom-sid
     580             :      * as the domain name for now, since we don't have
     581             :      * any way to get the real name.
     582             :      */
     583             : 
     584           0 :     if (is_domain_sid(dom_sid)) {
     585           0 :         new_dom_sid = discard_const(dom_sid);
     586             :     } else {
     587           0 :         tmp_ctx = talloc_new(NULL);
     588           0 :         if (tmp_ctx == NULL) {
     589           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     590           0 :             return false;
     591             :         }
     592             : 
     593           0 :         ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, dom_sid,
     594             :                                                  &new_dom_sid);
     595           0 :         if (ret != EOK) {
     596           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     597             :                   "Could not parse domain SID from [%s]\n", dom_sid);
     598           0 :             talloc_free(tmp_ctx);
     599           0 :             return false;
     600             :         }
     601             :     }
     602             : 
     603           0 :     ret = ctx->find_new_domain(ctx, dom_name, new_dom_sid);
     604           0 :     talloc_free(tmp_ctx);
     605           0 :     if (ret != EOK) {
     606           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     607             :               "Could not add new domain for sid [%s]\n", dom_sid);
     608           0 :         return false;
     609             :     }
     610             : 
     611           0 :     err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
     612             :                                                    &has_algorithmic_mapping);
     613           0 :     if (err == IDMAP_SUCCESS) {
     614           0 :         return has_algorithmic_mapping;
     615             :     }
     616             : 
     617           0 :     return false;
     618             : }

Generated by: LCOV version 1.10