ad_subdomains.c revision d19e343d3fcb0780300d69ba5813ca4762ca9b98
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen AD Subdomains Module
1036d2db2b718bdc5b10f0773dd01d62638e9ba9Timo Sirainen Sumit Bose <sbose@redhat.com>
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen Copyright (C) 2013 Red Hat
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen This program is free software; you can redistribute it and/or modify
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen it under the terms of the GNU General Public License as published by
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen the Free Software Foundation; either version 3 of the License, or
d758298b3b6f1ebcd494392c0f20b0e119a9e85eTimo Sirainen (at your option) any later version.
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen This program is distributed in the hope that it will be useful,
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen GNU General Public License for more details.
a40649829bce4c8de6210a2cb4a4b4cf5bb40da8Timo Sirainen You should have received a copy of the GNU General Public License
6eb191b58bc8553a516bd1c9b0eccaa696d0f41fTimo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen/* Attributes of AD trusted domains */
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen#define MASTER_DOMAIN_SID_FILTER "objectclass=domain"
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen/* trustType=2 denotes uplevel (NT5 and later) trusted domains. See
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680342%28v=vs.85%29.aspx
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen * for example.
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen * The absence of msDS-TrustForestTrustInfo attribute denotes a domain from
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen * the same forest. See http://msdn.microsoft.com/en-us/library/cc223786.aspx
e48f289d2e5b2546a2c5dcc90f7ab624cc58cca2Stephan Bosch * for more information.
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen#define SLAVE_DOMAIN_FILTER "(&(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*)))"
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen/* do not refresh more often than every 5 seconds for now */
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainenads_store_sdap_subdom(struct ad_subdomains_ctx *ctx,
e95bc848767afa2e52cb988a6d3f5e5cc5933885Timo Sirainen return sdap_domain_subdom_add(ctx->sdap_id_ctx, ctx->sdom, parent);
e95bc848767afa2e52cb988a6d3f5e5cc5933885Timo Sirainen ret = sysdb_attrs_get_uint32_t(subdom_attrs, AD_AT_TRUST_TYPE,
1036d2db2b718bdc5b10f0773dd01d62638e9ba9Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_uint32_t failed.\n"));
1036d2db2b718bdc5b10f0773dd01d62638e9ba9Timo Sirainen ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_TRUST_PARTNER, &name);
1036d2db2b718bdc5b10f0773dd01d62638e9ba9Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("failed to get subdomain name\n"));
28a57cc7b6f29cc55a4a586c80902b21daf5d55bTimo Sirainen ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_FLATNAME, &flat);
28a57cc7b6f29cc55a4a586c80902b21daf5d55bTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("failed to get flat name of subdomain %s\n",
28a57cc7b6f29cc55a4a586c80902b21daf5d55bTimo Sirainen ret = sysdb_attrs_get_el(subdom_attrs, AD_AT_SID, &el);
546d3609e0811a147269ee9979eb90649445f5acTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sdap_attrs_get_el failed.\n"));
546d3609e0811a147269ee9979eb90649445f5acTimo Sirainen err = sss_idmap_bin_sid_to_sid(ctx->idmap_ctx,
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen ("Could not convert SID: [%s].\n", idmap_error_string(err)));
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen mpg = sdap_idmap_domain_has_algorithmic_mapping(
28a57cc7b6f29cc55a4a586c80902b21daf5d55bTimo Sirainen /* AD subdomains are currently all mpg and do not enumerate */
546d3609e0811a147269ee9979eb90649445f5acTimo Sirainen ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str,
3b94ff5951db4d4eddb7a80ed4e3f61207202635Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sysdb_subdomain_store failed.\n"));
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainenstatic errno_t ad_subdomains_refresh(struct ad_subdomains_ctx *ctx,
e130dc7c712a10215b1e6be56403bbb934826251Timo Sirainen /* check existing subdomains */
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen for (c = 0; c < count; c++) {
93794594bc682b12353d2d0db08d91ae3e7c56c6Timo Sirainen ret = sysdb_attrs_get_string(reply[c], AD_AT_TRUST_PARTNER, &value);
93794594bc682b12353d2d0db08d91ae3e7c56c6Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen /* ok this subdomain does not exist anymore, let's clean up */
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen ret = sysdb_subdomain_delete(dom->sysdb, dom->name);
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen sdom = sdap_domain_get(ctx->sdap_id_ctx->opts, dom);
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("BUG: Domain does not exist?\n"));
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen /* Remove the subdomain from the list of LDAP domains */
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen sdap_domain_remove(ctx->sdap_id_ctx->opts, dom);
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen /* terminate all requests for this subdomain so we can free it */
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen be_terminate_domain_requests(ctx->be_ctx, dom->name);
3fc62f5a9b1646f0e385f0708c652fbd8b944ba9Timo Sirainen /* ok let's try to update it */
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen /* Nothing we can do about the error. Let's at least try
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen * to reuse the existing domains
e130dc7c712a10215b1e6be56403bbb934826251Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to parse subdom data, "
e130dc7c712a10215b1e6be56403bbb934826251Timo Sirainen "will try to use cached subdomain\n"));
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen /* all domains were already accounted for and have been updated */
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen /* if we get here it means we have changes to the subdomains list */
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen for (c = 0; c < count; c++) {
3b94ff5951db4d4eddb7a80ed4e3f61207202635Timo Sirainen /* Nothing we can do about the error. Let's at least try
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainen * to reuse the existing domains.
a40649829bce4c8de6210a2cb4a4b4cf5bb40da8Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to parse subdom data, "
a40649829bce4c8de6210a2cb4a4b4cf5bb40da8Timo Sirainen "will try to use cached subdomain\n"));
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainenstatic void ad_subdomains_get_conn_done(struct tevent_req *req);
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainenstatic void ad_subdomains_master_dom_done(struct tevent_req *req);
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainenstatic errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx);
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainenstatic void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx,
6eb191b58bc8553a516bd1c9b0eccaa696d0f41fTimo Sirainen req_ctx = talloc(be_req, struct ad_subdomains_req_ctx);
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed.\n"));
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret);
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_connect_send failed: %d(%s).\n",
3b94ff5951db4d4eddb7a80ed4e3f61207202635Timo Sirainen tevent_req_set_callback(req, ad_subdomains_get_conn_done, req_ctx);
93794594bc682b12353d2d0db08d91ae3e7c56c6Timo Sirainen be_req_terminate(be_req, dp_error, ret, NULL);
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainenstatic void ad_subdomains_get_conn_done(struct tevent_req *req)
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
3b94ff5951db4d4eddb7a80ed4e3f61207202635Timo Sirainen ret = sdap_id_op_connect_recv(req, &dp_error);
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen ("No AD server is available, cannot get the "
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen "subdomain list while offline\n"));
a40649829bce4c8de6210a2cb4a4b4cf5bb40da8Timo Sirainen ("Failed to connect to AD server: [%d](%s)\n",
a40649829bce4c8de6210a2cb4a4b4cf5bb40da8Timo Sirainen req = ad_master_domain_send(ctx, ctx->sd_ctx->be_ctx->ev,
bb979386852c7689dc66c0fce03319382f66d501Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("ad_master_domain_send failed.\n"));
6eb191b58bc8553a516bd1c9b0eccaa696d0f41fTimo Sirainen tevent_req_set_callback(req, ad_subdomains_master_dom_done, ctx);
d35364f4d7d139b4150d290e14717e10f1ede4cdTimo Sirainen be_req_terminate(ctx->be_req, dp_error, ret, NULL);
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainenstatic void ad_subdomains_master_dom_done(struct tevent_req *req)
4cb2599c5cdf27362a66ac475ce295409c093c92Timo Sirainen ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
e130dc7c712a10215b1e6be56403bbb934826251Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Cannot retrieve master domain info\n"));
e130dc7c712a10215b1e6be56403bbb934826251Timo Sirainen ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain,
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Cannot save master domain info\n"));
7cd08c67fde5371f662d8c95b30c341741950420Timo Sirainen be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL);
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainenstatic void ad_subdomains_get_slave_domain_done(struct tevent_req *req);
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainenstatic errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx)
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainen const char *slave_dom_attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER,
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen base = ctx->sd_ctx->sdap_id_ctx->opts->sdom->search_bases[ctx->base_iter];
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainen req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen tevent_req_set_callback(req, ad_subdomains_get_slave_domain_done, ctx);
771178a5c5285aa596723591271c8936c4007f1bTimo Sirainenstatic void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
771178a5c5285aa596723591271c8936c4007f1bTimo Sirainen ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
771178a5c5285aa596723591271c8936c4007f1bTimo Sirainen ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
771178a5c5285aa596723591271c8936c4007f1bTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen ctx->reply = talloc_realloc(ctx, ctx->reply, struct sysdb_attrs *,
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen /* Got all the subdomains, let's process them */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ret = ad_subdomains_refresh(ctx->sd_ctx, ctx->reply_count, ctx->reply,
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Failed to refresh subdomains.\n"));
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen ret = sysdb_update_subdomains(ctx->sd_ctx->be_ctx->domain);
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n"));
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen ret = ads_store_sdap_subdom(ctx->sd_ctx, ctx->sd_ctx->be_ctx->domain);
3e859421cc59d28d4ba99f32830e3d0531334813Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("ads_store_sdap_subdom failed.\n"));
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen ret = sss_write_domain_mappings(ctx->sd_ctx->be_ctx->domain, false);
done:
void *pvt)
const char *errstr)
if (!ctx) {
if (ctx) {
struct ad_subdomains_ctx);
if (!ctx) {
const char *ad_domain,
void **pvt_data)
int ret;
return ENOMEM;
return ENOMEM;
return EFAULT;
return EOK;