sdap_idmap.c revision 949fbc93defad394648b2651b43a7bbfa5bff42b
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek Stephen Gallagher <sgallagh@redhat.com>
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek Copyright (C) 2012 Red Hat
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek This program is free software; you can redistribute it and/or modify
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek it under the terms of the GNU General Public License as published by
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek the Free Software Foundation; either version 3 of the License, or
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek (at your option) any later version.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek This program is distributed in the hope that it will be useful,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek GNU General Public License for more details.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek You should have received a copy of the GNU General Public License
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void *
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MIN_ID);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_min_id must be greater than 0.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MAX_ID);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_min_id must be greater than 0.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS, ("Both ldap_min_id and ldap_max_id " \
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "either must be 0 (not set) " \
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "or positive integers.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* ldap_min_id and ldap_max_id not set, using min_id and max_id */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err = sss_idmap_add_domain_ex(idmap_ctx->map, id_ctx->be->domain->name,
2cba1c86f48db866fc72738a32eecbbdcdf3dbdbJakub Hrozek ("Could not add domain [%s] to the map: [%d]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct sysdb_ctx *sysdb = id_ctx->be->domain->sysdb;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Validate that the values make sense */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Invalid settings for range selection: [%d][%d][%d]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (((idmap_upper - idmap_lower) % rangesize) != 0) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Range size does not divide evenly. Uppermost range will "
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "not be used\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Initialize the map */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err = sss_idmap_init(sdap_idmap_talloc, idmap_ctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not initialize the ID map: [%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This should never happen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("sss_idmap_ctx corrupted\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Setup range for externally managed IDs, i.e. IDs are read from the
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * ldap_user_uid_number and ldap_group_gid_number attributes. */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sdap_idmap_add_configured_external_range(idmap_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("sdap_idmap_add_configured_external_range failed.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Read in any existing mappings from the cache */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sysdb_idmap_get_mappings(tmp_ctx, sysdb, id_ctx->be->domain, &res);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not read ID mappings from the cache: [%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Initializing [%d] domains for ID-mapping\n", res->count));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This should never happen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This should never happen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This should never happen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This is the first time we're setting up id-mapping
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Store the default domain as slice 0
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If it's not explicitly specified, use the SSSD domain name */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dom_name = idmap_ctx->id_ctx->be->domain->name;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Set the default domain as slice 0 */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* In autorid compatibility mode, we MUST have a slice 0 */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("WARNING: Autorid compatibility mode selected, "
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "but %s is not set. UID/GID values may differ "
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "between clients.\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Otherwise, we'll just fall back to hash values as they are seen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Failed to get upper bound of available ID range.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Failed to calculate range for domain [%s]: [%d]\n", dom_name,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Adding domain [%s] as slice [%llu]\n", dom_sid, slice));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This should never happen */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("BUG: Range maximum exceeds the global maximum: %d > %d\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Add this domain to the map */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek err = sss_idmap_add_domain(idmap_ctx->map, dom_name, dom_sid, &range);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not add domain [%s] to the map: [%d]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Add this domain to the SYSDB cache so it will survive reboot */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain->sysdb,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek const char *p;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek long long a;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek || strncmp(object_sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek } while(c < 3);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If we made it here, we are now one character past
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * the last hyphen in the object-sid.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Copy the dom-sid substring.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek *dom_sid_str = talloc_strndup(mem_ctx, object_sid,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Convert the SID into a UNIX ID */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* This is the first time we've seen this domain
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Create a new domain for it. We'll use the dom-sid
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * as the domain name for now, since we don't have
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * any way to get the real name.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sdap_idmap_get_dom_sid_from_object(NULL, sid_str,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not parse domain SID from [%s]\n", sid_str));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not add new domain for sid [%s]\n", sid_str));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Now try converting to a UNIX ID again */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not convert objectSID [%s] to a UNIX ID\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Object SID [%s] is a built-in one.\n", sid_str));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* ENOTSUP indicates built-in SID */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not convert objectSID [%s] to a UNIX ID\n",