summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2015-05-25 21:59:15 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-06-14 21:44:39 +0200
commit27e89b6925334565c73c407a9ae2809358789c81 (patch)
treeefe77b132deed319d9601075ff54994bfebc5d3d
parentc3243e3212f91b69ef9990e2cb4c9339bf2f7888 (diff)
downloadsssd-27e89b6925334565c73c407a9ae2809358789c81.tar.gz
sssd-27e89b6925334565c73c407a9ae2809358789c81.tar.xz
sssd-27e89b6925334565c73c407a9ae2809358789c81.zip
IPA: Move server-mode functions to a separate module
There is already quite a few functions that are server-mode specific and there will be even more with one-way trusts. Split the server-mode specific functions into a separate module. Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r--Makefile.am1
-rw-r--r--src/providers/ipa/ipa_init.c6
-rw-r--r--src/providers/ipa/ipa_subdomains.c316
-rw-r--r--src/providers/ipa/ipa_subdomains.h12
-rw-r--r--src/providers/ipa/ipa_subdomains_server.c340
5 files changed, 358 insertions, 317 deletions
diff --git a/Makefile.am b/Makefile.am
index 4e042922d..b85290896 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2760,6 +2760,7 @@ libsss_ipa_la_SOURCES = \
src/providers/ipa/ipa_hosts.c \
src/providers/ipa/ipa_subdomains.c \
src/providers/ipa/ipa_subdomains_id.c \
+ src/providers/ipa/ipa_subdomains_server.c \
src/providers/ipa/ipa_subdomains_ext_groups.c \
src/providers/ipa/ipa_views.c \
src/providers/ipa/ipa_utils.c \
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 15ec2339d..0e16dd97c 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -722,12 +722,6 @@ int sssm_ipa_subdomains_init(struct be_ctx *bectx,
return ret;
}
- ret = ipa_ad_subdom_init(bectx, id_ctx);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "ipa_ad_subdom_init failed.\n");
- return ret;
- }
-
return EOK;
}
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 95c941542..2a898d7eb 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -106,225 +106,6 @@ struct be_ctx *ipa_get_subdomains_be_ctx(struct be_ctx *be_ctx)
}
static errno_t
-ipa_ad_ctx_new(struct be_ctx *be_ctx,
- struct ipa_id_ctx *id_ctx,
- struct sss_domain_info *subdom,
- struct ad_id_ctx **_ad_id_ctx)
-{
- struct ad_options *ad_options;
- struct ad_id_ctx *ad_id_ctx;
- const char *gc_service_name;
- struct ad_srv_plugin_ctx *srv_ctx;
- char *ad_domain;
- const char *ad_site_override;
- struct sdap_domain *sdom;
- errno_t ret;
- const char *extra_attrs;
-
- ad_options = ad_create_default_options(id_ctx, id_ctx->server_mode->realm,
- id_ctx->server_mode->hostname);
- if (ad_options == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
- talloc_free(ad_options);
- return ENOMEM;
- }
-
- ad_domain = subdom->name;
-
- ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD domain\n");
- talloc_free(ad_options);
- return ret;
- }
-
- ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM,
- id_ctx->server_mode->realm);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD realm\n");
- talloc_free(ad_options);
- return ret;
- }
-
- extra_attrs = dp_opt_get_string(id_ctx->sdap_id_ctx->opts->basic,
- SDAP_USER_EXTRA_ATTRS);
- if (extra_attrs != NULL) {
- DEBUG(SSSDBG_TRACE_ALL,
- "Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain,
- extra_attrs);
-
- ret = dp_opt_set_string(ad_options->id->basic, SDAP_USER_EXTRA_ATTRS,
- extra_attrs);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "dp_opt_get_string failed.\n");
- talloc_free(ad_options);
- return ret;
- }
-
- ret = sdap_extend_map_with_list(ad_options->id, ad_options->id,
- SDAP_USER_EXTRA_ATTRS,
- ad_options->id->user_map,
- SDAP_OPTS_USER,
- &ad_options->id->user_map,
- &ad_options->id->user_map_cnt);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n");
- talloc_free(ad_options);
- return ret;
- }
- } else {
- DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n");
- }
-
- gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->name);
- if (gc_service_name == NULL) {
- talloc_free(ad_options);
- return ENOMEM;
- }
-
- /* Set KRB5 realm to same as the one of IPA when IPA
- * is able to attach PAC. For testing, use hardcoded. */
- ret = ad_failover_init(ad_options, be_ctx, NULL, NULL,
- id_ctx->server_mode->realm,
- subdom->name, gc_service_name,
- subdom->name, &ad_options->service);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n");
- talloc_free(ad_options);
- return ret;
- }
-
- ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
- if (ad_id_ctx == NULL) {
- talloc_free(ad_options);
- return ENOMEM;
- }
- ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
- ad_options->id_ctx = ad_id_ctx;
-
- ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
-
- /* use AD plugin */
- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
- default_host_dbs,
- ad_id_ctx->ad_options->id,
- id_ctx->server_mode->hostname,
- ad_domain,
- ad_site_override);
- if (srv_ctx == NULL) {
- DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
- return ENOMEM;
- }
- be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
- ad_srv_plugin_recv, srv_ctx, "AD");
-
- ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
- ad_id_ctx->sdap_id_ctx->opts->sdom,
- subdom->parent);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n");
- talloc_free(ad_options);
- return ret;
- }
-
- sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
- if (sdom == NULL) {
- return EFAULT;
- }
-
- sdap_inherit_options(subdom->parent->sd_inherit,
- id_ctx->sdap_id_ctx->opts,
- ad_id_ctx->sdap_id_ctx->opts);
-
- ret = sdap_id_setup_tasks(be_ctx,
- ad_id_ctx->sdap_id_ctx,
- sdom,
- ldap_enumeration_send,
- ldap_enumeration_recv,
- ad_id_ctx->sdap_id_ctx);
- if (ret != EOK) {
- talloc_free(ad_options);
- return ret;
- }
-
- sdom->pvt = ad_id_ctx;
-
- /* Set up the ID mapping object */
- ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
- id_ctx->sdap_id_ctx->opts->idmap_ctx;
-
- *_ad_id_ctx = ad_id_ctx;
- return EOK;
-}
-
-static errno_t
-ipa_server_trust_add(struct be_ctx *be_ctx,
- struct ipa_id_ctx *id_ctx,
- struct sss_domain_info *subdom)
-{
- struct ipa_ad_server_ctx *trust_ctx;
- struct ad_id_ctx *ad_id_ctx;
- errno_t ret;
-
- ret = ipa_ad_ctx_new(be_ctx, id_ctx, subdom, &ad_id_ctx);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot create ad_id_ctx for subdomain %s\n", subdom->name);
- return ret;
- }
-
- trust_ctx = talloc(id_ctx->server_mode, struct ipa_ad_server_ctx);
- if (trust_ctx == NULL) {
- return ENOMEM;
- }
- trust_ctx->dom = subdom;
- trust_ctx->ad_id_ctx = ad_id_ctx;
-
- DLIST_ADD(id_ctx->server_mode->trusts, trust_ctx);
- return EOK;
-}
-
-static errno_t
-ipa_ad_subdom_refresh(struct be_ctx *be_ctx,
- struct ipa_id_ctx *id_ctx,
- struct sss_domain_info *parent)
-{
- struct sss_domain_info *dom;
- struct ipa_ad_server_ctx *trust_iter;
- errno_t ret;
-
- if (dp_opt_get_bool(id_ctx->ipa_options->basic,
- IPA_SERVER_MODE) == false) {
- return EOK;
- }
-
- for (dom = get_next_domain(parent, true);
- dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
- dom = get_next_domain(dom, false)) {
-
- /* Check if we already have an ID context for this subdomain */
- DLIST_FOR_EACH(trust_iter, id_ctx->server_mode->trusts) {
- if (trust_iter->dom == dom) {
- break;
- }
- }
-
- /* Newly detected trust */
- if (trust_iter == NULL) {
- ret = ipa_server_trust_add(be_ctx, id_ctx, dom);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot create ad_id_ctx for subdomain %s\n",
- dom->name);
- continue;
- }
- }
- }
-
- return EOK;
-}
-
-static errno_t
ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
{
errno_t ret;
@@ -362,41 +143,6 @@ ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
return EOK;
}
-static void
-ipa_ad_subdom_remove(struct ipa_subdomains_ctx *ctx,
- struct sss_domain_info *subdom)
-{
- struct ipa_ad_server_ctx *iter;
- struct sdap_domain *sdom;
-
- if (dp_opt_get_bool(ctx->id_ctx->ipa_options->basic,
- IPA_SERVER_MODE) == false) {
- return;
- }
-
- DLIST_FOR_EACH(iter, ctx->id_ctx->server_mode->trusts) {
- if (iter->dom == subdom) break;
- }
-
- if (iter == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "No IPA-AD context for subdomain %s\n",
- subdom->name);
- return;
- }
-
- sdom = sdap_domain_get(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
- if (sdom == NULL) return;
- be_ptask_destroy(&sdom->enum_task);
- be_ptask_destroy(&sdom->cleanup_task);
-
- sdap_domain_remove(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
- DLIST_REMOVE(ctx->id_ctx->server_mode->trusts, iter);
-
- /* terminate all requests for this subdomain so we can free it */
- be_terminate_domain_requests(ctx->be_ctx, subdom->name);
- talloc_zfree(sdom);
-}
-
static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
char *domain_name,
size_t count,
@@ -764,7 +510,7 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx,
}
/* Remove the AD ID ctx from the list of LDAP domains */
- ipa_ad_subdom_remove(ctx, dom);
+ ipa_ad_subdom_remove(ctx->be_ctx, ctx->id_ctx, dom);
} else {
/* ok let's try to update it */
ret = ipa_subdom_store(parent, ctx->sdap_id_ctx->opts->idmap_ctx,
@@ -1288,7 +1034,8 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
goto done;
}
- ret = ipa_ad_subdom_refresh(ctx->sd_ctx->be_ctx, ctx->sd_ctx->id_ctx,
+ ret = ipa_ad_subdom_refresh(ctx->sd_ctx->be_ctx,
+ ctx->sd_ctx->id_ctx,
domain);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
@@ -1715,62 +1462,9 @@ int ipa_subdom_init(struct be_ctx *be_ctx,
"Users from trusted domains might not be resolved correctly\n");
}
- return EOK;
-}
-
-int ipa_ad_subdom_init(struct be_ctx *be_ctx,
- struct ipa_id_ctx *id_ctx)
-{
- char *realm;
- char *hostname;
- errno_t ret;
-
- if (dp_opt_get_bool(id_ctx->ipa_options->basic,
- IPA_SERVER_MODE) == false) {
- return EOK;
- }
-
- /* The IPA code relies on the default FQDN format to unparse user
- * names. Warn loudly if the full_name_format was customized on the
- * IPA server
- */
- if ((strcmp(be_ctx->domain->names->fq_fmt,
- CONFDB_DEFAULT_FULL_NAME_FORMAT) != 0)
- && (strcmp(be_ctx->domain->names->fq_fmt,
- CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL) != 0)) {
- DEBUG(SSSDBG_FATAL_FAILURE, "%s is set to a non-default value [%s] " \
- "lookups of subdomain users will likely fail!\n",
- CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
- sss_log(SSS_LOG_ERR, "%s is set to a non-default value [%s] " \
- "lookups of subdomain users will likely fail!\n",
- CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
- /* Attempt to continue */
- }
-
- realm = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_KRB5_REALM);
- if (realm == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
- return EINVAL;
- }
-
- hostname = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_HOSTNAME);
- if (hostname == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "No host name for IPA?\n");
- return EINVAL;
- }
-
- id_ctx->server_mode = talloc_zero(id_ctx, struct ipa_server_mode_ctx);
- if (id_ctx->server_mode == NULL) {
- return ENOMEM;
- }
- id_ctx->server_mode->realm = realm;
- id_ctx->server_mode->hostname = hostname;
- id_ctx->server_mode->trusts = NULL;
- id_ctx->server_mode->ext_groups = NULL;
-
- ret = ipa_ad_subdom_refresh(be_ctx, id_ctx, be_ctx->domain);
+ ret = ipa_ad_subdom_init(be_ctx, id_ctx);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
+ DEBUG(SSSDBG_CRIT_FAILURE, "ipa_ad_subdom_init failed.\n");
return ret;
}
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
index 0cece2cc7..d92bd01e8 100644
--- a/src/providers/ipa/ipa_subdomains.h
+++ b/src/providers/ipa/ipa_subdomains.h
@@ -47,6 +47,18 @@ struct ipa_ad_server_ctx {
struct ipa_ad_server_ctx *next, *prev;
};
+/* To be used by ipa_subdomains.c only */
+errno_t ipa_ad_subdom_refresh(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *parent);
+
+void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *subdom);
+
+int ipa_ad_subdom_init(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx);
+
/* struct for external group memberships, defined in
* ipa_subdomains_ext_groups.c */
struct ipa_ext_groups;
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
new file mode 100644
index 000000000..237f60e03
--- /dev/null
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -0,0 +1,340 @@
+/*
+ SSSD
+
+ IPA Subdomains Module - server mode
+
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2015 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "providers/ldap/sdap_async.h"
+#include "providers/ldap/sdap_idmap.h"
+#include "providers/ipa/ipa_subdomains.h"
+#include "providers/ipa/ipa_common.h"
+#include "providers/ipa/ipa_id.h"
+
+static errno_t
+ipa_ad_ctx_new(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *subdom,
+ struct ad_id_ctx **_ad_id_ctx)
+{
+ struct ad_options *ad_options;
+ struct ad_id_ctx *ad_id_ctx;
+ const char *gc_service_name;
+ struct ad_srv_plugin_ctx *srv_ctx;
+ char *ad_domain;
+ const char *ad_site_override;
+ struct sdap_domain *sdom;
+ errno_t ret;
+ const char *extra_attrs;
+
+ ad_options = ad_create_default_options(id_ctx, id_ctx->server_mode->realm,
+ id_ctx->server_mode->hostname);
+ if (ad_options == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
+ talloc_free(ad_options);
+ return ENOMEM;
+ }
+
+ ad_domain = subdom->name;
+
+ ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD domain\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM,
+ id_ctx->server_mode->realm);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD realm\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ extra_attrs = dp_opt_get_string(id_ctx->sdap_id_ctx->opts->basic,
+ SDAP_USER_EXTRA_ATTRS);
+ if (extra_attrs != NULL) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain,
+ extra_attrs);
+
+ ret = dp_opt_set_string(ad_options->id->basic, SDAP_USER_EXTRA_ATTRS,
+ extra_attrs);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "dp_opt_get_string failed.\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ ret = sdap_extend_map_with_list(ad_options->id, ad_options->id,
+ SDAP_USER_EXTRA_ATTRS,
+ ad_options->id->user_map,
+ SDAP_OPTS_USER,
+ &ad_options->id->user_map,
+ &ad_options->id->user_map_cnt);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+ } else {
+ DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n");
+ }
+
+ gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->name);
+ if (gc_service_name == NULL) {
+ talloc_free(ad_options);
+ return ENOMEM;
+ }
+
+ /* Set KRB5 realm to same as the one of IPA when IPA
+ * is able to attach PAC. For testing, use hardcoded. */
+ ret = ad_failover_init(ad_options, be_ctx, NULL, NULL,
+ id_ctx->server_mode->realm,
+ subdom->name, gc_service_name,
+ subdom->name, &ad_options->service);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
+ if (ad_id_ctx == NULL) {
+ talloc_free(ad_options);
+ return ENOMEM;
+ }
+ ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
+ ad_options->id_ctx = ad_id_ctx;
+
+ ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
+
+ /* use AD plugin */
+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
+ default_host_dbs,
+ ad_id_ctx->ad_options->id,
+ id_ctx->server_mode->hostname,
+ ad_domain,
+ ad_site_override);
+ if (srv_ctx == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
+ return ENOMEM;
+ }
+ be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
+ ad_srv_plugin_recv, srv_ctx, "AD");
+
+ ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
+ ad_id_ctx->sdap_id_ctx->opts->sdom,
+ subdom->parent);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
+ if (sdom == NULL) {
+ return EFAULT;
+ }
+
+ sdap_inherit_options(subdom->parent->sd_inherit,
+ id_ctx->sdap_id_ctx->opts,
+ ad_id_ctx->sdap_id_ctx->opts);
+
+ ret = sdap_id_setup_tasks(be_ctx,
+ ad_id_ctx->sdap_id_ctx,
+ sdom,
+ ldap_enumeration_send,
+ ldap_enumeration_recv,
+ ad_id_ctx->sdap_id_ctx);
+ if (ret != EOK) {
+ talloc_free(ad_options);
+ return ret;
+ }
+
+ sdom->pvt = ad_id_ctx;
+
+ /* Set up the ID mapping object */
+ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
+ id_ctx->sdap_id_ctx->opts->idmap_ctx;
+
+ *_ad_id_ctx = ad_id_ctx;
+ return EOK;
+}
+
+static errno_t ipa_server_trust_add(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *subdom)
+{
+ struct ipa_ad_server_ctx *trust_ctx;
+ struct ad_id_ctx *ad_id_ctx;
+ errno_t ret;
+
+ ret = ipa_ad_ctx_new(be_ctx, id_ctx, subdom, &ad_id_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot create ad_id_ctx for subdomain %s\n", subdom->name);
+ return ret;
+ }
+
+ trust_ctx = talloc(id_ctx->server_mode, struct ipa_ad_server_ctx);
+ if (trust_ctx == NULL) {
+ return ENOMEM;
+ }
+ trust_ctx->dom = subdom;
+ trust_ctx->ad_id_ctx = ad_id_ctx;
+
+ DLIST_ADD(id_ctx->server_mode->trusts, trust_ctx);
+ return EOK;
+}
+
+errno_t ipa_ad_subdom_refresh(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *parent)
+{
+ struct sss_domain_info *dom;
+ struct ipa_ad_server_ctx *trust_iter;
+ errno_t ret;
+
+ if (dp_opt_get_bool(id_ctx->ipa_options->basic,
+ IPA_SERVER_MODE) == false) {
+ return EOK;
+ }
+
+ for (dom = get_next_domain(parent, true);
+ dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
+ dom = get_next_domain(dom, false)) {
+
+ /* Check if we already have an ID context for this subdomain */
+ DLIST_FOR_EACH(trust_iter, id_ctx->server_mode->trusts) {
+ if (trust_iter->dom == dom) {
+ break;
+ }
+ }
+
+ /* Newly detected trust */
+ if (trust_iter == NULL) {
+ ret = ipa_server_trust_add(be_ctx, id_ctx, dom);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot create ad_id_ctx for subdomain %s\n",
+ dom->name);
+ continue;
+ }
+ }
+ }
+
+ return EOK;
+}
+
+void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *subdom)
+{
+ struct ipa_ad_server_ctx *iter;
+ struct sdap_domain *sdom;
+
+ if (dp_opt_get_bool(id_ctx->ipa_options->basic,
+ IPA_SERVER_MODE) == false) {
+ return;
+ }
+
+ DLIST_FOR_EACH(iter, id_ctx->server_mode->trusts) {
+ if (iter->dom == subdom) break;
+ }
+
+ if (iter == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No IPA-AD context for subdomain %s\n",
+ subdom->name);
+ return;
+ }
+
+ sdom = sdap_domain_get(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
+ if (sdom == NULL) return;
+ be_ptask_destroy(&sdom->enum_task);
+ be_ptask_destroy(&sdom->cleanup_task);
+
+ sdap_domain_remove(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
+ DLIST_REMOVE(id_ctx->server_mode->trusts, iter);
+
+ /* terminate all requests for this subdomain so we can free it */
+ be_terminate_domain_requests(be_ctx, subdom->name);
+ talloc_zfree(sdom);
+}
+
+int ipa_ad_subdom_init(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx)
+{
+ char *realm;
+ char *hostname;
+ errno_t ret;
+
+ if (dp_opt_get_bool(id_ctx->ipa_options->basic,
+ IPA_SERVER_MODE) == false) {
+ return EOK;
+ }
+
+ /* The IPA code relies on the default FQDN format to unparse user
+ * names. Warn loudly if the full_name_format was customized on the
+ * IPA server
+ */
+ if ((strcmp(be_ctx->domain->names->fq_fmt,
+ CONFDB_DEFAULT_FULL_NAME_FORMAT) != 0)
+ && (strcmp(be_ctx->domain->names->fq_fmt,
+ CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL) != 0)) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "%s is set to a non-default value [%s] " \
+ "lookups of subdomain users will likely fail!\n",
+ CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
+ sss_log(SSS_LOG_ERR, "%s is set to a non-default value [%s] " \
+ "lookups of subdomain users will likely fail!\n",
+ CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
+ /* Attempt to continue */
+ }
+
+ realm = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_KRB5_REALM);
+ if (realm == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
+ return EINVAL;
+ }
+
+ hostname = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_HOSTNAME);
+ if (hostname == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No host name for IPA?\n");
+ return EINVAL;
+ }
+
+ id_ctx->server_mode = talloc_zero(id_ctx, struct ipa_server_mode_ctx);
+ if (id_ctx->server_mode == NULL) {
+ return ENOMEM;
+ }
+ id_ctx->server_mode->realm = realm;
+ id_ctx->server_mode->hostname = hostname;
+ id_ctx->server_mode->trusts = NULL;
+ id_ctx->server_mode->ext_groups = NULL;
+
+ ret = ipa_ad_subdom_refresh(be_ctx, id_ctx, be_ctx->domain);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
+ return ret;
+ }
+
+ return EOK;
+}