sdap_idmap.c revision b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher Copyright (C) 2012 Red Hat
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 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 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 Gallaghersdap_idmap_talloc_free(void *ptr, void *pvt)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bosesdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MIN_ID);
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_min_id must be greater than 0.\n"));
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MAX_ID);
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose DEBUG(SSSDBG_CONF_SETTINGS, ("ldap_min_id must be greater than 0.\n"));
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose DEBUG(SSSDBG_CONF_SETTINGS, ("Both ldap_min_id and ldap_max_id " \
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose "either must be 0 (not set) " \
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose "or positive integers.\n"));
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose /* ldap_min_id and ldap_max_id not set, using min_id and max_id */
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose err = sss_idmap_add_domain_ex(idmap_ctx->map, id_ctx->be->domain->name,
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose ("Could not add domain [%s] to the map: [%d]\n",
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Boseerrno_t sdap_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx,
df0596ec12bc5091608371e2977f3111241e8cafSimo Sorce struct sysdb_ctx *sysdb = id_ctx->be->domain->sysdb;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Bose idmap_ctx->find_new_domain = sdap_idmap_find_new_domain;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Validate that the values make sense */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ("Invalid settings for range selection: [%d][%d][%d]\n",
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek if (((idmap_upper - idmap_lower) % rangesize) != 0) {
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ("Range size does not divide evenly. Uppermost range will "
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek "not be used\n"));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Initialize the map */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher err = sss_idmap_init(sdap_idmap_talloc, idmap_ctx,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not initialize the ID map: [%s]\n",
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* This should never happen */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, ("sss_idmap_ctx corrupted\n"));
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose /* Setup range for externally managed IDs, i.e. IDs are read from the
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose * ldap_user_uid_number and ldap_group_gid_number attributes. */
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose ret = sdap_idmap_add_configured_external_range(idmap_ctx);
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose ("sdap_idmap_add_configured_external_range failed.\n"));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Read in any existing mappings from the cache */
9a7b6d3248c5aac460e164f2246b26131cfbc055Simo Sorce ret = sysdb_idmap_get_mappings(tmp_ctx, sysdb, id_ctx->be->domain, &res);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not read ID mappings from the cache: [%s]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Initializing [%d] domains for ID-mapping\n", res->count));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher dom_name, sid_str, slice_num, strerror(ret)));
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher /* This is the first time we're setting up id-mapping
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher * Store the default domain as slice 0
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher /* If it's not explicitly specified, use the SSSD domain name */
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher dom_name = idmap_ctx->id_ctx->be->domain->name;
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher /* Set the default domain as slice 0 */
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher ("Could not add domain [%s][%s][%u] to ID map: [%s]\n",
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher /* In autorid compatibility mode, we MUST have a slice 0 */
5dedd73d90f0c1f23299f0c613f384ef902c3653Stephen Gallagher ("WARNING: Autorid compatibility mode selected, "
5dedd73d90f0c1f23299f0c613f384ef902c3653Stephen Gallagher "but %s is not set. UID/GID values may differ "
5dedd73d90f0c1f23299f0c613f384ef902c3653Stephen Gallagher "between clients.\n",
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name));
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher /* Otherwise, we'll just fall back to hash values as they are seen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallaghersdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ("Failed to get upper bound of available ID range.\n"));
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ("Failed to calculate range for domain [%s]: [%d]\n", dom_name,
5aad10b49e193ee14a86e1277146a223005a2d6bJakub Hrozek ("Adding domain [%s] as slice [%llu]\n", dom_sid, slice));
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* This should never happen */
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher ("BUG: Range maximum exceeds the global maximum: %d > %d\n",
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 ("Could not add domain [%s] to the map: [%d]\n",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher /* Add this domain to the SYSDB cache so it will survive reboot */
df0596ec12bc5091608371e2977f3111241e8cafSimo Sorce ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain->sysdb,
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallaghersdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx,
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher const char *p;
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher || strncmp(object_sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher } while(c < 3);
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher /* If we made it here, we are now one character past
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher * the last hyphen in the object-sid.
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher * Copy the dom-sid substring.
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher *dom_sid_str = talloc_strndup(mem_ctx, object_sid,
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallaghersdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx,
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher /* Convert the SID into a UNIX ID */
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher err = sss_idmap_sid_to_unix(idmap_ctx->map,
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher /* This is the first time we've seen this domain
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher * Create a new domain for it. We'll use the dom-sid
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher * as the domain name for now, since we don't have
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher * any way to get the real name.
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher ret = sdap_idmap_get_dom_sid_from_object(NULL, sid_str,
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher ("Could not parse domain SID from [%s]\n", sid_str));
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Bose ret = idmap_ctx->find_new_domain(idmap_ctx, dom_sid_str, dom_sid_str);
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher ("Could not add new domain for sid [%s]\n", sid_str));
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher /* Now try converting to a UNIX ID again */
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher err = sss_idmap_sid_to_unix(idmap_ctx->map,
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher ("Could not convert objectSID [%s] to a UNIX ID\n",
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek ("Object SID [%s] is a built-in one.\n", sid_str));
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek /* ENOTSUP indicates built-in SID */
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek ("Could not convert objectSID [%s] to a UNIX ID\n",
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bosebool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx,
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose } else if (err != IDMAP_SID_UNKNOWN && err != IDMAP_NO_DOMAIN) {
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose return false;
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose /* This is the first time we've seen this domain
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose * Create a new domain for it. We'll use the dom-sid
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose * as the domain name for now, since we don't have
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose * any way to get the real name.
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose return false;
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, dom_sid,
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose ("Could not parse domain SID from [%s]\n", dom_sid));
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose return false;
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose ret = ctx->find_new_domain(ctx, new_dom_sid, new_dom_sid);
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose ("Could not add new domain for sid [%s]\n", dom_sid));
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose return false;
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose return false;