sdap_idmap.c revision 505e75ba28b42bb3de7a6d55de825091b70cc2b2
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher/*
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SSSD
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher Authors:
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher Copyright (C) 2012 Red Hat
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher This program is free software; you can redistribute it and/or modify
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher it under the terms of the GNU General Public License as published by
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher (at your option) any later version.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher This program is distributed in the hope that it will be useful,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher GNU General Public License for more details.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher You should have received a copy of the GNU General Public License
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher*/
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#include "util/util.h"
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#include "util/dlinklist.h"
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#include "util/murmurhash3.h"
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#include "providers/ldap/sdap_idmap.h"
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic void *
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghersdap_idmap_talloc(size_t size, void *pvt)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher{
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher return talloc_size(pvt, size);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher}
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic void
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghersdap_idmap_talloc_free(void *ptr, void *pvt)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher{
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher talloc_free(ptr);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher}
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghererrno_t
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghersdap_idmap_init(TALLOC_CTX *mem_ctx,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sdap_id_ctx *id_ctx,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sdap_idmap_ctx **_idmap_ctx)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher{
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher errno_t ret;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher TALLOC_CTX *tmp_ctx;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher enum idmap_error_code err;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher size_t i;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct ldb_result *res;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher const char *dom_name;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher const char *sid_str;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t slice_num;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sdap_idmap_ctx *idmap_ctx = NULL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sysdb_ctx *sysdb = id_ctx->be->sysdb;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher tmp_ctx = talloc_new(NULL);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (!tmp_ctx) return ENOMEM;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (!idmap_ctx) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = ENOMEM;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_ctx->id_ctx = id_ctx;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Initialize the map */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher err = sss_idmap_init(sdap_idmap_talloc, idmap_ctx,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher sdap_idmap_talloc_free,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher &idmap_ctx->map);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (err != IDMAP_SUCCESS) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not initialize the ID map: [%s]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_error_string(err)));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (err == IDMAP_OUT_OF_MEMORY) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = ENOMEM;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher } else {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Read in any existing mappings from the cache */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = sysdb_idmap_get_mappings(tmp_ctx, sysdb, &res);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (ret != EOK && ret != ENOENT) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not read ID mappings from the cache: [%s]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher strerror(ret)));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (ret == EOK && res->count > 0) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Initializing [%d] domains for ID-mapping\n", res->count));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher for (i = 0; i < res->count; i++) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SYSDB_NAME,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher NULL);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (!dom_name) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SYSDB_IDMAP_SID_ATTR,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher NULL);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (!sid_str) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SYSDB_IDMAP_SLICE_ATTR,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher -1);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (slice_num == -1) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher sid_str, slice_num);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (ret != EOK) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name, sid_str, slice_num, strerror(ret)));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EOK;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherdone:
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher talloc_free(tmp_ctx);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher return ret;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher}
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghererrno_t
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghersdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher const char *dom_name,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher const char *dom_sid,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t slice)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher{
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher errno_t ret;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sdap_idmap_slice *new_slice;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t idmap_lower;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t idmap_upper;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t rangesize;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t max_slices;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher id_t orig_slice;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher uint32_t hash_val;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sdap_idmap_slice *s;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher struct sss_idmap_range range;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher enum idmap_error_code err;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SDAP_IDMAP_LOWER);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SDAP_IDMAP_UPPER);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher SDAP_IDMAP_RANGESIZE);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Validate that the values make sense */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (rangesize <= 0
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher || idmap_upper <= idmap_lower
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher || (idmap_upper-idmap_lower) < rangesize)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Invalid settings for range selection: [%d][%d][%d]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_lower, idmap_upper, rangesize));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher return EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher max_slices = (idmap_upper - idmap_lower + 1) / rangesize;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (((idmap_upper - idmap_lower + 1) % rangesize) != 0) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Range size does not divide evenly. Uppermost range will "
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher "not be used\n"));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice = talloc_zero(idmap_ctx, struct sdap_idmap_slice);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (!new_slice) return ENOMEM;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (slice != -1) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* The slice is being set explicitly.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * This may happen at system startup when we're loading
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * previously-determined slices. In the future, we may also
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * permit configuration to select the slice for a domain
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * explicitly.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice->slice_num = slice;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher } else {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* If slice is -1, we're being asked to pick a new slice */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Hash the domain sid string */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher hash_val = murmurhash3(dom_sid, strlen(dom_sid), 0xdeadbeef);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Now get take the modulus of the hash val and the max_slices
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * to determine its optimal position in the range.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice->slice_num = hash_val % max_slices;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher orig_slice = new_slice->slice_num;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Verify that this slice is not already in use */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher do {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DLIST_FOR_EACH(s, idmap_ctx->slices) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (s->slice_num == new_slice->slice_num) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This slice number matches one already registered
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * We'll try the next available slot
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice->slice_num++;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (new_slice->slice_num > max_slices) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* loop around to the beginning if necessary */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice->slice_num = 0;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher break;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Keep trying until s is NULL (meaning we got to the end
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * without matching) or we have run out of slices and gotten
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * back to the first one we tried.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher } while (s && new_slice->slice_num != orig_slice);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (s) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* We looped all the way through and found no empty slots */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not add domain [%s]: no free slices\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = ENOSPC;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Adding domain [%s] as slice [%d]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name, new_slice->slice_num));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DLIST_ADD_END(idmap_ctx->slices, new_slice, struct sdap_idmap_slice *);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Not adding a destructor to remove from this list, because it
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * should never be possible. Removal from this list can only
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher * destabilize the system.
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Create a range object to add to the mapping */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher range.min = (rangesize * new_slice->slice_num) + idmap_lower;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher range.max = range.min + rangesize;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (range.max > idmap_upper) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("BUG: Range maximum exceeds the global maximum: %d > %d\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher range.max, idmap_upper));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EINVAL;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Add this domain to the map */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher err = sss_idmap_add_domain(idmap_ctx->map, dom_name, dom_sid, &range);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (err != IDMAP_SUCCESS) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not add domain [%s] to the map: [%d]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name, err));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = EIO;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher goto done;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Add this domain to the SYSDB cache so it will survive reboot */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->sysdb,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name, dom_sid,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher new_slice->slice_num);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherdone:
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (ret != EOK) {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher talloc_free(new_slice);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher }
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher return ret;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher}