sdap_idmap.c revision 3d9bafcbb5c0fbf23351004ded4dea6aa13127fc
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster/*
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SSSD
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster Authors:
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster Stephen Gallagher <sgallagh@redhat.com>
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster Copyright (C) 2012 Red Hat
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster This program is free software; you can redistribute it and/or modify
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster it under the terms of the GNU General Public License as published by
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster the Free Software Foundation; either version 3 of the License, or
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster (at your option) any later version.
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster This program is distributed in the hope that it will be useful,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster but WITHOUT ANY WARRANTY; without even the implied warranty of
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster GNU General Public License for more details.
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster You should have received a copy of the GNU General Public License
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster along with this program. If not, see <http://www.gnu.org/licenses/>.
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster*/
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster#include "util/util.h"
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster#include "util/dlinklist.h"
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster#include "util/murmurhash3.h"
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster#include "providers/ldap/sdap_idmap.h"
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster#include "util/util_sss_idmap.h"
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fosterstatic errno_t
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fostersdap_idmap_get_configured_external_range(struct sdap_idmap_ctx *idmap_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sss_idmap_range *range)
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster{
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster int int_id;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sdap_id_ctx *id_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster uint32_t min;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster uint32_t max;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (idmap_ctx == NULL) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_ctx = idmap_ctx->id_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MIN_ID);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (int_id < 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_min_id must be greater than 0.\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster min = int_id;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MAX_ID);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (int_id < 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_max_id must be greater than 0.\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster max = int_id;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if ((min == 0 && max != 0) || (min != 0 && max == 0)) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CONF_SETTINGS, ("Both ldap_min_id and ldap_max_id " \
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster "either must be 0 (not set) " \
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster "or positive integers.\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (min == 0 && max == 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* ldap_min_id and ldap_max_id not set, using min_id and max_id */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster min = id_ctx->be->domain->id_min;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster max = id_ctx->be->domain->id_max;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (max == 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster max = UINT32_MAX;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster range->min = min;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster range->max =max;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EOK;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster}
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fosterstatic errno_t
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fostersdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster{
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster int ret;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sss_idmap_range range;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sdap_id_ctx *id_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster enum idmap_error_code err;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (ret != EOK) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_OP_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("sdap_idmap_get_configured_external_range failed.\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return ret;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_ctx = idmap_ctx->id_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err = sss_idmap_add_domain_ex(idmap_ctx->map, id_ctx->be->domain->name,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_ctx->be->domain->domain_id, &range,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster NULL, 0, true);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (err != IDMAP_SUCCESS) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CRIT_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Could not add domain [%s] to the map: [%d]\n",
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_ctx->be->domain->name, err));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EIO;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EOK;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster}
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fostererrno_t sdap_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster const char *dom_name,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster const char *dom_sid_str)
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster{
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster int ret;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = sdap_idmap_add_domain(idmap_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster dom_name, dom_sid_str,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster -1);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (ret != EOK) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_MINOR_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Could not add new domain [%s]\n", dom_name));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return ret;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EOK;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster}
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fostererrno_t
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Fostersdap_idmap_init(TALLOC_CTX *mem_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sdap_id_ctx *id_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sdap_idmap_ctx **_idmap_ctx)
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster{
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster errno_t ret;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster TALLOC_CTX *tmp_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster enum idmap_error_code err;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster size_t i;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct ldb_result *res;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster const char *dom_name;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster const char *sid_str;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_t slice_num;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_t idmap_lower;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_t idmap_upper;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster id_t rangesize;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster bool autorid_mode;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sdap_idmap_ctx *idmap_ctx = NULL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster struct sysdb_ctx *sysdb = id_ctx->be->domain->sysdb;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster tmp_ctx = talloc_new(NULL);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (!tmp_ctx) return ENOMEM;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (!idmap_ctx) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = ENOMEM;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster goto done;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_ctx->id_ctx = id_ctx;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_ctx->find_new_domain = sdap_idmap_find_new_domain;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SDAP_IDMAP_LOWER);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SDAP_IDMAP_UPPER);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SDAP_IDMAP_RANGESIZE);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SDAP_IDMAP_AUTORID_COMPAT);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* Validate that the values make sense */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (rangesize <= 0
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster || idmap_upper <= idmap_lower
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster || (idmap_upper-idmap_lower) < rangesize)
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_FATAL_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Invalid settings for range selection: "
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n",
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_lower, idmap_upper, rangesize));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster goto done;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (((idmap_upper - idmap_lower) % rangesize) != 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CONF_SETTINGS,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Range size does not divide evenly. Uppermost range will "
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster "not be used\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* Initialize the map */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster sss_idmap_talloc_free,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster &idmap_ctx->map);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (err != IDMAP_SUCCESS) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CRIT_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Could not initialize the ID map: [%s]\n",
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster idmap_error_string(err)));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (err == IDMAP_OUT_OF_MEMORY) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = ENOMEM;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster } else {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = EINVAL;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster goto done;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (err != IDMAP_SUCCESS) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* This should never happen */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CRIT_FAILURE, ("sss_idmap_ctx corrupted\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster return EIO;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* Setup range for externally managed IDs, i.e. IDs are read from the
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster * ldap_user_uid_number and ldap_group_gid_number attributes. */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = sdap_idmap_add_configured_external_range(idmap_ctx);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (ret != EOK) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_OP_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("sdap_idmap_add_configured_external_range failed.\n"));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster goto done;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster /* Read in any existing mappings from the cache */
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ret = sysdb_idmap_get_mappings(tmp_ctx, sysdb, id_ctx->be->domain, &res);
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (ret != EOK && ret != ENOENT) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_FATAL_FAILURE,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Could not read ID mappings from the cache: [%s]\n",
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster strerror(ret)));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster goto done;
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster }
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster if (ret == EOK && res->count > 0) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster DEBUG(SSSDBG_CONF_SETTINGS,
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster ("Initializing [%d] domains for ID-mapping\n", res->count));
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster for (i = 0; i < res->count; i++) {
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1cAllan Foster SYSDB_NAME,
NULL);
if (!dom_name) {
/* This should never happen */
ret = EINVAL;
goto done;
}
sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
SYSDB_IDMAP_SID_ATTR,
NULL);
if (!sid_str) {
/* This should never happen */
ret = EINVAL;
goto done;
}
slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
SYSDB_IDMAP_SLICE_ATTR,
-1);
if (slice_num == -1) {
/* This should never happen */
ret = EINVAL;
goto done;
}
ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
sid_str, slice_num);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Could not add domain [%s][%s][%"SPRIid"] "
"to ID map: [%s]\n",
dom_name, sid_str, slice_num, strerror(ret)));
goto done;
}
}
} else {
/* This is the first time we're setting up id-mapping
* Store the default domain as slice 0
*/
dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
if (!dom_name) {
/* If it's not explicitly specified, use the SSSD domain name */
dom_name = idmap_ctx->id_ctx->be->domain->name;
ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
SDAP_IDMAP_DEFAULT_DOMAIN,
dom_name);
if (ret != EOK) goto done;
}
sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
if (sid_str) {
/* Set the default domain as slice 0 */
ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
sid_str, 0);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
dom_name, sid_str, 0, strerror(ret)));
goto done;
}
} else {
if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
/* In autorid compatibility mode, we MUST have a slice 0 */
DEBUG(SSSDBG_CRIT_FAILURE,
("WARNING: Autorid compatibility mode selected, "
"but %s is not set. UID/GID values may differ "
"between clients.\n",
idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name));
}
/* Otherwise, we'll just fall back to hash values as they are seen */
}
}
*_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
ret = EOK;
done:
talloc_free(tmp_ctx);
return ret;
}
errno_t
sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
const char *dom_name,
const char *dom_sid,
id_t slice)
{
errno_t ret;
struct sss_idmap_range range;
enum idmap_error_code err;
id_t idmap_upper;
ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper);
if (ret != IDMAP_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Failed to get upper bound of available ID range.\n"));
ret = EIO;
goto done;
}
ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range);
if (ret != IDMAP_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Failed to calculate range for domain [%s]: [%d]\n", dom_name,
ret));
ret = EIO;
goto done;
}
DEBUG(SSSDBG_TRACE_LIBS,
("Adding domain [%s] as slice [%"SPRIid"]\n", dom_sid, slice));
if (range.max > idmap_upper) {
/* This should never happen */
DEBUG(SSSDBG_CRIT_FAILURE,
("BUG: Range maximum exceeds the global maximum: "
"%d > %"SPRIid"\n", range.max, idmap_upper));
ret = EINVAL;
goto done;
}
/* Add this domain to the map */
err = sss_idmap_add_domain(idmap_ctx->map, dom_name, dom_sid, &range);
if (err != IDMAP_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Could not add domain [%s] to the map: [%d]\n",
dom_name, err));
ret = EIO;
goto done;
}
/* Add this domain to the SYSDB cache so it will survive reboot */
ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain->sysdb,
idmap_ctx->id_ctx->be->domain,
dom_name, dom_sid,
slice);
done:
return ret;
}
errno_t
sdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx,
const char *object_sid,
char **dom_sid_str)
{
const char *p;
long long a;
size_t c;
char *endptr;
if (object_sid == NULL
|| strncmp(object_sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
return EINVAL;
}
p = object_sid + DOM_SID_PREFIX_LEN;
c = 0;
do {
errno = 0;
a = strtoull(p, &endptr, 10);
if (errno != 0 || a > UINT32_MAX) {
return EINVAL;
}
if (*endptr == '-') {
p = endptr + 1;
} else {
return EINVAL;
}
c++;
} while(c < 3);
/* If we made it here, we are now one character past
* the last hyphen in the object-sid.
* Copy the dom-sid substring.
*/
*dom_sid_str = talloc_strndup(mem_ctx, object_sid,
(endptr-object_sid));
if (!*dom_sid_str) return ENOMEM;
return EOK;
}
errno_t
sdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx,
const char *sid_str,
id_t *id)
{
errno_t ret;
enum idmap_error_code err;
char *dom_sid_str = NULL;
/* Convert the SID into a UNIX ID */
err = sss_idmap_sid_to_unix(idmap_ctx->map,
sid_str,
(uint32_t *)id);
switch (err) {
case IDMAP_SUCCESS:
break;
case IDMAP_NO_DOMAIN:
/* This is the first time we've seen this domain
* Create a new domain for it. We'll use the dom-sid
* as the domain name for now, since we don't have
* any way to get the real name.
*/
ret = sdap_idmap_get_dom_sid_from_object(NULL, sid_str,
&dom_sid_str);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not parse domain SID from [%s]\n", sid_str));
goto done;
}
ret = idmap_ctx->find_new_domain(idmap_ctx, dom_sid_str, dom_sid_str);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not add new domain for sid [%s]\n", sid_str));
goto done;
}
/* Now try converting to a UNIX ID again */
err = sss_idmap_sid_to_unix(idmap_ctx->map,
sid_str,
(uint32_t *)id);
if (err != IDMAP_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not convert objectSID [%s] to a UNIX ID\n",
sid_str));
ret = EIO;
goto done;
}
break;
case IDMAP_BUILTIN_SID:
DEBUG(SSSDBG_TRACE_FUNC,
("Object SID [%s] is a built-in one.\n", sid_str));
/* ENOTSUP indicates built-in SID */
ret = ENOTSUP;
goto done;
break;
default:
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not convert objectSID [%s] to a UNIX ID\n",
sid_str));
ret = EIO;
goto done;
}
ret = EOK;
done:
talloc_free(dom_sid_str);
return ret;
}
bool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx,
const char *dom_sid)
{
enum idmap_error_code err;
bool has_algorithmic_mapping;
char *new_dom_sid;
int ret;
TALLOC_CTX *tmp_ctx = NULL;
err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
&has_algorithmic_mapping);
if (err == IDMAP_SUCCESS) {
return has_algorithmic_mapping;
} else if (err != IDMAP_SID_UNKNOWN && err != IDMAP_NO_DOMAIN) {
return false;
}
/* This is the first time we've seen this domain
* Create a new domain for it. We'll use the dom-sid
* as the domain name for now, since we don't have
* any way to get the real name.
*/
if (is_domain_sid(dom_sid)) {
new_dom_sid = discard_const(dom_sid);
} else {
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
return false;
}
ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, dom_sid,
&new_dom_sid);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not parse domain SID from [%s]\n", dom_sid));
talloc_free(tmp_ctx);
return false;
}
}
ret = ctx->find_new_domain(ctx, new_dom_sid, new_dom_sid);
talloc_free(tmp_ctx);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Could not add new domain for sid [%s]\n", dom_sid));
return false;
}
err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
&has_algorithmic_mapping);
if (err == IDMAP_SUCCESS) {
return has_algorithmic_mapping;
}
return false;
}