ad_subdomains.c revision a82baf596bac1fdac6addca6419d8992111a8aa2
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski AD Subdomains Module
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Sumit Bose <sbose@redhat.com>
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Copyright (C) 2013 Red Hat
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is free software; you can redistribute it and/or modify
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski it under the terms of the GNU General Public License as published by
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder the Free Software Foundation; either version 3 of the License, or
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder (at your option) any later version.
a7a43d265fef55ddfd7c4412cd96c621ef9738ffChristian Maeder This program is distributed in the hope that it will be useful,
a7a43d265fef55ddfd7c4412cd96c621ef9738ffChristian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
a7a43d265fef55ddfd7c4412cd96c621ef9738ffChristian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a7a43d265fef55ddfd7c4412cd96c621ef9738ffChristian Maeder GNU General Public License for more details.
ae35311385999d91f812155fe99439724d54063bChristian Maeder You should have received a copy of the GNU General Public License
46b207daf66b64930a59f3615c8b127aac0b8e43Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
697e63e30aa3c309a1ef1f9357745111f8dfc5a9Christian Maeder/* Attributes of AD trusted domains */
38824a7dba4f7d82532afec67e0b594a5af5d76bChristian Maeder/* trustType=2 denotes uplevel (NT5 and later) trusted domains. See
520c5bce318eff52d9315f7c4491c3381a0c4336Christian Maeder * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680342%28v=vs.85%29.aspx
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * for example.
eaa88a5cefdc814e61039c5dcc1bffc324a2f93eChristian Maeder * The absence of msDS-TrustForestTrustInfo attribute denotes a domain from
46b1095ba983ce859e17c2a12f48b50583b7150cChristian Maeder * the same forest. See http://msdn.microsoft.com/en-us/library/cc223786.aspx
411392046c2ba1752cde81eaa92a95a2c28b672dChristian Maeder * for more information.
f527d5da7cd679c1a9b50a4906a0c12d395a6087Christian Maeder#define SLAVE_DOMAIN_FILTER_BASE "(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*))"
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder#define SLAVE_DOMAIN_FILTER "(&"SLAVE_DOMAIN_FILTER_BASE")"
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder#define FOREST_ROOT_FILTER_FMT "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))"
eaa88a5cefdc814e61039c5dcc1bffc324a2f93eChristian Maeder/* do not refresh more often than every 5 seconds for now */
eaa88a5cefdc814e61039c5dcc1bffc324a2f93eChristian Maederstatic errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx,
024703c9d1326c23e307c0b0d453ed3358e87fe4cmaeder const char *str;
eaa88a5cefdc814e61039c5dcc1bffc324a2f93eChristian Maeder str = dp_opt_get_cstring(ad_id_ctx->ad_options->basic, AD_ENABLED_DOMAINS);
46b1095ba983ce859e17c2a12f48b50583b7150cChristian Maeder ret = split_on_separator(tmp_ctx, str, ',', true, true,
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz option_name = ad_id_ctx->ad_options->basic[AD_ENABLED_DOMAINS].opt_name;
38824a7dba4f7d82532afec67e0b594a5af5d76bChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse option [%s], [%i] [%s]!\n",
411588cc915b27cef4e7e66fb23e67514b3a0c92Christian Maeder for (int i = 0; i < count; i++) {
21dbca247d5964daf2c5abd2de2ac1101e3e1ef4Christian Maeder is_ad_in_domains += strcmp(ad_domain, domains[i]) == 0 ? true : false;
961978c71545e0177683279f8b63358b3e3804b8Christian Maeder domains = talloc_realloc(tmp_ctx, domains, const char*, count + 2);
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa domains[count] = talloc_strdup(domains, ad_domain);
63da71bfb4226f504944b293fb77177ebcaea7d4Ewaryst Schulz domains = talloc_realloc(tmp_ctx, domains, const char*, count + 1);
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz *_ad_enabled_domains = talloc_steal(mem_ctx, domains);
4d54e7814b18ce142359c92a5868e6dcff9219b5Christian Maeder realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM);
ce900a84ed9d9882c64fccbd6300f6b0d67efa82Christian Maeder hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME);
48a98aa04f4c2c1f5f8f79c007e1ff95e699b31aFlorian Mossakowski keytab = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KEYTAB);
4067eba4f5605d9569d78085deb1a27f08ac34e2Christian Maeder if (realm == NULL || hostname == NULL || ad_domain == NULL) {
aad8b6ac810a08fca14ce0fbbf324fcce5305ad6Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm or hostname.\n");
aad8b6ac810a08fca14ce0fbbf324fcce5305ad6Christian Maeder ad_options = ad_create_2way_trust_options(id_ctx, realm, ad_domain,
4067eba4f5605d9569d78085deb1a27f08ac34e2Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->name);
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz service_name = talloc_asprintf(ad_options, "sd_%s", subdom->name);
074f8feaf71e0b71a95145e7439746f8eb8e2a7cChristian Maeder ret = ad_failover_init(ad_options, be_ctx, NULL, NULL, realm,
f6b2c6c33c635279973b8f378470da7dbb8ecee8Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n");
e6ac593966607b1da5b619e0f9492d37820eed74Christian Maeder ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder /* use AD plugin */
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
a7b34c1a61dabe150288424d90389d5988bf9d7aChristian Maeder DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
c1d06b3018b34ede2b3fb6c7fe2ad28cd5ce5b68Christian Maeder be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
5382091fd2a705e6f026026e8a6adcd3607bdb9fChristian Maeder ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
074f8feaf71e0b71a95145e7439746f8eb8e2a7cChristian Maeder DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n");
38824a7dba4f7d82532afec67e0b594a5af5d76bChristian Maeder sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
154be5bfac61cf5b61fd1571e7bfc2572c4b546aMihai Codescu sdap_inherit_options(subdom->parent->sd_inherit,
7fe976d9f9c4af1aa7636c568d9919859523de0aChristian Maeder /* Set up the ID mapping object */
38824a7dba4f7d82532afec67e0b594a5af5d76bChristian Maederstatic errno_t ad_subdom_enumerates(struct sss_domain_info *parent,
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist const char *name;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name);
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
ec351e60425e2f99448cb44e933d3828f8025dddChristian Maeder *_enumerates = subdomain_enumerates(parent, name);
411588cc915b27cef4e7e66fb23e67514b3a0c92Christian Maederad_subdom_store(struct sdap_idmap_ctx *idmap_ctx,
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa ret = sysdb_attrs_get_uint32_t(subdom_attrs, AD_AT_TRUST_TYPE,
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_uint32_t failed.\n");
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_TRUST_PARTNER, &name);
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze DEBUG(SSSDBG_OP_FAILURE, "failed to get subdomain name\n");
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze realm = get_uppercase_realm(tmp_ctx, name);
4067eba4f5605d9569d78085deb1a27f08ac34e2Christian Maeder ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_FLATNAME, &flat);
4067eba4f5605d9569d78085deb1a27f08ac34e2Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "failed to get flat name of subdomain %s\n",
57075b3ac70f37e55f72aa86aa1b70c6ccca8207Christian Maeder ret = sysdb_attrs_get_el(subdom_attrs, AD_AT_SID, &el);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "sdap_attrs_get_el failed.\n");
d34c6711bc746459074986c06f7c28b083b4be2fChristian Maeder err = sss_idmap_bin_sid_to_sid(idmap_ctx->map, el->values[0].data,
48a98aa04f4c2c1f5f8f79c007e1ff95e699b31aFlorian Mossakowski "Could not convert SID: [%s].\n", idmap_error_string(err));
a7b34c1a61dabe150288424d90389d5988bf9d7aChristian Maeder mpg = sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, name, sid_str);
bb9642ff292545658dc11251b83a7b7af3c1fccbChristian Maeder ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str,
6c08e47c4275556c18f4f89521bf21fe94c28dd5Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n");
eaa88a5cefdc814e61039c5dcc1bffc324a2f93eChristian Maeder sss_idmap_free_sid(idmap_ctx->map, sid_str);
4067eba4f5605d9569d78085deb1a27f08ac34e2Christian Maederstatic errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
1937dccb04b363364f7a7de17fdaae1d70583af9Christian Maeder memset(handled, 0, sizeof(bool) * num_subdomains);
938677803842b384a91fef21f58f86b8e3188b43Ewaryst Schulz ret = sysdb_attrs_get_string(subdomains[0], AD_AT_TRUST_PARTNER,
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
3143271856dbf456bd7acc1c07193173f886d986Christian Maeder /* check existing subdomains */
c30231257d9116b514dce02703a515fe21cd427dTill Mossakowski for (dom = get_next_domain(domain, SSS_GND_DESCEND);
3143271856dbf456bd7acc1c07193173f886d986Christian Maeder dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder /* If we are handling root domain, skip all the other domains. We don't
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder * want to accidentally remove non-root domains
3143271856dbf456bd7acc1c07193173f886d986Christian Maeder if (root_name && strcmp(root_name, dom->name) != 0) {
1937dccb04b363364f7a7de17fdaae1d70583af9Christian Maeder for (c = 0; c < num_subdomains; c++) {
35cb254f1f46a6f33b5c24111a37fbab49d79cfeChristian Maeder ret = sysdb_attrs_get_string(subdomains[c], AD_AT_TRUST_PARTNER,
180ab8c3df8cb0c88f0e881bca93354df6b5d560Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
ef2affdc0cdf3acd5c051597c04ab9b08a346a7dChristian Maeder /* ok this subdomain does not exist anymore, let's clean up */
63719301448519453f66383f4e583d9fd5b89ecbChristian Maeder ret = sysdb_subdomain_delete(dom->sysdb, dom->name);
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Domain does not exist?\n");
50a3afe91cef447a03d579976c179dc266290c93Christian Maeder /* Remove the subdomain from the list of LDAP domains */
goto done;
if (ret) {
handled[c] = true;
if (num_subdomains == h) {
*_changes = false;
goto done;
*_changes = true;
for (c = 0; c < num_subdomains; c++) {
if (handled[c]) {
goto done;
if (ret) {
done:
*_last_refreshed = 0;
return ret;
const char *sd_name;
return EOK;
return ENOMEM;
sdi = 0;
for (i = 0; i < nsd; i++) {
goto fail;
sdi++;
return EOK;
fail:
return ret;
static errno_t
int ret;
return ret;
return EOK;
const char *path;
bool canonicalize;
return ret;
return ret;
return EOK;
struct ad_get_slave_domain_state {
static struct tevent_req *
struct ad_get_slave_domain_state);
return NULL;
goto immediately;
return req;
return req;
int ret;
return ret;
return EAGAIN;
int dp_error;
NULL, false, 0,
bool has_changes;
int dp_error;
goto done;
goto done;
goto done;
&has_changes);
goto done;
if (has_changes) {
goto done;
done:
return EOK;
static struct sss_domain_info *
const char *name;
return NULL;
return root;
static struct ad_id_ctx *
return NULL;
&root_id_ctx);
return NULL;
return root_id_ctx;
struct ad_get_root_domain_state {
static struct tevent_req *
const char *forest,
const char *filter;
return NULL;
goto immediately;
goto immediately;
goto immediately;
return req;
return req;
bool has_changes;
&reply);
goto done;
if (reply_count == 0) {
goto done;
goto done;
&has_changes);
goto done;
if (has_changes) {
goto done;
goto done;
goto done;
done:
return EOK;
struct ad_subdomains_refresh_state {
static struct tevent_req *
struct ad_subdomains_refresh_state);
return NULL;
goto immediately;
return req;
return req;
int ret;
return ret;
return EAGAIN;
int dp_error;
const char *realm;
char *master_sid;
char *flat_name;
char *forest;
goto done;
goto done;
goto done;
goto done;
done:
int dp_error;
return EOK;
struct ad_subdomains_handler_state {
static struct tevent_req *
struct ad_subdomains_handler_state);
return NULL;
goto immediately;
goto immediately;
return req;
return req;
return EOK;
static struct tevent_req *
void *pvt)
static errno_t
const char *ad_domain;
return ENOMEM;
return EINVAL;
return ENOMEM;
return EOK;