diff options
Diffstat (limited to 'src/providers/ipa')
-rw-r--r-- | src/providers/ipa/ipa_common.c | 26 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.h | 2 | ||||
-rw-r--r-- | src/providers/ipa/ipa_init.c | 4 | ||||
-rw-r--r-- | src/providers/ipa/ipa_opts.h | 1 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 147 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.h | 1 |
6 files changed, 164 insertions, 17 deletions
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 262a9bccc..09fbeadc0 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -146,6 +146,9 @@ static errno_t ipa_parse_search_base(TALLOC_CTX *mem_ctx, case IPA_SUBDOMAINS_SEARCH_BASE: class_name = "IPA_SUBDOMAINS"; break; + case IPA_MASTER_DOMAIN_SEARCH_BASE: + class_name = "IPA_MASTER_DOMAIN"; + break; default: DEBUG(SSSDBG_CONF_SETTINGS, ("Unknown search base type: [%d]\n", class)); @@ -513,6 +516,29 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, &ipa_opts->subdomains_search_bases); if (ret != EOK) goto done; + if (NULL == dp_opt_get_string(ipa_opts->basic, + IPA_MASTER_DOMAIN_SEARCH_BASE)) { + value = talloc_asprintf(tmpctx, "cn=ad,cn=etc,%s", basedn); + if (value == NULL) { + ret = ENOMEM; + goto done; + } + + ret = dp_opt_set_string(ipa_opts->basic, IPA_MASTER_DOMAIN_SEARCH_BASE, value); + if (ret != EOK) { + goto done; + } + + DEBUG(SSSDBG_CONF_SETTINGS, ("Option %s set to %s\n", + ipa_opts->basic[IPA_MASTER_DOMAIN_SEARCH_BASE].opt_name, + dp_opt_get_string(ipa_opts->basic, + IPA_MASTER_DOMAIN_SEARCH_BASE))); + } + ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic, + IPA_MASTER_DOMAIN_SEARCH_BASE, + &ipa_opts->master_domain_search_bases); + if (ret != EOK) goto done; + ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_attr_map, SDAP_AT_GENERAL, diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 9232260eb..0a18ec1b1 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -42,6 +42,7 @@ enum ipa_basic_opt { IPA_HOST_SEARCH_BASE, IPA_SELINUX_SEARCH_BASE, IPA_SUBDOMAINS_SEARCH_BASE, + IPA_MASTER_DOMAIN_SEARCH_BASE, IPA_KRB5_REALM, IPA_HBAC_REFRESH, IPA_HBAC_DENY_METHOD, @@ -125,6 +126,7 @@ struct ipa_options { struct sdap_search_base **hbac_search_bases; struct sdap_search_base **selinux_search_bases; struct sdap_search_base **subdomains_search_bases; + struct sdap_search_base **master_domain_search_bases; struct ipa_service *service; /* id provider */ diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c index 90acb1082..b58058a8e 100644 --- a/src/providers/ipa/ipa_init.c +++ b/src/providers/ipa/ipa_init.c @@ -522,7 +522,7 @@ int sssm_ipa_autofs_init(struct be_ctx *bectx, int sssm_ipa_subdomains_init(struct be_ctx *bectx, struct bet_ops **ops, - void **pvt_data) + void **pvt_data) { int ret; struct ipa_subdomains_ctx *subdomains_ctx; @@ -541,7 +541,7 @@ int sssm_ipa_subdomains_init(struct be_ctx *bectx, } subdomains_ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; subdomains_ctx->search_bases = id_ctx->ipa_options->subdomains_search_bases; - + subdomains_ctx->master_search_bases = id_ctx->ipa_options->master_domain_search_bases; *ops = &ipa_subdomains_ops; *pvt_data = subdomains_ctx; diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index f688f765c..770406cfe 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -39,6 +39,7 @@ struct dp_option ipa_basic_opts[] = { { "ipa_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_selinux_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_subdomains_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ipa_master_domain_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ipa_hbac_refresh", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, { "ipa_hbac_treat_deny_as", DP_OPT_STRING, { "DENY_ALL" }, NULL_STRING }, diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index da9785f2c..185b3c523 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -27,10 +27,24 @@ #include "providers/ipa/ipa_common.h" #define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain" +#define MASTER_DOMAIN_FILTER "objectclass=ipaNTDomainAttrs" + #define IPA_CN "cn" #define IPA_FLATNAME "ipaNTFlatName" #define IPA_SID "ipaNTTrustedDomainSID" +enum ipa_subdomains_req_type { + IPA_SUBDOMAINS_MASTER, + IPA_SUBDOMAINS_SLAVE, + + IPA_SUBDOMAINS_MAX /* Counter */ +}; + +struct ipa_subdomains_req_params { + const char *filter; + tevent_req_fn cb; +}; + static void ipa_subdomains_reply(struct be_req *be_req, int dp_err, int result) { be_req->fn(be_req, dp_err, result, NULL); @@ -131,8 +145,16 @@ struct ipa_subdomains_req_ctx { }; static void ipa_subdomains_get_conn_done(struct tevent_req *req); -static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx); +static errno_t +ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx, + enum ipa_subdomains_req_type type); static void ipa_subdomains_handler_done(struct tevent_req *req); +static void ipa_subdomains_handler_master_done(struct tevent_req *req); + +static struct ipa_subdomains_req_params subdomain_requests[] = { + { MASTER_DOMAIN_FILTER, ipa_subdomains_handler_master_done }, + { SUBDOMAINS_FILTER, ipa_subdomains_handler_done } +}; void ipa_subdomains_handler(struct be_req *be_req) { @@ -208,7 +230,7 @@ static void ipa_subdomains_get_conn_done(struct tevent_req *req) goto fail; } - ret = ipa_subdomains_handler_next(ctx); + ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE); if (ret != EOK && ret != EAGAIN) { goto fail; } @@ -221,23 +243,31 @@ fail: ipa_subdomains_reply(be_req, dp_error, ret); } -static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx) +static errno_t +ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx, + enum ipa_subdomains_req_type type) { struct tevent_req *req; struct sdap_search_base *base; - const char *attrs[] = {"cn", - "ipaNTFlatName", - "ipaNTTrustedDomainSID", + struct ipa_subdomains_req_params *params; + const char *attrs[] = {IPA_CN, + IPA_FLATNAME, + IPA_SID, NULL}; + if (type >= IPA_SUBDOMAINS_MAX) { + return EINVAL; + } + + params = &subdomain_requests[type]; + base = ctx->search_bases[ctx->search_base_iter]; if (base == NULL) { return EOK; } talloc_free(ctx->current_filter); - ctx->current_filter = sdap_get_id_specific_filter(ctx, SUBDOMAINS_FILTER, - base->filter); + ctx->current_filter = sdap_get_id_specific_filter(ctx, params->filter, base->filter); if (ctx->current_filter == NULL) { return ENOMEM; } @@ -255,7 +285,7 @@ static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx) return ENOMEM; } - tevent_req_set_callback(req, ipa_subdomains_handler_done, ctx); + tevent_req_set_callback(req, params->cb, ctx); return EAGAIN; } @@ -263,13 +293,15 @@ static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx) static void ipa_subdomains_handler_done(struct tevent_req *req) { int ret; - struct be_req *be_req; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ipa_subdomains_req_ctx *ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); + struct be_req *be_req = ctx->be_req; + struct sysdb_ctx *sysdb; + struct subdomain_info *domain_info; - be_req = ctx->be_req; + sysdb = (be_req->sysdb)?be_req->sysdb:be_req->be_ctx->sysdb; ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); @@ -291,7 +323,7 @@ static void ipa_subdomains_handler_done(struct tevent_req *req) } ctx->search_base_iter++; - ret = ipa_subdomains_handler_next(ctx); + ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE); if (ret == EAGAIN) { return; } else if (ret != EOK) { @@ -304,14 +336,99 @@ static void ipa_subdomains_handler_done(struct tevent_req *req) goto done; } - ret = sysdb_update_subdomains(ctx->sd_ctx->sdap_id_ctx->be->sysdb, - ctx->sd_data->domain_list); + ret = sysdb_update_subdomains(sysdb, ctx->sd_data->domain_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n")); goto done; } - ret = EOK; + ret = sysdb_master_domain_get_info(ctx, sysdb, &domain_info); + if (ret != EOK) { + goto done; + } + + if (domain_info->flat_name == NULL || + domain_info->id == NULL || + domain_info->name == NULL) { + + ctx->search_base_iter = 0; + ctx->search_bases = ctx->sd_ctx->master_search_bases; + ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER); + if (ret == EAGAIN) { + return; + } else if (ret != EOK) { + goto done; + } + } else { + ret = EOK; + } + +done: + talloc_free(ctx); + ipa_subdomains_reply(be_req, (ret == EOK ? DP_ERR_OK : DP_ERR_FATAL), ret); +} + +static void ipa_subdomains_handler_master_done(struct tevent_req *req) +{ + errno_t ret; + size_t reply_count; + struct sysdb_attrs **reply = NULL; + struct ipa_subdomains_req_ctx *ctx = tevent_req_callback_data(req, + struct ipa_subdomains_req_ctx); + struct be_req *be_req = ctx->be_req; + struct subdomain_info *domain_info; + const char *tmp_str; + + ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); + talloc_zfree(req); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n")); + goto done; + } + + if (reply_count) { + domain_info = talloc_zero(ctx, struct subdomain_info); + if (domain_info == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &tmp_str); + if (ret != EOK) goto done; + domain_info->flat_name = talloc_strdup(domain_info, tmp_str); + if (domain_info->flat_name == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_attrs_get_string(reply[0], IPA_SID, &tmp_str); + if (ret != EOK) { + goto done; + } + domain_info->id = talloc_strdup(domain_info, tmp_str); + if (domain_info->flat_name == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_master_domain_add_info(be_req->be_ctx->sysdb, domain_info); + goto done; + } else { + ctx->search_base_iter++; + ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER); + if (ret == EAGAIN) { + return; + } else if (ret != EOK) { + goto done; + } + + /* Right now we know there has been an error + * and we don't have the master domain record + */ + DEBUG(SSSDBG_CRIT_FAILURE, ("Master domain record not found!\n")); + ret = EIO; + goto done; + } done: talloc_free(ctx); diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h index be62b1525..76406f122 100644 --- a/src/providers/ipa/ipa_subdomains.h +++ b/src/providers/ipa/ipa_subdomains.h @@ -31,6 +31,7 @@ struct ipa_subdomains_ctx { struct sdap_id_ctx *sdap_id_ctx; struct sdap_search_base **search_bases; + struct sdap_search_base **master_search_bases; }; |