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