diff --git a/Makefile.am b/Makefile.am index d0265b9f72..6b54e1eea0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3452,10 +3452,13 @@ test_ipa_subdom_server_SOURCES = \ src/tests/cmocka/common_mock_sdap.c \ src/tests/cmocka/common_mock_be.c \ src/tests/cmocka/common_mock_krb5.c \ + src/tests/cmocka/data_provider/mock_dp.c \ src/tests/cmocka/test_ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_utils.c \ + src/providers/ipa/ipa_common.c \ src/providers/ipa/ipa_opts.c \ + src/providers/ipa/ipa_srv.c \ src/providers/ldap/ldap_common.c \ $(NULL) test_ipa_subdom_server_CFLAGS = \ diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index f6e6b0cc41..fe63462da5 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -413,6 +413,7 @@ struct sss_domain_info { char *dns_name; char *domain_id; uint32_t trust_direction; + uint32_t trust_type; struct timeval subdomains_last_checked; bool has_views; diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 047a4877fe..1b827caf94 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -173,6 +173,7 @@ #define SYSDB_SUBDOMAIN_ENUM "enumerate" #define SYSDB_SUBDOMAIN_FOREST "memberOfForest" #define SYSDB_SUBDOMAIN_TRUST_DIRECTION "trustDirection" +#define SYSDB_SUBDOMAIN_TRUST_TYPE "trustType" #define SYSDB_UPN_SUFFIXES "upnSuffixes" #define SYSDB_SITE "site" #define SYSDB_ENABLED "enabled" @@ -566,6 +567,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, enum sss_domain_mpg_mode mpg_mode, bool enumerate, const char *forest, uint32_t trust_direction, + uint32_t trust_type, struct ldb_message_element *upn_suffixes); errno_t sysdb_update_subdomains(struct sss_domain_info *domain, @@ -607,6 +609,7 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, const char *forest, const char **upn_suffixes, uint32_t trust_direction, + uint32_t trust_type, struct confdb_ctx *confdb, bool enabled); diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index 149e9a1617..859a73b91d 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -40,6 +40,7 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, const char *forest, const char **upn_suffixes, uint32_t trust_direction, + uint32_t trust_type, struct confdb_ctx *confdb, bool enabled) { @@ -175,6 +176,7 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, dom->case_preserve = inherit_option ? parent->case_preserve : false; dom->trust_direction = trust_direction; + dom->trust_type = trust_type; /* If the parent domain explicitly limits ID ranges, the subdomain * should honour the limits as well. */ @@ -415,6 +417,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, SYSDB_SUBDOMAIN_TRUST_DIRECTION, + SYSDB_SUBDOMAIN_TRUST_TYPE, SYSDB_UPN_SUFFIXES, SYSDB_ENABLED, NULL}; @@ -431,6 +434,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, enum sss_domain_mpg_mode mpg_mode; bool enumerate; uint32_t trust_direction; + uint32_t trust_type; struct ldb_message_element *tmp_el; const char **upn_suffixes; @@ -519,6 +523,10 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, SYSDB_SUBDOMAIN_TRUST_DIRECTION, 0); + trust_type = ldb_msg_find_attr_as_int(res->msgs[i], + SYSDB_SUBDOMAIN_TRUST_TYPE, + 0); + enabled = ldb_msg_find_attr_as_bool(res->msgs[i], SYSDB_ENABLED, true); for (dom = domain->subdomains; dom; @@ -651,6 +659,12 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, dom->trust_direction = trust_direction; } + if (dom->trust_type != trust_type) { + DEBUG(SSSDBG_TRACE_INTERNAL, + "Trust type change from [%d] to [%d]!\n", + dom->trust_type, trust_type); + dom->trust_type = trust_type; + } break; } } @@ -658,8 +672,8 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, if (dom == NULL) { dom = new_subdomain(domain, domain, name, realm, flat, dns, id, mpg_mode, enumerate, forest, - upn_suffixes, trust_direction, confdb, - enabled); + upn_suffixes, trust_direction, trust_type, + confdb, enabled); if (dom == NULL) { ret = ENOMEM; goto done; @@ -1087,6 +1101,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, enum sss_domain_mpg_mode mpg_mode, bool enumerate, const char *forest, uint32_t trust_direction, + uint32_t trust_type, struct ldb_message_element *upn_suffixes) { TALLOC_CTX *tmp_ctx; @@ -1102,6 +1117,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, SYSDB_SUBDOMAIN_TRUST_DIRECTION, + SYSDB_SUBDOMAIN_TRUST_TYPE, SYSDB_UPN_SUFFIXES, NULL}; const char *tmp_str; @@ -1116,8 +1132,10 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, int enum_flags = 0; int forest_flags = 0; int td_flags = 0; + int tt_flags = 0; int upn_flags = 0; uint32_t tmp_td; + uint32_t tmp_tt; int ret; tmp_ctx = talloc_new(NULL); @@ -1151,6 +1169,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, enum_flags = LDB_FLAG_MOD_ADD; if (forest) forest_flags = LDB_FLAG_MOD_ADD; if (trust_direction) td_flags = LDB_FLAG_MOD_ADD; + if (trust_type) tt_flags = LDB_FLAG_MOD_ADD; if (upn_suffixes) upn_flags = LDB_FLAG_MOD_ADD; } else if (res->count != 1) { ret = EINVAL; @@ -1233,6 +1252,13 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, td_flags = LDB_FLAG_MOD_REPLACE; } + tmp_tt = ldb_msg_find_attr_as_uint(res->msgs[0], + SYSDB_SUBDOMAIN_TRUST_TYPE, + 0); + if (tmp_tt != trust_type) { + tt_flags = LDB_FLAG_MOD_REPLACE; + } + if (upn_suffixes) { tmp_el = ldb_msg_find_element(res->msgs[0], SYSDB_UPN_SUFFIXES); /* Luckily ldb_msg_element_compare() only compares the values and @@ -1247,7 +1273,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, if (!store && realm_flags == 0 && flat_flags == 0 && dns_flags == 0 && id_flags == 0 && mpg_flags == 0 && enum_flags == 0 && forest_flags == 0 - && td_flags == 0 && upn_flags == 0) { + && td_flags == 0 && tt_flags == 0 && upn_flags == 0) { ret = EOK; goto done; } @@ -1396,6 +1422,22 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, } } + if (tt_flags) { + ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_TRUST_TYPE, + tt_flags, NULL); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = ldb_msg_add_fmt(msg, SYSDB_SUBDOMAIN_TRUST_TYPE, + "%u", trust_type); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + } + if (upn_flags) { tmp_el = talloc_zero(tmp_ctx, struct ldb_message_element); if (tmp_el == NULL) { diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml index 57a55bef96..57b89b0369 100644 --- a/src/man/sssd-ipa.5.xml +++ b/src/man/sssd-ipa.5.xml @@ -935,6 +935,12 @@ ad_server = dc.ad.domain.com ad_site + + ipa_server + + + ipa_backup_server + ldap_search_base @@ -949,11 +955,15 @@ ad_server = dc.ad.domain.com + + Options prefixed with 'ad_' or 'ipa_' only apply to + their respective subdomain type. + OPTIONS TUNABLE ON IPA CLIENTS - The following options can be set in a subdomain + The following options can be set in an AD subdomain section on an IPA client: diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c index 48e3b81147..1377aa91c1 100644 --- a/src/providers/ad/ad_common.c +++ b/src/providers/ad/ad_common.c @@ -353,60 +353,21 @@ set_common_ad_trust_opts(struct ad_options *ad_options, } struct ad_options * -ad_create_2way_trust_options(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *conf_path, - struct data_provider *dp, - const char *realm, - struct sss_domain_info *subdom, - const char *hostname, - const char *keytab) +ad_create_trust_options(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + struct data_provider *dp, + struct sss_domain_info *subdom, + const char *realm, + const char *hostname, + const char *keytab, + const char *sasl_authid) { struct ad_options *ad_options; errno_t ret; + const char *upper_realm = NULL; - DEBUG(SSSDBG_TRACE_FUNC, "2way trust is defined to domain '%s'\n", - subdom->name); - - ad_options = ad_create_options(mem_ctx, cdb, conf_path, dp, subdom); - if (ad_options == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "ad_create_options failed\n"); - return NULL; - } - - ret = set_common_ad_trust_opts(ad_options, realm, subdom->name, hostname, - keytab); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_common_ad_trust_opts failed\n"); - talloc_free(ad_options); - return NULL; - } - - ret = ad_set_sdap_options(ad_options, ad_options->id); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "ad_set_sdap_options failed\n"); - talloc_free(ad_options); - return NULL; - } - - return ad_options; -} - -struct ad_options * -ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *subdom_conf_path, - struct data_provider *dp, - struct sss_domain_info *subdom, - const char *hostname, - const char *keytab, - const char *sasl_authid) -{ - struct ad_options *ad_options; - const char *realm; - errno_t ret; - - DEBUG(SSSDBG_TRACE_FUNC, "1way trust is defined to domain '%s'\n", + DEBUG(SSSDBG_TRACE_FUNC, "trust is defined to domain '%s'\n", subdom->name); ad_options = ad_create_options(mem_ctx, cdb, subdom_conf_path, dp, subdom); @@ -415,14 +376,16 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, return NULL; } - realm = get_uppercase_realm(ad_options, subdom->name); - if (!realm) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get uppercase realm\n"); - talloc_free(ad_options); - return NULL; + if (realm == NULL) { + upper_realm = get_uppercase_realm(ad_options, subdom->name); + if (upper_realm == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get uppercase realm\n"); + talloc_free(ad_options); + return NULL; + } } - ret = set_common_ad_trust_opts(ad_options, realm, + ret = set_common_ad_trust_opts(ad_options, (realm == NULL ? upper_realm : realm), subdom->name, hostname, keytab); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -433,12 +396,14 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, } /* Set SDAP_SASL_AUTHID to the trust principal */ - ret = dp_opt_set_string(ad_options->id->basic, - SDAP_SASL_AUTHID, sasl_authid); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n"); - talloc_free(ad_options); - return NULL; + if (sasl_authid != NULL) { + ret = dp_opt_set_string(ad_options->id->basic, + SDAP_SASL_AUTHID, sasl_authid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n"); + talloc_free(ad_options); + return NULL; + } } ret = ad_set_sdap_options(ad_options, ad_options->id); @@ -1656,11 +1621,11 @@ ad_user_conn_list(TALLOC_CTX *mem_ctx, return clist; } -errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts, - struct dp_option *subdom_opts, - struct confdb_ctx *cdb, - const char *subdom_conf_path, - int opt_id) +errno_t subdom_inherit_opts_if_needed(struct dp_option *parent_opts, + struct dp_option *subdom_opts, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + int opt_id) { int ret; bool is_default = true; diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h index 1c8d60e0c2..9fdfd58a31 100644 --- a/src/providers/ad/ad_common.h +++ b/src/providers/ad/ad_common.h @@ -135,23 +135,15 @@ struct ad_options *ad_create_options(TALLOC_CTX *mem_ctx, struct data_provider *dp, struct sss_domain_info *subdom); -struct ad_options *ad_create_2way_trust_options(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *conf_path, - struct data_provider *dp, - const char *realm, - struct sss_domain_info *subdom, - const char *hostname, - const char *keytab); - -struct ad_options *ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *conf_path, - struct data_provider *dp, - struct sss_domain_info *subdom, - const char *hostname, - const char *keytab, - const char *sasl_authid); +struct ad_options *ad_create_trust_options(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct data_provider *dp, + struct sss_domain_info *subdom, + const char *realm, + const char *hostname, + const char *keytab, + const char *sasl_authid); errno_t ad_set_search_bases(struct sdap_options *id_opts, struct sdap_domain *sdap); @@ -245,11 +237,11 @@ errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx, char **_site, char **_forest); -errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts, - struct dp_option *suddom_opts, - struct confdb_ctx *cdb, - const char *subdom_conf_path, - int opt_id); +errno_t subdom_inherit_opts_if_needed(struct dp_option *parent_opts, + struct dp_option *suddom_opts, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + int opt_id); errno_t ad_refresh_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx); diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index d8f3738ce9..0b4c557085 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -27,6 +27,7 @@ #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_srv.h" #include "providers/ad/ad_common.h" +#include "providers/ipa/ipa_subdomains.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_ops.h" @@ -42,7 +43,6 @@ /* Attributes of AD trusted domains */ #define AD_AT_FLATNAME "flatName" #define AD_AT_SID "securityIdentifier" -#define AD_AT_TRUST_TYPE "trustType" #define AD_AT_TRUST_PARTNER "trustPartner" #define AD_AT_TRUST_ATTRS "trustAttributes" #define AD_AT_DOMAIN_NAME "cn" @@ -310,13 +310,15 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, return ENOMEM; } - ad_options = ad_create_2way_trust_options(id_ctx, - be_ctx->cdb, - subdom_conf_path, - be_ctx->provider, - realm, - subdom, - hostname, keytab); + ad_options = ad_create_trust_options(id_ctx, + be_ctx->cdb, + subdom_conf_path, + be_ctx->provider, + subdom, + realm, + hostname, + keytab, + NULL); if (ad_options == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n"); talloc_free(ad_options); @@ -324,10 +326,10 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, return ENOMEM; } - ret = ad_inherit_opts_if_needed(id_ctx->ad_options->basic, - ad_options->basic, - be_ctx->cdb, subdom_conf_path, - AD_USE_LDAPS); + ret = subdom_inherit_opts_if_needed(id_ctx->ad_options->basic, + ad_options->basic, + be_ctx->cdb, subdom_conf_path, + AD_USE_LDAPS); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to inherit option [%s] to sub-domain [%s]. " @@ -341,10 +343,10 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, ad_set_ssf_and_mech_for_ldaps(ad_options->id); } - ret = ad_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic, - ad_options->id->basic, - be_ctx->cdb, subdom_conf_path, - SDAP_SASL_MECH); + ret = subdom_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic, + ad_options->id->basic, + be_ctx->cdb, subdom_conf_path, + SDAP_SASL_MECH); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to inherit option [%s] to sub-domain [%s]. " @@ -582,6 +584,7 @@ ad_subdom_store(struct confdb_ctx *cdb, char *realm; const char *flat; const char *dns; + uint32_t trust_type; errno_t ret; enum idmap_error_code err; struct ldb_message_element *el; @@ -595,6 +598,9 @@ ad_subdom_store(struct confdb_ctx *cdb, goto done; } + /* AD trust type */ + trust_type = IPA_TRUST_AD; + ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_TRUST_PARTNER, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "failed to get subdomain name\n"); @@ -645,7 +651,8 @@ ad_subdom_store(struct confdb_ctx *cdb, name, str_domain_mpg_mode(mpg_mode)); ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, dns, sid_str, - mpg_mode, enumerate, domain->forest, 0, NULL); + mpg_mode, enumerate, domain->forest, 0, trust_type, + NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; @@ -1216,7 +1223,7 @@ static void ad_get_slave_domain_connect_done(struct tevent_req *subreq) int dp_error; errno_t ret; const char *attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER, - AD_AT_SID, AD_AT_TRUST_TYPE, AD_AT_DOMAIN_NAME, + AD_AT_SID, AD_AT_DOMAIN_NAME, AD_AT_TRUST_ATTRS, AD_AT_TRUST_DIRECTION, NULL }; req = tevent_req_callback_data(subreq, struct tevent_req); @@ -1425,7 +1432,7 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx, struct sdap_options *opts; errno_t ret; const char *attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER, - AD_AT_SID, AD_AT_TRUST_TYPE, AD_AT_TRUST_DIRECTION, + AD_AT_SID, AD_AT_TRUST_DIRECTION, AD_AT_TRUST_ATTRS, AD_AT_DOMAIN_NAME, NULL }; req = tevent_req_create(mem_ctx, &state, struct ad_get_root_domain_state); @@ -2587,6 +2594,7 @@ ad_check_domain_send(TALLOC_CTX *mem_ctx, const char *parent_dom_name) { errno_t ret; + uint32_t trust_type; struct tevent_req *req; struct tevent_req *subreq; struct ad_check_domain_state *state; @@ -2604,6 +2612,9 @@ ad_check_domain_send(TALLOC_CTX *mem_ctx, state->parent = NULL; state->sdom = NULL; + /* AD trust type */ + trust_type = IPA_TRUST_AD; + state->dom = find_domain_by_name(be_ctx->domain, dom_name, true); if (state->dom == NULL) { state->parent = find_domain_by_name(be_ctx->domain, parent_dom_name, @@ -2619,7 +2630,7 @@ ad_check_domain_send(TALLOC_CTX *mem_ctx, state->dom = new_subdomain(state->parent, state->parent, dom_name, dom_name, NULL, NULL, NULL, MPG_DISABLED, false, state->parent->forest, - NULL, 0, be_ctx->cdb, true); + NULL, 0, trust_type, be_ctx->cdb, true); if (state->dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "new_subdomain() failed.\n"); ret = EINVAL; diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 01c835c733..c84603a183 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -22,10 +22,15 @@ along with this program. If not, see . */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* For strcasestr() in ipa_set_search_bases() */ +#endif + #include #include #include #include +#include #include "db/sysdb_selinux.h" #include "providers/ipa/ipa_common.h" @@ -178,23 +183,10 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct data_provider *dp, + bool sdom_add, struct sdap_options **_opts) { - TALLOC_CTX *tmpctx; - char *basedn; - char *realm; - char *value; int ret; - int i; - bool server_mode; - struct ldb_context *ldb; - - ldb = sysdb_ctx_get_ldb(dp->be_ctx->domain->sysdb); - - tmpctx = talloc_new(ipa_opts); - if (!tmpctx) { - return ENOMEM; - } ipa_opts->id = talloc_zero(ipa_opts, struct sdap_options); if (!ipa_opts->id) { @@ -203,11 +195,13 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, } ipa_opts->id->dp = dp; - ret = sdap_domain_add(ipa_opts->id, - ipa_opts->id_ctx->sdap_id_ctx->be->domain, - NULL); - if (ret != EOK) { - goto done; + if (sdom_add) { + ret = sdap_domain_add(ipa_opts->id, + ipa_opts->id_ctx->sdap_id_ctx->be->domain, + NULL); + if (ret != EOK) { + goto done; + } } /* get sdap options */ @@ -228,38 +222,33 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - ret = domain_to_basedn(tmpctx, - dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM), - &basedn); + + ret = EOK; + *_opts = ipa_opts->id; + +done: if (ret != EOK) { - goto done; + talloc_zfree(ipa_opts->id); } + return ret; +} - if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)) { - /* FIXME: get values by querying IPA */ - /* set search base */ - value = talloc_asprintf(tmpctx, "cn=accounts,%s", basedn); - if (!value) { - ret = ENOMEM; - goto done; - } - ret = dp_opt_set_string(ipa_opts->id->basic, - SDAP_SEARCH_BASE, value); - if (ret != EOK) { - goto done; - } +errno_t +ipa_set_sdap_options(struct ipa_options *ipa_opts, + struct sdap_options *sdap_opts) +{ + TALLOC_CTX *tmpctx; + errno_t ret; + char *realm; + char *value; - DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_SEARCH_BASE].opt_name, - dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); + tmpctx = talloc_new(ipa_opts); + if (!tmpctx) { + return ENOMEM; } - ret = sdap_parse_search_base(ipa_opts->id, ldb, ipa_opts->id->basic, - SDAP_SEARCH_BASE, - &ipa_opts->id->sdom->search_bases); - if (ret != EOK) goto done; /* set krb realm */ - if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)) { + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_KRB5_REALM)) { realm = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM); value = talloc_strdup(tmpctx, realm); if (value == NULL) { @@ -267,22 +256,22 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, ret = ENOMEM; goto done; } - ret = dp_opt_set_string(ipa_opts->id->basic, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_KRB5_REALM, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_KRB5_REALM].opt_name, - dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)); + sdap_opts->basic[SDAP_KRB5_REALM].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_KRB5_REALM)); } - ret = sdap_set_sasl_options(ipa_opts->id, + ret = sdap_set_sasl_options(sdap_opts, dp_opt_get_string(ipa_opts->basic, IPA_HOSTNAME), - dp_opt_get_string(ipa_opts->id->basic, + dp_opt_get_string(sdap_opts->basic, SDAP_KRB5_REALM), - dp_opt_get_string(ipa_opts->id->basic, + dp_opt_get_string(sdap_opts->basic, SDAP_KRB5_KEYTAB)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the SASL-related options\n"); @@ -290,26 +279,85 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, } /* fix schema to IPAv1 for now */ - ipa_opts->id->schema_type = SDAP_SCHEMA_IPA_V1; + sdap_opts->schema_type = SDAP_SCHEMA_IPA_V1; + + ret = EOK; + +done: + talloc_zfree(tmpctx); + return ret; +} + +errno_t +ipa_set_search_bases(struct ipa_options *ipa_opts, + struct confdb_ctx *cdb, + const char *basedn, + const char *conf_path, + struct sdap_domain *sdap_dom) +{ + TALLOC_CTX *tmpctx; + errno_t ret; + struct sdap_domain *sdom; + char *value; + struct ldb_context *ldb; + struct sdap_options *sdap_opts; + bool server_mode; + int i; + + sdap_opts = ipa_opts->id; + + if (sdap_dom != NULL) { + sdom = sdap_dom; + } else { + sdom = ipa_opts->id->sdom; + } + + tmpctx = talloc_new(ipa_opts); + if (!tmpctx) { + return ENOMEM; + } + + ldb = sysdb_ctx_get_ldb(ipa_opts->id->dp->be_ctx->domain->sysdb); + + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE)) { + value = talloc_asprintf(tmpctx, "cn=accounts,%s", basedn); + if (!value) { + ret = ENOMEM; + goto done; + } + ret = dp_opt_set_string(sdap_opts->basic, + SDAP_SEARCH_BASE, value); + if (ret != EOK) { + goto done; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", + sdap_opts->basic[SDAP_SEARCH_BASE].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE)); + } + ret = sdap_parse_search_base(sdap_opts, ldb, sdap_opts->basic, + SDAP_SEARCH_BASE, + &sdom->search_bases); + if (ret != EOK) goto done; /* set user/group search bases if they are not specified */ - if (NULL == dp_opt_get_string(ipa_opts->id->basic, + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_USER_SEARCH_BASE)) { - ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE, - dp_opt_get_string(ipa_opts->id->basic, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_USER_SEARCH_BASE, + dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_USER_SEARCH_BASE].opt_name, - dp_opt_get_string(ipa_opts->id->basic, + sdap_opts->basic[SDAP_USER_SEARCH_BASE].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_USER_SEARCH_BASE)); } - ret = sdap_parse_search_base(ipa_opts->id, ldb, ipa_opts->id->basic, + ret = sdap_parse_search_base(sdap_opts, ldb, sdap_opts->basic, SDAP_USER_SEARCH_BASE, - &ipa_opts->id->sdom->user_search_bases); + &sdom->user_search_bases); if (ret != EOK) goto done; /* In server mode we need to search both cn=accounts,$SUFFIX and @@ -319,7 +367,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, server_mode = dp_opt_get_bool(ipa_opts->basic, IPA_SERVER_MODE); if (server_mode != false) { /* bases is not NULL at this point already */ - struct sdap_search_base **bases = ipa_opts->id->sdom->user_search_bases; + struct sdap_search_base **bases = sdom->user_search_bases; struct sdap_search_base *new_base = NULL; for (i = 0; bases[i] != NULL; i++) { @@ -345,8 +393,8 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - bases = talloc_realloc(ipa_opts->id, - ipa_opts->id->sdom->user_search_bases, + bases = talloc_realloc(sdap_opts, + sdom->user_search_bases, struct sdap_search_base*, i + 2); @@ -357,77 +405,77 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, bases[i] = new_base; bases[i+1] = NULL; - ipa_opts->id->sdom->user_search_bases = bases; + sdom->user_search_bases = bases; DEBUG(SSSDBG_TRACE_FUNC, "Option %s expanded to cover cn=trusts base\n", - ipa_opts->id->basic[SDAP_USER_SEARCH_BASE].opt_name); + sdap_opts->basic[SDAP_USER_SEARCH_BASE].opt_name); } } - if (NULL == dp_opt_get_string(ipa_opts->id->basic, + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_GROUP_SEARCH_BASE)) { - ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE, - dp_opt_get_string(ipa_opts->id->basic, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_GROUP_SEARCH_BASE, + dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_GROUP_SEARCH_BASE].opt_name, - dp_opt_get_string(ipa_opts->id->basic, + sdap_opts->basic[SDAP_GROUP_SEARCH_BASE].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_GROUP_SEARCH_BASE)); } - ret = sdap_parse_search_base(ipa_opts->id, ldb, ipa_opts->id->basic, + ret = sdap_parse_search_base(sdap_opts, ldb, sdap_opts->basic, SDAP_GROUP_SEARCH_BASE, - &ipa_opts->id->sdom->group_search_bases); + &sdom->group_search_bases); if (ret != EOK) goto done; - if (NULL == dp_opt_get_string(ipa_opts->id->basic, + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_NETGROUP_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ng,cn=alt,%s", basedn); if (!value) { ret = ENOMEM; goto done; } - ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_NETGROUP_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_NETGROUP_SEARCH_BASE].opt_name, - dp_opt_get_string(ipa_opts->id->basic, + sdap_opts->basic[SDAP_NETGROUP_SEARCH_BASE].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_NETGROUP_SEARCH_BASE)); } - ret = sdap_parse_search_base(ipa_opts->id, ldb, ipa_opts->id->basic, + ret = sdap_parse_search_base(sdap_opts, ldb, sdap_opts->basic, SDAP_NETGROUP_SEARCH_BASE, - &ipa_opts->id->sdom->netgroup_search_bases); + &sdom->netgroup_search_bases); if (ret != EOK) goto done; - if (NULL == dp_opt_get_string(ipa_opts->id->basic, + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_HOST_SEARCH_BASE)) { value = dp_opt_get_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE); if (!value) { - value = dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE); + value = dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE); } - ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_HOST_SEARCH_BASE, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_HOST_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_HOST_SEARCH_BASE].opt_name, + sdap_opts->basic[SDAP_HOST_SEARCH_BASE].opt_name, value); } - ret = sdap_parse_search_base(ipa_opts->id->basic, ldb, ipa_opts->id->basic, + ret = sdap_parse_search_base(sdap_opts->basic, ldb, sdap_opts->basic, SDAP_HOST_SEARCH_BASE, - &ipa_opts->id->sdom->host_search_bases); + &sdom->host_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, @@ -503,7 +551,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_SUBID_RANGES_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=subids,%s", - ipa_opts->id->sdom->search_bases[0]->basedn); + sdom->search_bases[0]->basedn); if (!value) { ret = ENOMEM; goto done; @@ -521,20 +569,20 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, } ret = ipa_parse_search_base(ipa_opts->basic, ldb, ipa_opts->basic, IPA_SUBID_RANGES_SEARCH_BASE, - &ipa_opts->id->sdom->subid_ranges_search_bases); + &sdom->subid_ranges_search_bases); if (ret != EOK) goto done; - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_subid_map, SDAP_OPTS_SUBID_RANGE, - &ipa_opts->id->subid_map); + &sdap_opts->subid_map); if (ret != EOK) { goto done; } #endif - value = dp_opt_get_string(ipa_opts->id->basic, SDAP_DEREF); + value = dp_opt_get_string(sdap_opts->basic, SDAP_DEREF); if (value != NULL) { ret = deref_string_to_val(value, &i); if (ret != EOK) { @@ -543,29 +591,29 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, } } - if (NULL == dp_opt_get_string(ipa_opts->id->basic, + if (NULL == dp_opt_get_string(sdap_opts->basic, SDAP_SERVICE_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ipservices,%s", - dp_opt_get_string(ipa_opts->id->basic, + dp_opt_get_string(sdap_opts->basic, SDAP_SEARCH_BASE)); if (!value) { ret = ENOMEM; goto done; } - ret = dp_opt_set_string(ipa_opts->id->basic, + ret = dp_opt_set_string(sdap_opts->basic, SDAP_SERVICE_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", - ipa_opts->id->basic[SDAP_SERVICE_SEARCH_BASE].opt_name, - dp_opt_get_string(ipa_opts->id->basic, + sdap_opts->basic[SDAP_SERVICE_SEARCH_BASE].opt_name, + dp_opt_get_string(sdap_opts->basic, SDAP_SERVICE_SEARCH_BASE)); } - ret = sdap_parse_search_base(ipa_opts->id, ldb, ipa_opts->id->basic, + ret = sdap_parse_search_base(sdap_opts, ldb, sdap_opts->basic, SDAP_SERVICE_SEARCH_BASE, - &ipa_opts->id->sdom->service_search_bases); + &sdom->service_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, @@ -660,61 +708,61 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, &ipa_opts->views_search_bases); if (ret != EOK) goto done; - ret = sdap_get_map(ipa_opts->id, cdb, conf_path, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_attr_map, SDAP_AT_GENERAL, - &ipa_opts->id->gen_map); + &sdap_opts->gen_map); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_user_map, SDAP_OPTS_USER, - &ipa_opts->id->user_map); + &sdap_opts->user_map); if (ret != EOK) { goto done; } - ret = sdap_extend_map_with_list(ipa_opts->id, ipa_opts->id, + ret = sdap_extend_map_with_list(sdap_opts, sdap_opts, SDAP_USER_EXTRA_ATTRS, - ipa_opts->id->user_map, + sdap_opts->user_map, SDAP_OPTS_USER, - &ipa_opts->id->user_map, - &ipa_opts->id->user_map_cnt); + &sdap_opts->user_map, + &sdap_opts->user_map_cnt); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_group_map, SDAP_OPTS_GROUP, - &ipa_opts->id->group_map); + &sdap_opts->group_map); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_netgroup_map, IPA_OPTS_NETGROUP, - &ipa_opts->id->netgroup_map); + &sdap_opts->netgroup_map); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_host_map, SDAP_OPTS_HOST, - &ipa_opts->id->host_map); + &sdap_opts->host_map); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_hostgroup_map, IPA_OPTS_HOSTGROUP, @@ -723,16 +771,16 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_service_map, SDAP_OPTS_SERVICES, - &ipa_opts->id->service_map); + &sdap_opts->service_map); if (ret != EOK) { goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_selinux_user_map, IPA_OPTS_SELINUX_USERMAP, @@ -741,7 +789,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_view_map, IPA_OPTS_VIEW, @@ -750,7 +798,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - ret = sdap_get_map(ipa_opts->id, + ret = sdap_get_map(sdap_opts, cdb, conf_path, ipa_override_map, IPA_OPTS_OVERRIDE, @@ -760,13 +808,9 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, } ret = EOK; - *_opts = ipa_opts->id; done: talloc_zfree(tmpctx); - if (ret != EOK) { - talloc_zfree(ipa_opts->id); - } return ret; } @@ -956,6 +1000,7 @@ static void ipa_resolve_callback(void *private_data, struct fo_server *server) } static errno_t _ipa_servers_init(struct be_ctx *ctx, + const char *fo_service, struct ipa_service *service, struct ipa_options *options, const char *servers, @@ -1003,14 +1048,15 @@ static errno_t _ipa_servers_init(struct be_ctx *ctx, } ipa_domain = dp_opt_get_string(options->basic, IPA_DOMAIN); - ret = be_fo_add_srv_server(ctx, "IPA", "ldap", ipa_domain, + ret = be_fo_add_srv_server(ctx, fo_service, "ldap", ipa_domain, BE_FO_PROTO_TCP, false, NULL); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } - DEBUG(SSSDBG_TRACE_FUNC, "Added service lookup for service IPA\n"); + DEBUG(SSSDBG_TRACE_FUNC, "Added service lookup for service [%s]\n", + fo_service); continue; } @@ -1021,7 +1067,7 @@ static errno_t _ipa_servers_init(struct be_ctx *ctx, goto done; } - ret = be_fo_add_server(ctx, "IPA", list[i], 0, NULL, primary); + ret = be_fo_add_server(ctx, fo_service, list[i], 0, NULL, primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; @@ -1036,17 +1082,19 @@ static errno_t _ipa_servers_init(struct be_ctx *ctx, } static inline errno_t -ipa_primary_servers_init(struct be_ctx *ctx, struct ipa_service *service, - struct ipa_options *options, const char *servers) +ipa_primary_servers_init(struct be_ctx *ctx, const char *fo_service, + struct ipa_service *service, struct ipa_options *options, + const char *servers) { - return _ipa_servers_init(ctx, service, options, servers, true); + return _ipa_servers_init(ctx, fo_service, service, options, servers, true); } static inline errno_t -ipa_backup_servers_init(struct be_ctx *ctx, struct ipa_service *service, - struct ipa_options *options, const char *servers) +ipa_backup_servers_init(struct be_ctx *ctx, const char *fo_service, + struct ipa_service *service, struct ipa_options *options, + const char *servers) { - return _ipa_servers_init(ctx, service, options, servers, false); + return _ipa_servers_init(ctx, fo_service, service, options, servers, false); } static int ipa_user_data_cmp(void *ud1, void *ud2) @@ -1057,12 +1105,13 @@ static int ipa_user_data_cmp(void *ud1, void *ud2) int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *primary_servers, const char *backup_servers, + const char *realm, + const char *ipa_service, struct ipa_options *options, struct ipa_service **_service) { TALLOC_CTX *tmp_ctx; struct ipa_service *service; - char *realm; int ret; tmp_ctx = talloc_new(NULL); @@ -1070,13 +1119,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, return ENOMEM; } - realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM); - if (!realm) { - DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n"); - ret = EINVAL; - goto done; - } - service = talloc_zero(tmp_ctx, struct ipa_service); if (!service) { ret = ENOMEM; @@ -1089,7 +1131,7 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, } service->krb5_service = krb5_service_new(service, ctx, - "IPA", realm, + ipa_service, realm, true, /* The configured value */ 0, /* will be set later when */ 0); /* the auth provider is set up */ @@ -1099,13 +1141,13 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, goto done; } - ret = be_fo_add_service(ctx, "IPA", ipa_user_data_cmp); + ret = be_fo_add_service(ctx, ipa_service, ipa_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); goto done; } - service->sdap->name = talloc_strdup(service, "IPA"); + service->sdap->name = talloc_strdup(service, ipa_service); if (!service->sdap->name) { ret = ENOMEM; goto done; @@ -1119,19 +1161,19 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, primary_servers = BE_SRV_IDENTIFIER; } - ret = ipa_primary_servers_init(ctx, service, options, primary_servers); + ret = ipa_primary_servers_init(ctx, ipa_service, service, options, primary_servers); if (ret != EOK) { goto done; } if (backup_servers) { - ret = ipa_backup_servers_init(ctx, service, options, backup_servers); + ret = ipa_backup_servers_init(ctx, ipa_service, service, options, backup_servers); if (ret != EOK) { goto done; } } - ret = be_fo_service_add_callback(memctx, ctx, "IPA", + ret = be_fo_service_add_callback(memctx, ctx, ipa_service, ipa_resolve_callback, service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add failover callback!\n"); @@ -1368,3 +1410,117 @@ errno_t ipa_get_host_attrs(struct dp_option *ipa_options, done: return ret; } + +struct ipa_options * +ipa_create_trust_options(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + struct data_provider *dp, + struct sss_domain_info *subdom, + const char *keytab, + const char *sasl_authid) +{ + struct ipa_options *ipa_options = NULL; + struct ipa_id_ctx *ipa_id_ctx = NULL; + struct sdap_id_ctx *sdap_id_ctx = NULL; + const char *ipa_servers; + const char *ipa_backup_servers; + const char *service_name; + errno_t ret; + + DEBUG(SSSDBG_TRACE_FUNC, "Trust is defined to domain '%s'\n", + subdom->name); + + ret = ipa_get_options(mem_ctx, cdb, subdom_conf_path, subdom, &ipa_options); + if (ret != EOK || ipa_options == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "ipa_get_options failed\n"); + goto done; + } else if (ipa_options == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "ipa_options is NULL\n"); + ret = ENOMEM; + goto done; + } + + ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER); + ipa_backup_servers = dp_opt_get_string(ipa_options->basic, IPA_BACKUP_SERVER); + + service_name = talloc_asprintf(ipa_options, "sd_%s", subdom->name); + if (service_name == NULL) { + ret = ENOMEM; + goto done; + } + + ret = ipa_service_init(ipa_options, be_ctx, ipa_servers, + ipa_backup_servers, subdom->realm, + service_name, ipa_options, + &ipa_options->service); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init IPA service [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + /* Set IPA SDAP options */ + ipa_id_ctx = talloc_zero(mem_ctx, struct ipa_id_ctx); + if (ipa_id_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + sdap_id_ctx = sdap_id_ctx_new(mem_ctx, be_ctx, ipa_options->service->sdap); + if (sdap_id_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + ipa_id_ctx->ipa_options = ipa_options; + ipa_id_ctx->sdap_id_ctx = sdap_id_ctx; + ipa_options->id_ctx = ipa_id_ctx; + + ret = ipa_get_id_options(ipa_options, + cdb, + subdom_conf_path, + dp, + false, + &ipa_options->id); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "ipa_get_id_options failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (keytab != NULL) { + ret = dp_opt_set_string(ipa_options->id->basic, SDAP_KRB5_KEYTAB, + keytab); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set trust keytab\n"); + goto done; + } + } + + /* Set IPA KRB5 realm */ + ret = dp_opt_set_string(ipa_options->id->basic, + IPA_KRB5_REALM, subdom->realm); + + /* Set SDAP_SASL_AUTHID to the trust principal */ + ret = dp_opt_set_string(ipa_options->id->basic, + SDAP_SASL_AUTHID, sasl_authid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n"); + goto done; + } + +done: + if (ret != EOK) { + if (ipa_options != NULL) { + talloc_free(ipa_options); + } + if (ipa_id_ctx != NULL) { + talloc_free(ipa_options); + } + return NULL; + } + + return ipa_options; +} diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 82b9622bde..d8bf2d9739 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -255,6 +255,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct data_provider *dp, + bool sdom_add, struct sdap_options **_opts); int ipa_get_auth_options(struct ipa_options *ipa_opts, @@ -271,6 +272,15 @@ int ipa_get_autofs_options(struct ipa_options *ipa_opts, errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx, struct ipa_options *ctx); +errno_t ipa_set_sdap_options(struct ipa_options *ipa_opts, + struct sdap_options *sdap_opts); + +errno_t ipa_set_search_bases(struct ipa_options *ipa_opts, + struct confdb_ctx *cdb, + const char *basedn, + const char *conf_path, + struct sdap_domain *sdap_dom); + errno_t ipa_hostid_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, @@ -284,6 +294,8 @@ errno_t ipa_autofs_init(TALLOC_CTX *mem_ctx, int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *primary_servers, const char *backup_servers, + const char *realm, + const char *ipa_service, struct ipa_options *options, struct ipa_service **_service); @@ -323,4 +335,15 @@ errno_t ipa_get_host_attrs(struct dp_option *ipa_options, errno_t ipa_refresh_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); + +struct ipa_options * +ipa_create_trust_options(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + struct data_provider *dp, + struct sss_domain_info *subdom, + const char *keytab, + const char *sasl_authid); + #endif /* _IPA_COMMON_H_ */ diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c index fcac56ce28..a270c7dd4f 100644 --- a/src/providers/ipa/ipa_id.c +++ b/src/providers/ipa/ipa_id.c @@ -334,14 +334,14 @@ static int ipa_initgr_get_overrides_step(struct tevent_req *req) DEBUG(SSSDBG_TRACE_LIBS, "Fetching group %s: %s\n", dn, ipa_uuid); - subreq = ipa_get_ad_override_send(state, state->ev, + subreq = ipa_get_trusted_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, state->realm, state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, @@ -361,7 +361,7 @@ static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq) int ret; struct sysdb_attrs *override_attrs = NULL; - ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state, + ret = ipa_get_trusted_override_recv(subreq, &state->dp_error, state, &override_attrs); talloc_zfree(subreq); if (ret != EOK) { @@ -605,11 +605,11 @@ static void ipa_id_get_account_info_connected(struct tevent_req *subreq) goto fail; } - subreq = ipa_get_ad_override_send(state, state->ev, state->ctx, - state->ipa_ctx->ipa_options, state->realm, - state->ipa_ctx->view_name, state->ar); + subreq = ipa_get_trusted_override_send(state, state->ev, state->ctx, + state->ipa_ctx->ipa_options, state->realm, + state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto fail; } @@ -636,8 +636,8 @@ static void ipa_id_get_account_info_got_override(struct tevent_req *subreq) char *anchor_domain; char *ipa_uuid; - ret = ipa_get_ad_override_recv(subreq, &dp_error, state, - &state->override_attrs); + ret = ipa_get_trusted_override_recv(subreq, &dp_error, state, + &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { @@ -903,14 +903,14 @@ static int ipa_id_get_account_info_post_proc_step(struct tevent_req *req) goto done; } - subreq = ipa_get_ad_override_send(state, state->ev, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->ipa_options, - state->realm, - state->ipa_ctx->view_name, - state->ar); + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + state->realm, + state->ipa_ctx->view_name, + state->ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto done; } @@ -987,8 +987,8 @@ static void ipa_id_get_account_info_done(struct tevent_req *subreq) const char *class; enum sysdb_member_type type; - ret = ipa_get_ad_override_recv(subreq, &dp_error, state, - &state->override_attrs); + ret = ipa_get_trusted_override_recv(subreq, &dp_error, state, + &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h index c18e709b80..2c64113029 100644 --- a/src/providers/ipa/ipa_id.h +++ b/src/providers/ipa/ipa_id.h @@ -98,17 +98,17 @@ errno_t get_dp_id_data_for_user_name(TALLOC_CTX *mem_ctx, const char *domain_name, struct dp_id_data **_ar); -struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_id_ctx *sdap_id_ctx, - struct ipa_options *ipa_options, - const char *ipa_realm, - const char *view_name, - struct dp_id_data *ar); - -errno_t ipa_get_ad_override_recv(struct tevent_req *req, int *dp_error_out, - TALLOC_CTX *mem_ctx, - struct sysdb_attrs **override_attrs); +struct tevent_req *ipa_get_trusted_override_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sdap_id_ctx *sdap_id_ctx, + struct ipa_options *ipa_options, + const char *ipa_realm, + const char *view_name, + struct dp_id_data *ar); + +errno_t ipa_get_trusted_override_recv(struct tevent_req *req, int *dp_error_out, + TALLOC_CTX *mem_ctx, + struct sysdb_attrs **override_attrs); struct tevent_req *ipa_subdomain_account_send(TALLOC_CTX *memctx, struct tevent_context *ev, diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c index 5ea92ec98b..f7a6a74a5a 100644 --- a/src/providers/ipa/ipa_init.c +++ b/src/providers/ipa/ipa_init.c @@ -111,6 +111,7 @@ static errno_t ipa_init_options(TALLOC_CTX *mem_ctx, struct ipa_options *ipa_options; const char *ipa_servers; const char *ipa_backup_servers; + const char *realm; errno_t ret; ret = ipa_get_options(mem_ctx, be_ctx->cdb, be_ctx->conf_path, @@ -121,9 +122,10 @@ static errno_t ipa_init_options(TALLOC_CTX *mem_ctx, ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER); ipa_backup_servers = dp_opt_get_string(ipa_options->basic, IPA_BACKUP_SERVER); + realm = dp_opt_get_string(ipa_options->basic, IPA_KRB5_REALM); ret = ipa_service_init(ipa_options, be_ctx, ipa_servers, - ipa_backup_servers, ipa_options, + ipa_backup_servers, realm, "IPA", ipa_options, &ipa_options->service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init IPA service [%d]: %s\n", @@ -143,6 +145,7 @@ static errno_t ipa_init_id_ctx(TALLOC_CTX *mem_ctx, { struct ipa_id_ctx *ipa_id_ctx = NULL; struct sdap_id_ctx *sdap_id_ctx = NULL; + char *basedn; errno_t ret; ipa_id_ctx = talloc_zero(mem_ctx, struct ipa_id_ctx); @@ -165,11 +168,35 @@ static errno_t ipa_init_id_ctx(TALLOC_CTX *mem_ctx, be_ctx->cdb, be_ctx->conf_path, be_ctx->provider, + true, &sdap_id_ctx->opts); if (ret != EOK) { goto done; } + ret = ipa_set_sdap_options(ipa_options, ipa_options->id); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set IPA sdap options\n"); + goto done; + } + + ret = domain_to_basedn(mem_ctx, + dp_opt_get_string(ipa_options->basic, IPA_KRB5_REALM), + &basedn); + if (ret != EOK) { + goto done; + } + + ret = ipa_set_search_bases(ipa_options, + be_ctx->cdb, + basedn, + be_ctx->conf_path, + NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set search bases\n"); + goto done; + } + *_ipa_id_ctx = ipa_id_ctx; ret = EOK; diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c index ec944d91f4..bcc7aae736 100644 --- a/src/providers/ipa/ipa_s2n_exop.c +++ b/src/providers/ipa/ipa_s2n_exop.c @@ -1454,6 +1454,9 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq) struct berval *retdata = NULL; const char *sid_str; struct dp_id_data *ar; + struct req_input *req_inp; + + req_inp = &state->req_input; ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata); talloc_zfree(subreq); @@ -1488,11 +1491,24 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq) ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, + DEBUG(SSSDBG_OP_FAILURE, "Object [%s] has no SID, please check the " - "ipaNTSecurityIdentifier attribute on the server-side", + "ipaNTSecurityIdentifier attribute on the server-side\n", state->attrs->a.name); - goto fail; + /* In IPA IPA trust case, the IPA user private group will not contain a + * SID, so ignore processing it and continue */ + if (req_inp->type == REQ_INP_NAME && + strcasecmp(state->attrs->domain_name, state->dom->name) == 0 && + (state->attrs->response_type == RESP_GROUP || + state->attrs->response_type == RESP_GROUP_MEMBERS) && + /* user private group name == username */ + strncasecmp(req_inp->inp.name, state->attrs->a.name, strlen(req_inp->inp.name)) == 0) { + DEBUG(SSSDBG_TRACE_FUNC, "Skipping UPG object [%s]\n", state->attrs->a.group.gr_name); + tevent_req_done(req); + return; + } else { + goto fail; + } } ret = get_dp_id_data_for_sid(state, sid_str, state->obj_domain->name, &ar); @@ -1501,15 +1517,15 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq) goto fail; } - subreq = ipa_get_ad_override_send(state, state->ev, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->ipa_options, - dp_opt_get_string(state->ipa_ctx->ipa_options->basic, - IPA_KRB5_REALM), - state->ipa_ctx->view_name, - ar); + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + dp_opt_get_string(state->ipa_ctx->ipa_options->basic, + IPA_KRB5_REALM), + state->ipa_ctx->view_name, + ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto fail; } @@ -1566,7 +1582,7 @@ static void ipa_s2n_get_list_get_override_done(struct tevent_req *subreq) struct ipa_s2n_get_list_state *state = tevent_req_data(req, struct ipa_s2n_get_list_state); - ret = ipa_get_ad_override_recv(subreq, NULL, state, &state->override_attrs); + ret = ipa_get_trusted_override_recv(subreq, NULL, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); @@ -2318,15 +2334,15 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq) goto done; } - subreq = ipa_get_ad_override_send(state, state->ev, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->ipa_options, - dp_opt_get_string(state->ipa_ctx->ipa_options->basic, - IPA_KRB5_REALM), - state->ipa_ctx->view_name, - ar); + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + dp_opt_get_string(state->ipa_ctx->ipa_options->basic, + IPA_KRB5_REALM), + state->ipa_ctx->view_name, + ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto done; } @@ -2468,7 +2484,6 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, time_t now; struct sss_nss_homedir_ctx homedir_ctx; char *name = NULL; - char *upn = NULL; gid_t gid; gid_t orig_gid = 0; TALLOC_CTX *tmp_ctx; @@ -2543,22 +2558,6 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } - - ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_UPN, &tmp_str); - if (ret == EOK) { - upn = talloc_strdup(tmp_ctx, tmp_str); - if (upn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); - ret = ENOMEM; - goto done; - } - DEBUG(SSSDBG_TRACE_ALL, "Found original AD upn [%s].\n", upn); - } else if (ret == ENOENT) { - upn = NULL; - } else { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); - goto done; - } } if (strcmp(dom->name, attrs->domain_name) != 0) { @@ -2979,15 +2978,15 @@ static void ipa_s2n_get_list_done(struct tevent_req *subreq) if (state->override_attrs == NULL && !is_default_view(state->ipa_ctx->view_name)) { - subreq = ipa_get_ad_override_send(state, state->ev, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->ipa_options, - dp_opt_get_string(state->ipa_ctx->ipa_options->basic, - IPA_KRB5_REALM), - state->ipa_ctx->view_name, - ar); + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + dp_opt_get_string(state->ipa_ctx->ipa_options->basic, + IPA_KRB5_REALM), + state->ipa_ctx->view_name, + ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto fail; } @@ -3023,7 +3022,7 @@ static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq) struct ipa_s2n_get_user_state); struct sysdb_attrs *override_attrs = NULL; - ret = ipa_get_ad_override_recv(subreq, NULL, state, &override_attrs); + ret = ipa_get_trusted_override_recv(subreq, NULL, state, &override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 075f6f4706..f33ad786cf 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -378,6 +378,22 @@ static errno_t ipa_get_sd_trust_direction(struct sysdb_attrs *sd, } } +static errno_t ipa_get_sd_trust_type(struct sysdb_attrs *sd, + struct ipa_id_ctx *id_ctx, + struct ldb_context *ldb_ctx, + uint32_t *_type) +{ + if (id_ctx->server_mode != NULL) { + return ipa_server_get_trust_type(sd, ldb_ctx, _type); + } else { + /* Clients do not have access to the trust objects's trust type + * and don't generally care + */ + *_type = 0; + return EOK; + } +} + static errno_t ipa_subdom_store(struct sss_domain_info *parent, struct ipa_id_ctx *id_ctx, struct sdap_idmap_ctx *sdap_idmap_ctx, @@ -395,6 +411,7 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, enum sss_domain_mpg_mode mpg_mode; bool enumerate; uint32_t direction; + uint32_t type; struct ldb_message_element *alternative_domain_suffixes = NULL; struct range_info *range; const char *forest_id; @@ -460,9 +477,20 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, goto done; } + ret = ipa_get_sd_trust_type(attrs, id_ctx, + sysdb_ctx_get_ldb(parent->sysdb), + &type); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "ipa_get_sd_trust_type failed: %d\n", ret); + goto done; + } + if (id_ctx->server_mode != NULL) { DEBUG(SSSDBG_FUNC_DATA, - "Trust type of [%s]: %s\n", name, ipa_trust_dir2str(direction)); + "Trust direction of [%s]: %s\n", name, ipa_trust_dir2str(direction)); + DEBUG(SSSDBG_FUNC_DATA, + "Trust type of [%s]: %s\n", name, ipa_trust_type2str(type)); } /* First see if there is an ID range for the domain. */ @@ -505,7 +533,7 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, ret = sysdb_subdomain_store(parent->sysdb, name, realm, flat, dns, id, mpg_mode, enumerate, forest, - direction, alternative_domain_suffixes); + direction, type, alternative_domain_suffixes); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; @@ -1369,7 +1397,8 @@ ipa_subdomains_slave_send(TALLOC_CTX *mem_ctx, errno_t ret; const char *attrs[] = { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, IPA_TRUST_DIRECTION, IPA_ADDITIONAL_SUFFIXES, - IPA_SID_BLACKLIST_INCOMING, NULL }; + IPA_SID_BLACKLIST_INCOMING, IPA_PARTNER_TRUST_TYPE, + NULL }; req = tevent_req_create(mem_ctx, &state, struct ipa_subdomains_slave_state); @@ -3170,9 +3199,9 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, /* Ignore this error and try to discover the subdomains later */ } - ret = ipa_ad_subdom_init(be_ctx, ipa_id_ctx); + ret = ipa_trusted_subdom_init(be_ctx, ipa_id_ctx); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "ipa_ad_subdom_init() failed.\n"); + DEBUG(SSSDBG_CRIT_FAILURE, "ipa_trusted_subdom_init() failed.\n"); return ret; } diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h index 1411d0cd27..a656f10153 100644 --- a/src/providers/ipa/ipa_subdomains.h +++ b/src/providers/ipa/ipa_subdomains.h @@ -69,11 +69,21 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, struct dp_method *dp_methods); /* The following are used in server mode only */ -struct ipa_ad_server_ctx { +enum ipa_trust_type { + IPA_TRUST_UNKNOWN = 0, + IPA_TRUST_AD = 1, + IPA_TRUST_IPA = 2, +}; + +struct ipa_subdom_server_ctx { struct sss_domain_info *dom; - struct ad_id_ctx *ad_id_ctx; + enum ipa_trust_type type; + union { + struct ad_id_ctx *ad_id_ctx; + struct ipa_id_ctx *ipa_id_ctx; + } id_ctx; - struct ipa_ad_server_ctx *next, *prev; + struct ipa_subdom_server_ctx *next, *prev; }; /* Can be used to set up trusted subdomain, for example fetch @@ -101,17 +111,23 @@ 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, +int ipa_trusted_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd, struct ldb_context *ldb_ctx, uint32_t *_direction); +errno_t ipa_server_get_trust_type(struct sysdb_attrs *sd, + struct ldb_context *ldb_ctx, + uint32_t *_type); + const char *ipa_trust_dir2str(uint32_t direction); +const char *ipa_trust_type2str(uint32_t type); /* Utilities */ #define IPA_TRUST_DIRECTION "ipaNTTrustDirection" +#define IPA_PARTNER_TRUST_TYPE "ipaPartnerTrustType" struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, @@ -127,14 +143,14 @@ struct ipa_server_mode_ctx { const char *realm; const char *hostname; - struct ipa_ad_server_ctx *trusts; + struct ipa_subdom_server_ctx *trusts; struct ipa_ext_groups *ext_groups; uid_t kt_owner_uid; uid_t kt_owner_gid; }; -int ipa_ad_subdom_init(struct be_ctx *be_ctx, +int ipa_trusted_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); enum req_input_type { @@ -154,15 +170,15 @@ struct req_input { } inp; }; -struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct dp_id_data *ar, - struct ipa_server_mode_ctx *server_mode, - struct sss_domain_info *user_dom, - struct sdap_id_ctx *sdap_id_ctx, - const char *domain); +struct tevent_req *ipa_get_trusted_memberships_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dp_id_data *ar, + struct ipa_server_mode_ctx *server_mode, + struct sss_domain_info *user_dom, + struct sdap_id_ctx *sdap_id_ctx, + const char *domain); -errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out); +errno_t ipa_get_trusted_memberships_recv(struct tevent_req *req, int *dp_error_out); struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c index f4f84749a2..ba3fb39538 100644 --- a/src/providers/ipa/ipa_subdomains_ext_groups.c +++ b/src/providers/ipa/ipa_subdomains_ext_groups.c @@ -387,16 +387,16 @@ static errno_t add_ad_user_to_cached_groups(struct ldb_dn *user_dn, return ret; } -static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sdap_id_ctx *sdap_id_ctx, - struct ldb_dn *user_dn, - struct sss_domain_info *user_dom, - char **groups, - struct sss_domain_info *group_dom); -static void ipa_add_ad_memberships_done(struct tevent_req *subreq); - -struct get_ad_membership_state { +static struct tevent_req *ipa_add_trusted_memberships_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sdap_id_ctx *sdap_id_ctx, + struct ldb_dn *user_dn, + struct sss_domain_info *user_dom, + char **groups, + struct sss_domain_info *group_dom); +static void ipa_add_trusted_memberships_done(struct tevent_req *subreq); + +struct get_trusted_membership_state { struct tevent_context *ev; struct ipa_server_mode_ctx *server_mode; struct sdap_id_op *sdap_op; @@ -411,26 +411,26 @@ struct get_ad_membership_state { struct sysdb_attrs **reply; }; -static void ipa_get_ad_memberships_connect_done(struct tevent_req *subreq); +static void ipa_get_trusted_memberships_connect_done(struct tevent_req *subreq); static void ipa_get_ext_groups_done(struct tevent_req *subreq); static errno_t ipa_add_ext_groups_step(struct tevent_req *req); -static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req, - int *dp_error_out); - -struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct dp_id_data *ar, - struct ipa_server_mode_ctx *server_mode, - struct sss_domain_info *user_dom, - struct sdap_id_ctx *sdap_id_ctx, - const char *domain) +static errno_t ipa_add_trusted_memberships_recv(struct tevent_req *req, + int *dp_error_out); + +struct tevent_req *ipa_get_trusted_memberships_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dp_id_data *ar, + struct ipa_server_mode_ctx *server_mode, + struct sss_domain_info *user_dom, + struct sdap_id_ctx *sdap_id_ctx, + const char *domain) { int ret; struct tevent_req *req; struct tevent_req *subreq; - struct get_ad_membership_state *state; + struct get_trusted_membership_state *state; - req = tevent_req_create(mem_ctx, &state, struct get_ad_membership_state); + req = tevent_req_create(mem_ctx, &state, struct get_trusted_membership_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; @@ -498,7 +498,7 @@ struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, goto done; } - tevent_req_set_callback(subreq, ipa_get_ad_memberships_connect_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_memberships_connect_done, req); return req; @@ -515,12 +515,12 @@ struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, return req; } -static void ipa_get_ad_memberships_connect_done(struct tevent_req *subreq) +static void ipa_get_trusted_memberships_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct get_ad_membership_state *state = tevent_req_data(req, - struct get_ad_membership_state); + struct get_trusted_membership_state *state = tevent_req_data(req, + struct get_trusted_membership_state); int ret; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); @@ -564,8 +564,8 @@ static void ipa_get_ext_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct get_ad_membership_state *state = tevent_req_data(req, - struct get_ad_membership_state); + struct get_trusted_membership_state *state = tevent_req_data(req, + struct get_trusted_membership_state); int ret; hash_table_t *ext_group_hash; @@ -617,8 +617,8 @@ static void ipa_get_ext_groups_done(struct tevent_req *subreq) static errno_t ipa_add_ext_groups_step(struct tevent_req *req) { - struct get_ad_membership_state *state = tevent_req_data(req, - struct get_ad_membership_state); + struct get_trusted_membership_state *state = tevent_req_data(req, + struct get_trusted_membership_state); struct ldb_dn *user_dn; int ret; char **groups = NULL; @@ -638,16 +638,16 @@ static errno_t ipa_add_ext_groups_step(struct tevent_req *req) return EOK; } - subreq = ipa_add_ad_memberships_send(state, state->ev, state->sdap_id_ctx, - user_dn, state->user_dom, groups, - state->sdap_id_ctx->be->domain); + subreq = ipa_add_trusted_memberships_send(state, state->ev, state->sdap_id_ctx, + user_dn, state->user_dom, groups, + state->sdap_id_ctx->be->domain); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ad_memberships_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_add_trusted_memberships_send failed.\n"); ret = ENOMEM; goto fail; } - tevent_req_set_callback(subreq, ipa_add_ad_memberships_done, req); + tevent_req_set_callback(subreq, ipa_add_trusted_memberships_done, req); return EAGAIN; fail: @@ -655,15 +655,15 @@ static errno_t ipa_add_ext_groups_step(struct tevent_req *req) return ret; } -static void ipa_add_ad_memberships_done(struct tevent_req *subreq) +static void ipa_add_trusted_memberships_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct get_ad_membership_state *state = tevent_req_data(req, - struct get_ad_membership_state); + struct get_trusted_membership_state *state = tevent_req_data(req, + struct get_trusted_membership_state); int ret; - ret = ipa_add_ad_memberships_recv(subreq, &state->dp_error); + ret = ipa_add_trusted_memberships_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ad_memberships request failed.\n"); @@ -676,10 +676,10 @@ static void ipa_add_ad_memberships_done(struct tevent_req *subreq) return; } -errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out) +errno_t ipa_get_trusted_memberships_recv(struct tevent_req *req, int *dp_error_out) { - struct get_ad_membership_state *state = tevent_req_data(req, - struct get_ad_membership_state); + struct get_trusted_membership_state *state = tevent_req_data(req, + struct get_trusted_membership_state); TEVENT_REQ_RETURN_ON_ERROR(req); @@ -690,7 +690,7 @@ errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out) return EOK; } -struct add_ad_membership_state { +struct add_trusted_membership_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; struct sdap_id_op *sdap_op; @@ -703,10 +703,10 @@ struct add_ad_membership_state { struct sdap_domain *group_sdom; }; -static void ipa_add_ad_memberships_connect_done(struct tevent_req *subreq); -static void ipa_add_ad_memberships_get_next(struct tevent_req *req); -static void ipa_add_ad_memberships_get_group_done(struct tevent_req *subreq); -static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, +static void ipa_add_trusted_memberships_connect_done(struct tevent_req *subreq); +static void ipa_add_trusted_memberships_get_next(struct tevent_req *req); +static void ipa_add_trusted_memberships_get_group_done(struct tevent_req *subreq); +static struct tevent_req *ipa_add_trusted_memberships_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ldb_dn *user_dn, @@ -717,10 +717,10 @@ static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, int ret; struct tevent_req *req; struct tevent_req *subreq; - struct add_ad_membership_state *state; + struct add_trusted_membership_state *state; bool missing_groups = false; - req = tevent_req_create(mem_ctx, &state, struct add_ad_membership_state); + req = tevent_req_create(mem_ctx, &state, struct add_trusted_membership_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; @@ -768,7 +768,7 @@ static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, goto done; } - tevent_req_set_callback(subreq, ipa_add_ad_memberships_connect_done, req); + tevent_req_set_callback(subreq, ipa_add_trusted_memberships_connect_done, req); return req; @@ -785,12 +785,12 @@ static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, return req; } -static void ipa_add_ad_memberships_connect_done(struct tevent_req *subreq) +static void ipa_add_trusted_memberships_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct add_ad_membership_state *state = tevent_req_data(req, - struct add_ad_membership_state); + struct add_trusted_membership_state *state = tevent_req_data(req, + struct add_trusted_membership_state); int ret; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); @@ -810,13 +810,13 @@ static void ipa_add_ad_memberships_connect_done(struct tevent_req *subreq) } state->iter = 0; - ipa_add_ad_memberships_get_next(req); + ipa_add_trusted_memberships_get_next(req); } -static void ipa_add_ad_memberships_get_next(struct tevent_req *req) +static void ipa_add_trusted_memberships_get_next(struct tevent_req *req) { - struct add_ad_membership_state *state = tevent_req_data(req, - struct add_ad_membership_state); + struct add_trusted_membership_state *state = tevent_req_data(req, + struct add_trusted_membership_state); struct tevent_req *subreq; struct ldb_dn *group_dn; int ret; @@ -890,19 +890,19 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req) goto fail; } - tevent_req_set_callback(subreq, ipa_add_ad_memberships_get_group_done, req); + tevent_req_set_callback(subreq, ipa_add_trusted_memberships_get_group_done, req); return; fail: tevent_req_error(req, ret); } -static void ipa_add_ad_memberships_get_group_done(struct tevent_req *subreq) +static void ipa_add_trusted_memberships_get_group_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct add_ad_membership_state *state = tevent_req_data(req, - struct add_ad_membership_state); + struct add_trusted_membership_state *state = tevent_req_data(req, + struct add_trusted_membership_state); int ret; ret = groups_get_recv(subreq, &state->dp_error, NULL); @@ -916,14 +916,14 @@ static void ipa_add_ad_memberships_get_group_done(struct tevent_req *subreq) } state->iter++; - ipa_add_ad_memberships_get_next(req); + ipa_add_trusted_memberships_get_next(req); } -static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req, +static errno_t ipa_add_trusted_memberships_recv(struct tevent_req *req, int *dp_error_out) { - struct add_ad_membership_state *state = tevent_req_data(req, - struct add_ad_membership_state); + struct add_trusted_membership_state *state = tevent_req_data(req, + struct add_trusted_membership_state); TEVENT_REQ_RETURN_ON_ERROR(req); diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c index 8e2e0c06c4..f7c7663431 100644 --- a/src/providers/ipa/ipa_subdomains_id.c +++ b/src/providers/ipa/ipa_subdomains_id.c @@ -23,11 +23,13 @@ */ #include +#include #include "util/util.h" #include "util/sss_nss.h" #include "util/strtonum.h" #include "db/sysdb.h" +#include "db/sysdb_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_async_ad.h" @@ -37,13 +39,13 @@ #include "providers/ipa/ipa_subdomains.h" static struct tevent_req * -ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct ipa_id_ctx *ipa_ctx, - struct sysdb_attrs *override_attrs, - struct dp_id_data *ar); +ipa_srv_acct_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, + struct sysdb_attrs *override_attrs, + struct dp_id_data *ar); static errno_t -ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out); +ipa_srv_acct_recv(struct tevent_req *req, int *dp_error_out); struct ipa_subdomain_account_state { struct tevent_context *ev; @@ -169,13 +171,13 @@ static void ipa_subdomain_account_connected(struct tevent_req *subreq) goto fail; } - subreq = ipa_get_ad_override_send(state, state->ev, state->ctx, + subreq = ipa_get_trusted_override_send(state, state->ev, state->ctx, state->ipa_ctx->ipa_options, dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM), state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto fail; } @@ -204,8 +206,8 @@ static void ipa_subdomain_account_got_override(struct tevent_req *subreq) const char *anchor = NULL; struct dp_id_data *ar; - ret = ipa_get_ad_override_recv(subreq, &dp_error, state, - &state->override_attrs); + ret = ipa_get_trusted_override_recv(subreq, &dp_error, state, + &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->op, ret, &dp_error); @@ -337,8 +339,8 @@ static errno_t ipa_subdomain_account_get_original_step(struct tevent_req *req, struct tevent_req *subreq; if (state->ipa_server_mode) { - subreq = ipa_srv_ad_acct_send(state, state->ev, state->ipa_ctx, - state->override_attrs, ar); + subreq = ipa_srv_acct_send(state, state->ev, state->ipa_ctx, + state->override_attrs, ar); } else { subreq = ipa_get_subdom_acct_send(state, state->ev, state->ipa_ctx, state->override_attrs, ar); @@ -367,7 +369,7 @@ static void ipa_subdomain_account_done(struct tevent_req *subreq) struct sss_domain_info *object_dom; if (state->ipa_server_mode) { - ret = ipa_srv_ad_acct_recv(subreq, &dp_error); + ret = ipa_srv_acct_recv(subreq, &dp_error); } else { ret = ipa_get_subdom_acct_recv(subreq, &dp_error); } @@ -783,8 +785,8 @@ ipa_ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ipa_id_ctx *ipa_ctx, return clist; } -/* IPA lookup for server mode. Directly to AD. */ -struct ipa_get_ad_acct_state { +/* IPA lookup for server mode. AD or IPA subdomain */ +struct ipa_get_acct_state { int dp_error; struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; @@ -793,32 +795,37 @@ struct ipa_get_ad_acct_state { char *object_sid; struct sysdb_attrs *override_attrs; struct ldb_message *obj_msg; + enum ipa_trust_type type; }; -static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq); -static void ipa_get_ad_override_done(struct tevent_req *subreq); -static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req); -static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req); +static void ipa_get_trusted_acct_part_done(struct tevent_req *subreq); +static void ipa_get_trusted_override_done(struct tevent_req *subreq); +static errno_t ipa_get_trusted_apply_override_step(struct tevent_req *req); +static errno_t ipa_get_trusted_ipa_membership_step(struct tevent_req *req); static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq); -static void ipa_get_ad_acct_done(struct tevent_req *subreq); +static void ipa_get_trusted_acct_done(struct tevent_req *subreq); +static enum ipa_trust_type +ipa_get_trust_type(struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *dom); static struct tevent_req * ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sysdb_attrs *override_attrs, - struct dp_id_data *ar) + struct dp_id_data *ar, + enum ipa_trust_type type) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; - struct ipa_get_ad_acct_state *state; + struct ipa_get_acct_state *state; struct sdap_domain *sdom; struct sdap_id_conn_ctx **clist; struct sdap_id_ctx *sdap_id_ctx; struct ad_id_ctx *ad_id_ctx; - req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_acct_state); + req = tevent_req_create(mem_ctx, &state, struct ipa_get_acct_state); if (req == NULL) return NULL; state->dp_error = -1; @@ -826,6 +833,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, state->ipa_ctx = ipa_ctx; state->ar = ar; state->obj_msg = NULL; + state->type = type; state->override_attrs = override_attrs; /* This can only be a subdomain request, verify subdomain */ @@ -879,7 +887,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, ret = ENOMEM; goto fail; } - tevent_req_set_callback(subreq, ipa_get_ad_acct_ad_part_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_acct_part_done, req); return req; fail: @@ -893,15 +901,111 @@ static struct ad_id_ctx * ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *dom) { - struct ipa_ad_server_ctx *iter; + struct ipa_subdom_server_ctx *iter; + + DLIST_FOR_EACH(iter, ipa_ctx->server_mode->trusts) { + if (iter->dom == dom) break; + } + + return (iter) ? iter->id_ctx.ad_id_ctx : NULL; +} + +static struct ipa_id_ctx * +ipa_get_ipa_id_ctx(struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *dom) +{ + struct ipa_subdom_server_ctx *iter; + + DLIST_FOR_EACH(iter, ipa_ctx->server_mode->trusts) { + if (iter->dom == dom) break; + } + + return (iter) ? iter->id_ctx.ipa_id_ctx : NULL; +} + +static enum ipa_trust_type +ipa_get_trust_type(struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *dom) +{ + struct ipa_subdom_server_ctx *iter; DLIST_FOR_EACH(iter, ipa_ctx->server_mode->trusts) { if (iter->dom == dom) break; } - return (iter) ? iter->ad_id_ctx : NULL; + return iter->type; +} + +static struct ipa_id_ctx *ipa_get_ipa_id_ctx(struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *dom); + +static struct tevent_req * +ipa_get_ipa_acct_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, + struct sysdb_attrs *override_attrs, + struct dp_id_data *ar, + enum ipa_trust_type type) +{ + errno_t ret; + struct tevent_req *req; + struct tevent_req *subreq; + struct ipa_get_acct_state *state; + struct sdap_domain *sdom; + struct sdap_id_ctx *sdap_id_ctx; + struct ipa_id_ctx *ipa_id_ctx; + + req = tevent_req_create(mem_ctx, &state, struct ipa_get_acct_state); + if (req == NULL) return NULL; + + state->dp_error = -1; + state->ev = ev; + state->ipa_ctx = ipa_ctx; + state->ar = ar; + state->obj_msg = NULL; + state->type = type; + state->override_attrs = override_attrs; + + /* This can only be a subdomain request, verify subdomain */ + state->obj_dom = find_domain_by_name(ipa_ctx->sdap_id_ctx->be->domain, + ar->domain, true); + if (state->obj_dom == NULL) { + ret = EINVAL; + goto fail; + } + + /* Let's see if this subdomain has a ipa_id_ctx */ + ipa_id_ctx = ipa_get_ipa_id_ctx(ipa_ctx, state->obj_dom); + if (ipa_id_ctx == NULL) { + ret = EINVAL; + goto fail; + } + sdap_id_ctx = ipa_id_ctx->sdap_id_ctx; + + /* Now we already need ipa_id_ctx in particular sdap_id_conn_ctx */ + sdom = sdap_domain_get(sdap_id_ctx->opts, state->obj_dom); + if (sdom == NULL) { + ret = EIO; + goto fail; + } + + ipa_id_ctx->sdap_id_ctx->opts->sdom = sdom; + subreq = ipa_id_get_account_info_send(req, ev, ipa_id_ctx, ar); + if (subreq == NULL) { + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, ipa_get_trusted_acct_part_done, req); + return req; + +fail: + state->dp_error = DP_ERR_FATAL; + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; } + static errno_t get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *fqname, uint32_t uid, @@ -1258,18 +1362,123 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, return ret; } +static void ipa_get_sid_ipa_next(struct tevent_req *subreq) +{ + int ret; + int dp_error = DP_ERR_FATAL; + const char *sid; + const char *user; + struct ldb_message *user_msg; + struct dp_id_data *ar; + struct dp_id_data *user_ar; + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); + + ret = ipa_subdomain_account_recv(subreq, &state->dp_error); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_id_get_account_info failed: %d %d\n", ret, + dp_error); + goto done; + } + + /* Get username object and id data */ + user = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_NAME, NULL); + if (user == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find SYSDB_NAME.\n"); + ret = ENOMEM; + goto done; + } + + DEBUG(SSSDBG_TRACE_INTERNAL, + "Looking up IPA object [%s] from LDAP.\n", + user); + ret = get_dp_id_data_for_user_name(state, + user, + state->obj_dom->name, + &user_ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to create lookup data for IPA object [%s].\n", + user); + goto done; + } + + /* Get user object */ + ret = get_object_from_cache(state, state->obj_dom, user_ar, + &user_msg); + if (ret == ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n"); + tevent_req_done(req); + return; + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n"); + goto done; + } + + /* Retrieve SID from user object */ + sid = ldb_msg_find_attr_as_string(user_msg, SYSDB_SID_STR, NULL); + if (sid == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a SID.\n"); + } + + state->object_sid = talloc_strdup(state, sid); + if (state->object_sid == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); + ret = ENOMEM; + goto done; + } + + ret = get_dp_id_data_for_sid(state, state->object_sid, + state->obj_dom->name, &ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "get_dp_id_data_for_sid failed.\n"); + goto done; + } + + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + state->ipa_ctx->server_mode->realm, + state->ipa_ctx->view_name, + ar); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + ret = ENOMEM; + goto done; + } + tevent_req_set_callback(subreq, ipa_get_trusted_override_done, req); + + return; + +done: + tevent_req_error(req,ret); + return; +} + static void -ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq) +ipa_get_trusted_acct_part_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); errno_t ret; const char *sid; + const char *user; struct dp_id_data *ar; + struct dp_id_data *user_ar; + + if (state->type == IPA_TRUST_AD) { + ret = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL); + } else if (state->type == IPA_TRUST_IPA) { + ret = ipa_id_get_account_info_recv(subreq, &state->dp_error); + } else { + ret = EINVAL; + } - ret = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret == ERR_SUBDOM_INACTIVE) { tevent_req_error(req, ret); @@ -1303,9 +1512,45 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq) if (state->override_attrs == NULL) { sid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_SID_STR, NULL); if (sid == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a SID.\n"); - ret = EINVAL; - goto fail; + DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find a SID.\n"); + /* In IPA-IPA trust, user private groups do not contain a SID. Lookup the + * equivalent user object of the same name in IPA and use this SID instead */ + if (state->type == IPA_TRUST_IPA) { + user = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_NAME, NULL); + if (user == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find SYSDB_NAME.\n"); + ret = ENOMEM; + goto fail; + } + + DEBUG(SSSDBG_TRACE_INTERNAL, + "Looking up IPA object [%s] from LDAP.\n", + user); + ret = get_dp_id_data_for_user_name(state, + user, + state->obj_dom->name, + &user_ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to create lookup data for IPA object [%s].\n", + user); + goto fail; + } + + subreq = ipa_subdomain_account_send(state, state->ev, state->ipa_ctx, user_ar); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + "ipa_id_get_account_info_send failed.\n"); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, ipa_get_sid_ipa_next, req); + } else { + ret = EINVAL; + goto fail; + } + + return; } state->object_sid = talloc_strdup(state, sid); @@ -1322,23 +1567,23 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq) goto fail; } - subreq = ipa_get_ad_override_send(state, state->ev, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->ipa_options, - state->ipa_ctx->server_mode->realm, - state->ipa_ctx->view_name, - ar); + subreq = ipa_get_trusted_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + state->ipa_ctx->server_mode->realm, + state->ipa_ctx->view_name, + ar); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override_send failed.\n"); ret = ENOMEM; goto fail; } - tevent_req_set_callback(subreq, ipa_get_ad_override_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_override_done, req); } else { - ret = ipa_get_ad_apply_override_step(req); + ret = ipa_get_trusted_apply_override_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, - "ipa_get_ad_apply_override_step failed.\n"); + "ipa_get_trusted_apply_override_step failed.\n"); goto fail; } } @@ -1353,15 +1598,15 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq) static void -ipa_get_ad_override_done(struct tevent_req *subreq) +ipa_get_trusted_override_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); errno_t ret; - ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state, + ret = ipa_get_trusted_override_recv(subreq, &state->dp_error, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { @@ -1371,9 +1616,9 @@ ipa_get_ad_override_done(struct tevent_req *subreq) } - ret = ipa_get_ad_apply_override_step(req); + ret = ipa_get_trusted_apply_override_step(req); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_apply_override_step failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_apply_override_step failed.\n"); goto fail; } @@ -1388,8 +1633,8 @@ ipa_get_ad_override_done(struct tevent_req *subreq) static void ipa_check_ghost_members_done(struct tevent_req *subreq); static errno_t ipa_check_ghost_members(struct tevent_req *req) { - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); errno_t ret; struct tevent_req *subreq; struct ldb_message_element *ghosts = NULL; @@ -1446,10 +1691,10 @@ static void ipa_check_ghost_members_done(struct tevent_req *subreq) return; } -static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) +static errno_t ipa_get_trusted_apply_override_step(struct tevent_req *req) { - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); errno_t ret; struct tevent_req *subreq; const char *obj_name; @@ -1555,9 +1800,9 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) return EOK; } - ret = ipa_get_ad_ipa_membership_step(req); + ret = ipa_get_trusted_ipa_membership_step(req); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_ipa_membership_step failed.\n"); return ret; } @@ -1579,9 +1824,9 @@ static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq) return; } - ret = ipa_get_ad_ipa_membership_step(req); + ret = ipa_get_trusted_ipa_membership_step(req); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_ipa_membership_step failed.\n"); tevent_req_error(req, ret); return; } @@ -1589,39 +1834,39 @@ static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq) return; } -static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req) +static errno_t ipa_get_trusted_ipa_membership_step(struct tevent_req *req) { - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); struct tevent_req *subreq; - /* For initgroups request we have to check IPA group memberships of AD + /* For initgroups request we have to check IPA group memberships of trusted * users. This has to be done for other user-request as well to make sure * IPA related attributes are not overwritten. */ - subreq = ipa_get_ad_memberships_send(state, state->ev, state->ar, - state->ipa_ctx->server_mode, - state->obj_dom, - state->ipa_ctx->sdap_id_ctx, - state->ipa_ctx->server_mode->realm); + subreq = ipa_get_trusted_memberships_send(state, state->ev, state->ar, + state->ipa_ctx->server_mode, + state->obj_dom, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->server_mode->realm); if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_memberships_send failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_memberships_send failed.\n"); return ENOMEM; } - tevent_req_set_callback(subreq, ipa_get_ad_acct_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_acct_done, req); return EOK; } static void -ipa_get_ad_acct_done(struct tevent_req *subreq) +ipa_get_trusted_acct_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); errno_t ret; - ret = ipa_get_ad_memberships_recv(subreq, &state->dp_error); + ret = ipa_get_trusted_memberships_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA external groups lookup failed: %d\n", @@ -1635,10 +1880,10 @@ ipa_get_ad_acct_done(struct tevent_req *subreq) } static errno_t -ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out) +ipa_get_acct_recv(struct tevent_req *req, int *dp_error_out) { - struct ipa_get_ad_acct_state *state = tevent_req_data(req, - struct ipa_get_ad_acct_state); + struct ipa_get_acct_state *state = tevent_req_data(req, + struct ipa_get_acct_state); if (dp_error_out) { *dp_error_out = state->dp_error; @@ -1649,7 +1894,7 @@ ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out) return EOK; } -struct ipa_srv_ad_acct_state { +struct ipa_srv_acct_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sysdb_attrs *override_attrs; @@ -1657,27 +1902,28 @@ struct ipa_srv_ad_acct_state { struct sss_domain_info *obj_dom; struct be_ctx *be_ctx; + enum ipa_trust_type type; bool retry; int dp_error; }; -static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req); -static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq); -static void ipa_srv_ad_acct_retried(struct tevent_req *subreq); +static int ipa_srv_acct_lookup_step(struct tevent_req *req); +static void ipa_srv_acct_lookup_done(struct tevent_req *subreq); +static void ipa_srv_acct_retried(struct tevent_req *subreq); static struct tevent_req * -ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct ipa_id_ctx *ipa_ctx, - struct sysdb_attrs *override_attrs, - struct dp_id_data *ar) +ipa_srv_acct_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, + struct sysdb_attrs *override_attrs, + struct dp_id_data *ar) { errno_t ret; struct tevent_req *req; - struct ipa_srv_ad_acct_state *state; + struct ipa_srv_acct_state *state; - req = tevent_req_create(mem_ctx, &state, struct ipa_srv_ad_acct_state); + req = tevent_req_create(mem_ctx, &state, struct ipa_srv_acct_state); if (req == NULL) { return NULL; } @@ -1699,7 +1945,9 @@ ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, goto fail; } - ret = ipa_srv_ad_acct_lookup_step(req); + state->type = ipa_get_trust_type(state->ipa_ctx, state->obj_dom); + + ret = ipa_srv_acct_lookup_step(req); if (ret != EOK) { goto fail; } @@ -1712,34 +1960,45 @@ ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, return req; } -static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req) +static int ipa_srv_acct_lookup_step(struct tevent_req *req) { struct tevent_req *subreq; - struct ipa_srv_ad_acct_state *state = tevent_req_data(req, - struct ipa_srv_ad_acct_state); + struct ipa_srv_acct_state *state = tevent_req_data(req, + struct ipa_srv_acct_state); + + if (state->type == IPA_TRUST_AD) { + DEBUG(SSSDBG_TRACE_FUNC, "Looking up AD account\n"); + subreq = ipa_get_ad_acct_send(state, state->ev, state->ipa_ctx, + state->override_attrs, + state->ar, state->type); + } else if (state->type == IPA_TRUST_IPA) { + DEBUG(SSSDBG_TRACE_FUNC, "Looking up IPA account\n"); + subreq = ipa_get_ipa_acct_send(state, state->ev, state->ipa_ctx, + state->override_attrs, + state->ar, state->type); + } else { + DEBUG(SSSDBG_TRACE_FUNC, "Trust type is unknown\n"); + subreq = NULL; + } - DEBUG(SSSDBG_TRACE_FUNC, "Looking up AD account\n"); - subreq = ipa_get_ad_acct_send(state, state->ev, state->ipa_ctx, - state->override_attrs, - state->ar); if (subreq == NULL) { return ENOMEM; } - tevent_req_set_callback(subreq, ipa_srv_ad_acct_lookup_done, req); + tevent_req_set_callback(subreq, ipa_srv_acct_lookup_done, req); return EOK; } -static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq) +static void ipa_srv_acct_lookup_done(struct tevent_req *subreq) { errno_t ret; int dp_error = DP_ERR_FATAL; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_srv_ad_acct_state *state = tevent_req_data(req, - struct ipa_srv_ad_acct_state); + struct ipa_srv_acct_state *state = tevent_req_data(req, + struct ipa_srv_acct_state); - ret = ipa_get_ad_acct_recv(subreq, &dp_error); + ret = ipa_get_acct_recv(subreq, &dp_error); talloc_free(subreq); if (ret == ERR_SUBDOM_INACTIVE && state->retry == true) { @@ -1754,7 +2013,7 @@ static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq) if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, ipa_srv_ad_acct_retried, req); + tevent_req_set_callback(subreq, ipa_srv_acct_retried, req); return; } else if (ret != EOK) { be_mark_dom_offline(state->obj_dom, state->be_ctx); @@ -1773,14 +2032,14 @@ static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq) tevent_req_error(req, ret); } -static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) +static void ipa_srv_acct_retried(struct tevent_req *subreq) { errno_t ret; struct ad_id_ctx *ad_id_ctx; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_srv_ad_acct_state *state = tevent_req_data(req, - struct ipa_srv_ad_acct_state); + struct ipa_srv_acct_state *state = tevent_req_data(req, + struct ipa_srv_acct_state); ret = ipa_server_trusted_dom_setup_recv(subreq); talloc_free(subreq); @@ -1803,7 +2062,7 @@ static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) ad_failover_reset(state->be_ctx, ad_id_ctx->ad_options->service); - ret = ipa_srv_ad_acct_lookup_step(req); + ret = ipa_srv_acct_lookup_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to look up AD acct [%d]: %s\n", ret, sss_strerror(ret)); @@ -1814,10 +2073,10 @@ static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) } static errno_t -ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out) +ipa_srv_acct_recv(struct tevent_req *req, int *dp_error_out) { - struct ipa_srv_ad_acct_state *state = tevent_req_data(req, - struct ipa_srv_ad_acct_state); + struct ipa_srv_acct_state *state = tevent_req_data(req, + struct ipa_srv_acct_state); if (dp_error_out) { *dp_error_out = state->dp_error; diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c index aaedf62102..2fccf51474 100644 --- a/src/providers/ipa/ipa_subdomains_server.c +++ b/src/providers/ipa/ipa_subdomains_server.c @@ -27,6 +27,7 @@ #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" +#include "providers/ipa/ipa_srv.h" /* These constants are defined in MS-ADTS 6.1.6.7.1 * https://msdn.microsoft.com/en-us/library/cc223768.aspx @@ -35,6 +36,10 @@ #define LSA_TRUST_DIRECTION_OUTBOUND 0x00000002 #define LSA_TRUST_DIRECTION_MASK (LSA_TRUST_DIRECTION_INBOUND | LSA_TRUST_DIRECTION_OUTBOUND) +/* See ipatrust_encode_type() method in freeipa ipaserver/dcerpc_common.py */ +#define TRUST_TYPE_AD (1 << 4) +#define TRUST_TYPE_IPA (1 << 5) + static char *forest_keytab(TALLOC_CTX *mem_ctx, const char *forest) { return talloc_asprintf(mem_ctx, @@ -55,6 +60,34 @@ static char *subdomain_trust_princ(TALLOC_CTX *mem_ctx, sd->parent->flat_name, forest_realm); } +struct sdap_domain * +sdap_domain_get_by_trust_type(struct ipa_subdom_server_ctx *trust, + struct sss_domain_info *dom) +{ + struct sdap_domain *sdom = NULL; + + if (trust->type == IPA_TRUST_AD) { + sdom = sdap_domain_get(trust->id_ctx.ad_id_ctx->sdap_id_ctx->opts, + dom); + } else if (trust->type == IPA_TRUST_AD) { + sdom = sdap_domain_get(trust->id_ctx.ipa_id_ctx->sdap_id_ctx->opts, + dom); + } + + return sdom; +} + +void +sdap_domain_remove_by_trust_type(struct ipa_subdom_server_ctx *trust, + struct sss_domain_info *subdom) +{ + if (trust->type == IPA_TRUST_AD) { + sdap_domain_remove(trust->id_ctx.ad_id_ctx->sdap_id_ctx->opts, subdom); + } else if (trust->type == IPA_TRUST_IPA) { + sdap_domain_remove(trust->id_ctx.ipa_id_ctx->sdap_id_ctx->opts, subdom); + } +} + static uint32_t default_direction(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs) @@ -108,6 +141,59 @@ errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd, return EOK; } +/* See ipatrust_encode_type() method in freeipa ipaserver/dcerpc_common.py + * + * ipaTrustType attribute will encode: + * bits 0..1 -- direction of trust + * bit 0 -- one-way incoming trust + * bit 1 -- one-way outgoing trust + * bits 4..7 -- type of trust + * bit 4 -- trust to Active Directory + * bit 5 -- trust to IPA + */ +enum ipa_trust_type ipa_server_decode_trust_type(uint32_t type) +{ + enum ipa_trust_type trust_type; + + if (type & TRUST_TYPE_AD) { + trust_type = IPA_TRUST_AD; + } else if (type & TRUST_TYPE_IPA) { + trust_type = IPA_TRUST_IPA; + /* Always assume existing trusts are AD */ + } else { + trust_type = IPA_TRUST_AD; + } + + return trust_type; +} + +errno_t ipa_server_get_trust_type(struct sysdb_attrs *sd, + struct ldb_context *ldb_ctx, + uint32_t *_type) +{ + uint32_t ipa_trust_type = 0; + uint32_t type; + int ret; + + ret = sysdb_attrs_get_uint32_t(sd, IPA_PARTNER_TRUST_TYPE, + &ipa_trust_type); + DEBUG(SSSDBG_TRACE_INTERNAL, + "Raw %s value: %d\n", IPA_PARTNER_TRUST_TYPE, ipa_trust_type); + if (ret == ENOENT) { + /* Always assume existing trusts (without IPA_PARTNER_TRUST_TYPE) are AD */ + type = IPA_TRUST_AD; + } else if (ret == EOK) { + /* Just store the value in SYSDB, we will check it while we're + * trying to use the trust */ + type = ipa_server_decode_trust_type(ipa_trust_type); + } else { + return ret; + } + + *_type = type; + return EOK; +} + const char *ipa_trust_dir2str(uint32_t direction) { if ((direction & LSA_TRUST_DIRECTION_OUTBOUND) @@ -124,17 +210,65 @@ const char *ipa_trust_dir2str(uint32_t direction) return "unknown"; } +const char *ipa_trust_type2str(uint32_t type) +{ + if (type == IPA_TRUST_AD) { + return "Active Directory Trust"; + } else if (type == IPA_TRUST_IPA) { + return "IPA Trust"; + } else if (type == 0) { + return "not set"; + } + + return "unknown"; +} + #ifndef IPA_GETKEYTAB_TIMEOUT #define IPA_GETKEYTAB_TIMEOUT 5 #endif /* IPA_GETKEYTAB_TIMEOUT */ +static struct ipa_options * +ipa_create_ipa_trust_ctx(struct ipa_id_ctx *id_ctx, + struct be_ctx *be_ctx, + const char *subdom_conf_path, + const char *forest, + const char *forest_realm, + struct sss_domain_info *subdom) +{ + char *keytab; + char *principal; + struct ipa_options *ipa_options; + + keytab = forest_keytab(id_ctx, forest); + principal = subdomain_trust_princ(id_ctx, forest_realm, subdom); + if (keytab == NULL || principal == NULL) { + return NULL; + } + + ipa_options = ipa_create_trust_options(id_ctx, + be_ctx, + be_ctx->cdb, + subdom_conf_path, + be_ctx->provider, + subdom, + keytab, + principal); + if (ipa_options == NULL) { + talloc_free(keytab); + talloc_free(principal); + return NULL; + } + + return ipa_options; +} + static struct ad_options * -ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx, - struct be_ctx *be_ctx, - const char *subdom_conf_path, - const char *forest, - const char *forest_realm, - struct sss_domain_info *subdom) +ipa_create_ad_trust_ctx(struct ipa_id_ctx *id_ctx, + struct be_ctx *be_ctx, + const char *subdom_conf_path, + const char *forest, + const char *forest_realm, + struct sss_domain_info *subdom) { char *keytab; char *principal; @@ -146,14 +280,15 @@ ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx, return NULL; } - ad_options = ad_create_1way_trust_options(id_ctx, - be_ctx->cdb, - subdom_conf_path, - be_ctx->provider, - subdom, - id_ctx->server_mode->hostname, - keytab, - principal); + ad_options = ad_create_trust_options(id_ctx, + be_ctx->cdb, + subdom_conf_path, + be_ctx->provider, + subdom, + NULL, + id_ctx->server_mode->hostname, + keytab, + principal); if (ad_options == NULL) { talloc_free(keytab); talloc_free(principal); @@ -190,9 +325,9 @@ static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx, * thus we always should be initializing principals/keytabs * as if we are running one-way trust */ if (direction & LSA_TRUST_DIRECTION_MASK) { - ad_options = ipa_create_1way_trust_ctx(id_ctx, be_ctx, - subdom_conf_path, forest, - forest_realm, subdom); + ad_options = ipa_create_ad_trust_ctx(id_ctx, be_ctx, + subdom_conf_path, forest, + forest_realm, subdom); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported trust direction!\n"); ad_options = NULL; @@ -204,9 +339,9 @@ static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx, return NULL; } - ret = ad_inherit_opts_if_needed(id_ctx->ipa_options->id->basic, - ad_options->id->basic, be_ctx->cdb, - subdom_conf_path, SDAP_SASL_MECH); + ret = subdom_inherit_opts_if_needed(id_ctx->ipa_options->id->basic, + ad_options->id->basic, be_ctx->cdb, + subdom_conf_path, SDAP_SASL_MECH); talloc_free(subdom_conf_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -222,6 +357,65 @@ static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx, return ad_options; } +static struct ipa_options *ipa_options_new(struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx, + struct sss_domain_info *subdom) +{ + struct ipa_options *ipa_options = NULL; + uint32_t direction; + const char *forest; + const char *forest_realm; + char *subdom_conf_path; + int ret; + + /* Trusts are only established with forest roots */ + direction = subdom->forest_root->trust_direction; + forest_realm = subdom->forest_root->realm; + forest = subdom->forest_root->forest; + + subdom_conf_path = subdomain_create_conf_path(id_ctx, subdom); + if (subdom_conf_path == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n"); + return NULL; + } + + /* In both inbound and outbound trust cases we should be + * using trusted domain object in a trusted domain space, + * thus we always should be initializing principals/keytabs + * as if we are running one-way trust */ + if (direction & LSA_TRUST_DIRECTION_MASK) { + ipa_options = ipa_create_ipa_trust_ctx(id_ctx, be_ctx, + subdom_conf_path, forest, + forest_realm, subdom); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported trust direction!\n"); + ipa_options = NULL; + } + + if (ipa_options == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize IPA options\n"); + talloc_free(subdom_conf_path); + return NULL; + } + + ret = subdom_inherit_opts_if_needed(id_ctx->ipa_options->id->basic, + ipa_options->id->basic, be_ctx->cdb, + subdom_conf_path, SDAP_SASL_MECH); + talloc_free(subdom_conf_path); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to inherit option [%s] to sub-domain [%s]. " + "This error is ignored but might cause issues or unexpected " + "behavior later on.\n", + id_ctx->ipa_options->id->basic[SDAP_SASL_MECH].opt_name, + subdom->name); + + return NULL; + } + + return ipa_options; +} + static errno_t ipa_ad_ctx_new(struct be_ctx *be_ctx, @@ -403,6 +597,163 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, return EOK; } +static errno_t +ipa_ctx_new(struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx, + struct sss_domain_info *subdom, + struct ipa_id_ctx **_ipa_id_ctx) +{ + struct ipa_options *ipa_options = NULL; + struct ipa_id_ctx *ipa_subdom_id_ctx; + struct ipa_srv_plugin_ctx *srv_ctx; + const char *ipa_domain; + char *subdom_conf_path = NULL; + char *basedn; + struct sdap_domain *sdom; + errno_t ret; + const char *extra_attrs; + + ipa_domain = subdom->name; + DEBUG(SSSDBG_TRACE_LIBS, "Setting up IPA subdomain %s\n", subdom->name); + + subdom_conf_path = subdomain_create_conf_path(id_ctx, subdom); + if (subdom_conf_path == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n"); + ret = ENOMEM; + goto done; + } + + ipa_options = ipa_options_new(be_ctx, id_ctx, subdom); + if (ipa_options == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n"); + ret = ENOMEM; + goto done; + } + + 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", ipa_domain, + extra_attrs); + + ret = dp_opt_set_string(ipa_options->id->basic, SDAP_USER_EXTRA_ATTRS, + extra_attrs); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "dp_opt_set_string failed.\n"); + goto done; + } + + ret = sdap_extend_map_with_list(ipa_options->id, ipa_options->id, + SDAP_USER_EXTRA_ATTRS, + ipa_options->id->user_map, + SDAP_OPTS_USER, + &ipa_options->id->user_map, + &ipa_options->id->user_map_cnt); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n"); + goto done; + } + } else { + DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n"); + } + + /* ipa_id_ctx and sdap_id_ctx for the ipa subdomain + * are initialized in ipa_options_new() */ + ipa_subdom_id_ctx = ipa_options->id_ctx; + ipa_subdom_id_ctx->sdap_id_ctx->opts = ipa_options->id; + + srv_ctx = ipa_srv_plugin_ctx_init(be_ctx, be_ctx->be_res->resolv, + id_ctx->server_mode->hostname, + ipa_domain); + + if (srv_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); + ret = ENOMEM; + goto done; + } + be_fo_set_srv_lookup_plugin(be_ctx, ipa_srv_plugin_send, + ipa_srv_plugin_recv, srv_ctx, "IPA"); + + ret = sdap_domain_subdom_add(ipa_subdom_id_ctx->sdap_id_ctx, + ipa_subdom_id_ctx->sdap_id_ctx->opts->sdom, + subdom->parent); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n"); + goto done; + } + + sdom = sdap_domain_get(ipa_subdom_id_ctx->sdap_id_ctx->opts, subdom); + if (sdom == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot get sdap domain\n"); + ret = EFAULT; + goto done; + } + + ret = ipa_set_sdap_options(ipa_options, ipa_options->id); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set IPA sdap options\n"); + goto done; + } + + ret = domain_to_basedn(be_ctx, + dp_opt_get_string(ipa_options->id->basic, IPA_KRB5_REALM), + &basedn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failure\n"); + goto done; + } + + ipa_set_search_bases(ipa_options, + be_ctx->cdb, + basedn, + subdom_conf_path, + sdom); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set search bases\n"); + goto done; + } + + sdap_inherit_options(subdom->parent->sd_inherit, + id_ctx->sdap_id_ctx->opts, + ipa_subdom_id_ctx->sdap_id_ctx->opts); + + ret = sdap_id_setup_tasks(be_ctx, + ipa_subdom_id_ctx->sdap_id_ctx, + sdom, + ldap_id_enumeration_send, + ldap_id_enumeration_recv, + ipa_subdom_id_ctx->sdap_id_ctx); + if (ret != EOK) { + goto done; + } + + sdom->pvt = ipa_subdom_id_ctx; + + /* Set up the ID mapping object */ + ipa_subdom_id_ctx->sdap_id_ctx->opts->idmap_ctx = + id_ctx->sdap_id_ctx->opts->idmap_ctx; + + /* Set up the certificate mapping context */ + ipa_subdom_id_ctx->sdap_id_ctx->opts->sdap_certmap_ctx = + id_ctx->sdap_id_ctx->opts->sdap_certmap_ctx; + + *_ipa_id_ctx = ipa_subdom_id_ctx; + + ret = EOK; +done: + + if (ret != EOK) { + if (subdom_conf_path != NULL) { + talloc_free(subdom_conf_path); + } + if (ipa_options != NULL) { + talloc_free(ipa_options); + } + } + return ret; +} + struct ipa_getkeytab_state { int child_status; struct sss_child_ctx_old *child_ctx; @@ -904,8 +1255,8 @@ ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx, static errno_t ipa_server_create_trusts_step(struct tevent_req *req) { struct tevent_req *subreq = NULL; - struct ipa_ad_server_ctx *trust_iter; - struct ipa_ad_server_ctx *trust_i; + struct ipa_subdom_server_ctx *trust_iter; + struct ipa_subdom_server_ctx *trust_i; struct ipa_server_create_trusts_state *state = NULL; state = tevent_req_data(req, struct ipa_server_create_trusts_state); @@ -936,12 +1287,11 @@ static errno_t ipa_server_create_trusts_step(struct tevent_req *req) } } - /* Refresh all sdap_dom lists in all ipa_ad_server_ctx contexts */ + /* Refresh all sdap_dom lists in all ipa_subdom_server_ctx contexts */ DLIST_FOR_EACH(trust_iter, state->id_ctx->server_mode->trusts) { struct sdap_domain *sdom_a; - sdom_a = sdap_domain_get(trust_iter->ad_id_ctx->sdap_id_ctx->opts, - trust_iter->dom); + sdom_a = sdap_domain_get_by_trust_type(trust_iter, trust_iter->dom); if (sdom_a == NULL) { continue; } @@ -953,8 +1303,7 @@ static errno_t ipa_server_create_trusts_step(struct tevent_req *req) continue; } - sdom_b = sdap_domain_get(trust_i->ad_id_ctx->sdap_id_ctx->opts, - sdom_a->dom); + sdom_b = sdap_domain_get_by_trust_type(trust_i, sdom_a->dom); if (sdom_b == NULL) { continue; } @@ -1001,26 +1350,48 @@ static void ipa_server_create_trusts_done(struct tevent_req *subreq) static errno_t ipa_server_create_trusts_ctx(struct tevent_req *req) { - struct ipa_ad_server_ctx *trust_ctx; + struct ipa_subdom_server_ctx *trust_ctx; struct ad_id_ctx *ad_id_ctx; + struct ipa_id_ctx *ipa_id_ctx; errno_t ret; + enum ipa_trust_type trust_type; struct ipa_server_create_trusts_state *state = NULL; state = tevent_req_data(req, struct ipa_server_create_trusts_state); - ret = ipa_ad_ctx_new(state->be_ctx, state->id_ctx, state->domiter, &ad_id_ctx); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Cannot create ad_id_ctx for subdomain %s\n", state->domiter->name); - return ret; - } + trust_type = state->domiter->forest_root->trust_type; - trust_ctx = talloc(state->id_ctx->server_mode, struct ipa_ad_server_ctx); + trust_ctx = talloc(state->id_ctx->server_mode, struct ipa_subdom_server_ctx); if (trust_ctx == NULL) { return ENOMEM; } trust_ctx->dom = state->domiter; - trust_ctx->ad_id_ctx = ad_id_ctx; + trust_ctx->type = trust_type; + + /* Previously stored AD trusted domains dont contain trust type attr */ + if (trust_type != IPA_TRUST_AD && trust_type != IPA_TRUST_IPA) { + trust_type = IPA_TRUST_AD; + } + + if (trust_type == IPA_TRUST_AD) { + ret = ipa_ad_ctx_new(state->be_ctx, state->id_ctx, state->domiter, &ad_id_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot create ad_id_ctx for subdomain %s\n", state->domiter->name); + return ret; + } + + trust_ctx->id_ctx.ad_id_ctx = ad_id_ctx; + } else if (trust_type == IPA_TRUST_IPA) { + ret = ipa_ctx_new(state->be_ctx, state->id_ctx, state->domiter, &ipa_id_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot create ipa_id_ctx for subdomain %s\n", state->domiter->name); + return ret; + } + + trust_ctx->id_ctx.ipa_id_ctx = ipa_id_ctx; + } DLIST_ADD(state->id_ctx->server_mode->trusts, trust_ctx); return EOK; @@ -1036,7 +1407,7 @@ 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 ipa_subdom_server_ctx *iter; struct sdap_domain *sdom; if (dp_opt_get_bool(id_ctx->ipa_options->basic, @@ -1054,10 +1425,10 @@ void ipa_ad_subdom_remove(struct be_ctx *be_ctx, return; } - sdom = sdap_domain_get(iter->ad_id_ctx->sdap_id_ctx->opts, subdom); + sdom = sdap_domain_get_by_trust_type(iter, subdom); if (sdom == NULL) return; - sdap_domain_remove(iter->ad_id_ctx->sdap_id_ctx->opts, subdom); + sdap_domain_remove_by_trust_type(iter, subdom); DLIST_REMOVE(id_ctx->server_mode->trusts, iter); /* terminate all requests for this subdomain so we can free it */ @@ -1065,7 +1436,7 @@ void ipa_ad_subdom_remove(struct be_ctx *be_ctx, talloc_zfree(sdom); } -struct ipa_ad_subdom_reinit_state { +struct ipa_trusted_subdom_reinit_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct ipa_id_ctx *id_ctx; @@ -1090,9 +1461,9 @@ static void create_trusts_at_startup(struct tevent_context *ev, void *pvt) { struct tevent_req *req; - struct ipa_ad_subdom_reinit_state *state; + struct ipa_trusted_subdom_reinit_state *state; - state = talloc_get_type(pvt, struct ipa_ad_subdom_reinit_state); + state = talloc_get_type(pvt, struct ipa_trusted_subdom_reinit_state); req = ipa_server_create_trusts_send(state, state->ev, state->be_ctx, state->id_ctx, state->parent); @@ -1106,16 +1477,16 @@ static void create_trusts_at_startup(struct tevent_context *ev, return; } -static errno_t ipa_ad_subdom_reinit(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct be_ctx *be_ctx, - struct ipa_id_ctx *id_ctx, - struct sss_domain_info *parent) +static errno_t ipa_trusted_subdom_reinit(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx, + struct sss_domain_info *parent) { struct tevent_immediate *imm; - struct ipa_ad_subdom_reinit_state *state; + struct ipa_trusted_subdom_reinit_state *state; - state = talloc(mem_ctx, struct ipa_ad_subdom_reinit_state); + state = talloc(mem_ctx, struct ipa_trusted_subdom_reinit_state); if (state == NULL) { return ENOMEM; } @@ -1140,8 +1511,8 @@ static errno_t ipa_ad_subdom_reinit(TALLOC_CTX *mem_ctx, return EOK; } -int ipa_ad_subdom_init(struct be_ctx *be_ctx, - struct ipa_id_ctx *id_ctx) +int ipa_trusted_subdom_init(struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx) { char *realm; char *hostname; @@ -1204,10 +1575,10 @@ int ipa_ad_subdom_init(struct be_ctx *be_ctx, } } - ret = ipa_ad_subdom_reinit(be_ctx, be_ctx->ev, + ret = ipa_trusted_subdom_reinit(be_ctx, be_ctx->ev, be_ctx, id_ctx, be_ctx->domain); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_trusted_subdom_reinit failed.\n"); return ret; } diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c index 2cc7db2e23..129ee874c9 100644 --- a/src/providers/ipa/ipa_views.c +++ b/src/providers/ipa/ipa_views.c @@ -379,7 +379,7 @@ errno_t get_dp_id_data_for_user_name(TALLOC_CTX *mem_ctx, _ar); } -struct ipa_get_ad_override_state { +struct ipa_get_trusted_override_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; struct ipa_options *ipa_options; @@ -393,12 +393,12 @@ struct ipa_get_ad_override_state { char *filter; }; -static void ipa_get_ad_override_connect_done(struct tevent_req *subreq); -static errno_t ipa_get_ad_override_qualify_name( - struct ipa_get_ad_override_state *state); -static void ipa_get_ad_override_done(struct tevent_req *subreq); +static void ipa_get_trusted_override_connect_done(struct tevent_req *subreq); +static errno_t ipa_get_trusted_override_qualify_name( + struct ipa_get_trusted_override_state *state); +static void ipa_get_trusted_override_done(struct tevent_req *subreq); -struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, +struct tevent_req *ipa_get_trusted_override_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ipa_options *ipa_options, @@ -409,9 +409,9 @@ struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, int ret; struct tevent_req *req; struct tevent_req *subreq; - struct ipa_get_ad_override_state *state; + struct ipa_get_trusted_override_state *state; - req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_override_state); + req = tevent_req_create(mem_ctx, &state, struct ipa_get_trusted_override_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; @@ -453,7 +453,7 @@ struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, goto done; } - tevent_req_set_callback(subreq, ipa_get_ad_override_connect_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_override_connect_done, req); return req; @@ -470,12 +470,12 @@ struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, return req; } -static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) +static void ipa_get_trusted_override_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_get_ad_override_state *state = tevent_req_data(req, - struct ipa_get_ad_override_state); + struct ipa_get_trusted_override_state *state = tevent_req_data(req, + struct ipa_get_trusted_override_state); int ret; char *basedn; char *search_base; @@ -536,7 +536,7 @@ static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) goto fail; } - tevent_req_set_callback(subreq, ipa_get_ad_override_done, req); + tevent_req_set_callback(subreq, ipa_get_trusted_override_done, req); return; fail: @@ -545,12 +545,12 @@ static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) return; } -static void ipa_get_ad_override_done(struct tevent_req *subreq) +static void ipa_get_trusted_override_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct ipa_get_ad_override_state *state = tevent_req_data(req, - struct ipa_get_ad_override_state); + struct ipa_get_trusted_override_state *state = tevent_req_data(req, + struct ipa_get_trusted_override_state); int ret; size_t reply_count = 0; struct sysdb_attrs **reply = NULL; @@ -558,7 +558,7 @@ static void ipa_get_ad_override_done(struct tevent_req *subreq) ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override request failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_trusted_override request failed.\n"); goto fail; } @@ -590,7 +590,7 @@ static void ipa_get_ad_override_done(struct tevent_req *subreq) state->filter); state->override_attrs = reply[0]; - ret = ipa_get_ad_override_qualify_name(state); + ret = ipa_get_trusted_override_qualify_name(state); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot qualify object name\n"); goto fail; @@ -606,8 +606,8 @@ static void ipa_get_ad_override_done(struct tevent_req *subreq) return; } -static errno_t ipa_get_ad_override_qualify_name( - struct ipa_get_ad_override_state *state) +static errno_t ipa_get_trusted_override_qualify_name( + struct ipa_get_trusted_override_state *state) { int ret; struct ldb_message_element *name; @@ -633,12 +633,12 @@ static errno_t ipa_get_ad_override_qualify_name( return EOK; } -errno_t ipa_get_ad_override_recv(struct tevent_req *req, int *dp_error_out, +errno_t ipa_get_trusted_override_recv(struct tevent_req *req, int *dp_error_out, TALLOC_CTX *mem_ctx, struct sysdb_attrs **override_attrs) { - struct ipa_get_ad_override_state *state = tevent_req_data(req, - struct ipa_get_ad_override_state); + struct ipa_get_trusted_override_state *state = tevent_req_data(req, + struct ipa_get_trusted_override_state); if (dp_error_out != NULL) { *dp_error_out = state->dp_error; diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c index 9d34ad7688..ae82b8c46d 100644 --- a/src/tests/cmocka/test_ad_common.c +++ b/src/tests/cmocka/test_ad_common.c @@ -749,15 +749,15 @@ static void test_ad_create_1way_trust_options(void **state) mock_keytab_with_contents(test_ctx, ONEWAY_KEYTAB_PATH, ONEWAY_TEST_PRINC); test_ctx->subdom->name = discard_const(ONEWAY_DOMNAME); - test_ctx->ad_ctx->ad_options = ad_create_1way_trust_options( - test_ctx->ad_ctx, - NULL, - NULL, - NULL, - test_ctx->subdom, - ONEWAY_HOST_NAME, - ONEWAY_KEYTAB_PATH, - ONEWAY_AUTHID); + test_ctx->ad_ctx->ad_options = ad_create_trust_options(test_ctx->ad_ctx, + NULL, + NULL, + NULL, + test_ctx->subdom, + NULL, + ONEWAY_HOST_NAME, + ONEWAY_KEYTAB_PATH, + ONEWAY_AUTHID); assert_non_null(test_ctx->ad_ctx->ad_options); assert_int_equal(test_ctx->ad_ctx->ad_options->id->schema_type, @@ -816,14 +816,15 @@ static void test_ad_create_2way_trust_options(void **state) mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC); test_ctx->subdom->name = discard_const(DOMNAME); - test_ctx->ad_ctx->ad_options = ad_create_2way_trust_options( + test_ctx->ad_ctx->ad_options = ad_create_trust_options( test_ctx->ad_ctx, NULL, NULL, NULL, - REALMNAME, test_ctx->subdom, + REALMNAME, HOST_NAME, + NULL, NULL); assert_non_null(test_ctx->ad_ctx->ad_options); @@ -887,14 +888,15 @@ test_ldap_conn_setup(void **state) ad_ctx = test_ctx->ad_ctx; - test_ctx->ad_ctx->ad_options = ad_create_2way_trust_options( + test_ctx->ad_ctx->ad_options = ad_create_trust_options( ad_ctx, NULL, NULL, NULL, - REALMNAME, test_ctx->subdom, + REALMNAME, HOST_NAME, + NULL, NULL); assert_non_null(ad_ctx->ad_options); diff --git a/src/tests/cmocka/test_fqnames.c b/src/tests/cmocka/test_fqnames.c index efb3f57e89..be6a27ae81 100644 --- a/src/tests/cmocka/test_fqnames.c +++ b/src/tests/cmocka/test_fqnames.c @@ -23,6 +23,7 @@ #include #include "db/sysdb_private.h" +#include "providers/ipa/ipa_subdomains.h" #include "tests/cmocka/common_mock.h" #define NAME "name" @@ -308,7 +309,8 @@ static int parse_name_test_setup_re(void **state, const char *regexp) */ test_ctx->subdom = new_subdomain(dom, dom, SUBDOMNAME, NULL, SUBFLATNAME, SUBDOMNAME, NULL, MPG_DISABLED, false, - NULL, NULL, 0, NULL, true); + NULL, NULL, 0, IPA_TRUST_UNKNOWN, + NULL, true); assert_non_null(test_ctx->subdom); check_leaks_push(test_ctx); diff --git a/src/tests/cmocka/test_ipa_subdomains_server.c b/src/tests/cmocka/test_ipa_subdomains_server.c index 737abbb99a..d23ac76a23 100644 --- a/src/tests/cmocka/test_ipa_subdomains_server.c +++ b/src/tests/cmocka/test_ipa_subdomains_server.c @@ -35,12 +35,14 @@ #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_opts.h" +#include "providers/ipa/ipa_srv.h" #include "providers/data_provider.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "tests/cmocka/common_mock_krb5.h" #include "tests/cmocka/common_mock_sdap.h" #include "tests/cmocka/common_mock_be.h" +#include "tests/cmocka/data_provider/mock_dp.h" #define DOM_REALM "DOM.MAIN" #define HOSTNAME "ipaserver.dom.main" @@ -50,23 +52,35 @@ #define KEYTAB_TEST_PRINC TEST_AUTHID"@"DOM_REALM #define KEYTAB_PATH TEST_DIR"/"TESTS_PATH"/keytab_test.keytab" -#define SUBDOM_NAME "twoway.subdom.test" -#define SUBDOM_REALM "TWOWAY.SUBDOM.TEST" -#define SUBDOM_FLAT "TWOWAY" -#define SUBDOM_SID "S-1-2-3" +#define AD_SUBDOM_NAME "adtwoway.subdom.test" +#define AD_SUBDOM_REALM "ADTWOWAY.SUBDOM.TEST" +#define AD_SUBDOM_FLAT "ADTWOWAY" +#define AD_SUBDOM_SID "S-1-2-3" -#define CHILD_NAME "child."SUBDOM_NAME -#define CHILD_REALM "CHILD."SUBDOM_REALM -#define CHILD_FLAT "CHILD" -#define CHILD_SID "S-1-2-3-4" +#define AD_CHILD_NAME "child."AD_SUBDOM_NAME +#define AD_CHILD_REALM "CHILD."AD_SUBDOM_REALM +#define AD_CHILD_FLAT "CHILD" +#define AD_CHILD_SID "S-1-2-3-4" + +#define IPA_SUBDOM_NAME "ipa.subdom.test" +#define IPA_SUBDOM_REALM "IPA.SUBDOM.TEST" +#define IPA_SUBDOM_FLAT "IPA" +#define IPA_SUBDOM_SID "S-1-2-4" + +#define IPA_SUBDOM_TWO_NAME "ipa2.subdom2.test" +#define IPA_SUBDOM_TWO_REALM "IPA2.SUBDOM2.TEST" +#define IPA_SUBDOM_TWO_FLAT "IPA2" +#define IPA_SUBDOM_TWO_SID "S-1-2-5" #define TEST_CONF_DB "test_ipa_subdom_server.ldb" #define TEST_DOM_NAME "ipa_subdom_server_test" #define TEST_ID_PROVIDER "ipa" -#define ONEWAY_KEYTAB TEST_DIR"/"TESTS_PATH"/"SUBDOM_REALM".keytab" +#define AD_ONEWAY_KEYTAB TEST_DIR"/"TESTS_PATH"/"AD_SUBDOM_REALM".keytab" +#define IPA_ONEWAY_KEYTAB TEST_DIR"/"TESTS_PATH"/"IPA_SUBDOM_REALM".keytab" +#define IPA_ONEWAY_TWO_KEYTAB TEST_DIR"/"TESTS_PATH"/"IPA_SUBDOM_TWO_REALM".keytab" #define ONEWAY_PRINC DOM_FLAT"$" -#define ONEWAY_AUTHID ONEWAY_PRINC"@"SUBDOM_REALM +#define ONEWAY_AUTHID ONEWAY_PRINC"@"AD_SUBDOM_REALM static bool global_rename_called; @@ -202,6 +216,8 @@ static struct ipa_id_ctx *mock_ipa_ctx(TALLOC_CTX *mem_ctx, struct sdap_options); assert_non_null(ipa_ctx->ipa_options->id); + ipa_ctx->ipa_options->id->dp = be_ctx->provider; + ret = sdap_copy_map(ipa_ctx->ipa_options->id, ipa_user_map, SDAP_OPTS_USER, @@ -261,19 +277,33 @@ static void add_test_subdomains(struct trust_test_ctx *test_ctx, { errno_t - /* Add two subdomains */ + /* Add two AD subdomains and one IPA subdomain */ + ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, + AD_SUBDOM_NAME, AD_SUBDOM_REALM, + NULL, AD_SUBDOM_NAME, AD_SUBDOM_SID, + MPG_ENABLED, false, AD_SUBDOM_REALM, + direction, IPA_TRUST_AD, NULL); + assert_int_equal(ret, EOK); + ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, - SUBDOM_NAME, SUBDOM_REALM, - NULL, SUBDOM_NAME, SUBDOM_SID, - MPG_ENABLED, false, SUBDOM_REALM, - direction, NULL); + AD_CHILD_NAME, AD_CHILD_REALM, + AD_CHILD_FLAT, AD_CHILD_NAME, AD_CHILD_SID, + MPG_ENABLED, false, AD_SUBDOM_REALM, + direction, IPA_TRUST_AD, NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, - CHILD_NAME, CHILD_REALM, - CHILD_FLAT, CHILD_NAME, CHILD_SID, - MPG_ENABLED, false, SUBDOM_REALM, - direction, NULL); + IPA_SUBDOM_NAME, IPA_SUBDOM_REALM, + NULL, IPA_SUBDOM_NAME, IPA_SUBDOM_SID, + MPG_ENABLED, false, IPA_SUBDOM_REALM, + direction, IPA_TRUST_IPA, NULL); + assert_int_equal(ret, EOK); + + ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, + IPA_SUBDOM_TWO_NAME, IPA_SUBDOM_TWO_REALM, + NULL, IPA_SUBDOM_TWO_NAME, IPA_SUBDOM_TWO_SID, + MPG_ENABLED, false, IPA_SUBDOM_TWO_REALM, + direction, IPA_TRUST_IPA, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -313,6 +343,9 @@ static int test_ipa_server_create_trusts_setup(void **state) test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); + test_ctx->be_ctx->provider = mock_dp(test_ctx, test_ctx->be_ctx); + assert_non_null(test_ctx->be_ctx->provider); + test_ctx->ipa_ctx = mock_ipa_ctx(test_ctx, test_ctx->be_ctx, test_ctx->tctx, DOM_REALM, HOSTNAME); assert_non_null(test_ctx->tctx); @@ -340,7 +373,8 @@ static int test_ipa_server_create_trusts_teardown(void **state) ret = unlink(KEYTAB_PATH); assert_int_equal(ret, 0); - unlink(ONEWAY_KEYTAB); + unlink(AD_ONEWAY_KEYTAB); + unlink(IPA_ONEWAY_KEYTAB); /* Ignore failures */ /* If a test needs this variable, it should be set again in @@ -399,22 +433,17 @@ static void test_ipa_server_create_trusts_none(struct tevent_req *req) } -static void assert_trust_object(struct ipa_ad_server_ctx *trust, - const char *dom_name, - const char *dom_realm, - const char *sid, - const char *keytab, - const char *authid, - const char *sdap_realm) +static void assert_trust_object_ad(struct ipa_subdom_server_ctx *trust, + const char *dom_name, + const char *dom_realm, + const char *sid, + const char *keytab, + const char *authid, + const char *sdap_realm) { const char *s; - assert_non_null(trust); - assert_non_null(trust->dom); - assert_string_equal(trust->dom->name, dom_name); - assert_string_equal(trust->dom->domain_id, sid); - - s = dp_opt_get_string(trust->ad_id_ctx->ad_options->basic, + s = dp_opt_get_string(trust->id_ctx.ad_id_ctx->ad_options->basic, AD_KRB5_REALM); if (dom_realm != NULL) { assert_non_null(s); @@ -423,7 +452,7 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust, assert_null(s); } - s = dp_opt_get_string(trust->ad_id_ctx->ad_options->basic, + s = dp_opt_get_string(trust->id_ctx.ad_id_ctx->ad_options->basic, AD_DOMAIN); if (dom_name != NULL) { assert_non_null(s); @@ -433,7 +462,7 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust, } /* both one-way and two-way trust uses specialized keytab */ - s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, + s = dp_opt_get_string(trust->id_ctx.ad_id_ctx->ad_options->id->basic, SDAP_KRB5_KEYTAB); if (keytab != NULL) { assert_non_null(s); @@ -442,7 +471,7 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust, assert_null(s); } - s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, + s = dp_opt_get_string(trust->id_ctx.ad_id_ctx->ad_options->id->basic, SDAP_SASL_REALM); if (sdap_realm != NULL) { assert_non_null(s); @@ -451,7 +480,7 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust, assert_null(s); } - s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, + s = dp_opt_get_string(trust->id_ctx.ad_id_ctx->ad_options->id->basic, SDAP_SASL_AUTHID); if (authid != NULL) { assert_non_null(s); @@ -461,14 +490,123 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust, } } +static void assert_trust_object_ipa(struct ipa_subdom_server_ctx *trust, + const char *dom_name, + const char *dom_realm, + const char *sid, + const char *keytab, + const char *authid, + const char *sdap_realm) +{ + const char *s; + + s = dp_opt_get_string(trust->id_ctx.ipa_id_ctx->ipa_options->basic, + IPA_KRB5_REALM); + if (dom_realm != NULL) { + assert_non_null(s); + assert_string_equal(s, dom_realm); + } else { + assert_null(s); + } + + s = dp_opt_get_string(trust->id_ctx.ipa_id_ctx->ipa_options->basic, + IPA_DOMAIN); + if (dom_name != NULL) { + assert_non_null(s); + assert_string_equal(s, dom_name); + } else { + assert_null(s); + } + + /* both one-way and two-way trust uses specialized keytab */ + s = dp_opt_get_string(trust->id_ctx.ipa_id_ctx->ipa_options->id->basic, + SDAP_KRB5_KEYTAB); + if (keytab != NULL) { + assert_non_null(s); + assert_string_equal(s, keytab); + } else { + assert_null(s); + } +} + +static void assert_trust_object(struct ipa_subdom_server_ctx *trust, + const char *dom_name, + const char *dom_realm, + const char *sid, + const char *keytab, + const char *authid, + const char *sdap_realm) +{ + assert_non_null(trust); + assert_non_null(trust->dom); + assert_string_equal(trust->dom->name, dom_name); + assert_string_equal(trust->dom->domain_id, sid); + + if (trust->type == IPA_TRUST_AD) { + assert_trust_object_ad(trust, dom_name, dom_realm, + sid, keytab, authid, + sdap_realm); + } else if (trust->type == IPA_TRUST_IPA) { + assert_trust_object_ipa(trust, dom_name, dom_realm, + sid, keytab, authid, + sdap_realm); + } +} + +static void assert_trusts(struct trust_test_ctx *test_ctx) +{ + struct ipa_subdom_server_ctx *iter; + + assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); + assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); + + DLIST_FOR_EACH(iter, test_ctx->ipa_ctx->server_mode->trusts) { + if (strcmp(iter->dom->name, AD_SUBDOM_NAME) == 0) { + assert_trust_object(iter, + AD_SUBDOM_NAME, + AD_SUBDOM_REALM, + AD_SUBDOM_SID, + AD_ONEWAY_KEYTAB, + ONEWAY_PRINC, + AD_SUBDOM_REALM); + } else if (strcmp(iter->dom->name, AD_CHILD_NAME) == 0) { + assert_trust_object(iter, + AD_CHILD_NAME, + AD_CHILD_REALM, + AD_CHILD_SID, + AD_ONEWAY_KEYTAB, + ONEWAY_PRINC, + AD_SUBDOM_REALM); + } else if (strcmp(iter->dom->name, IPA_SUBDOM_NAME) == 0) { + assert_trust_object(iter, + IPA_SUBDOM_NAME, + IPA_SUBDOM_REALM, + IPA_SUBDOM_SID, + IPA_ONEWAY_KEYTAB, + ONEWAY_PRINC, + IPA_SUBDOM_REALM); + } else if (strcmp(iter->dom->name, IPA_SUBDOM_TWO_NAME) == 0) { + assert_trust_object(iter, + IPA_SUBDOM_TWO_NAME, + IPA_SUBDOM_TWO_REALM, + IPA_SUBDOM_TWO_SID, + IPA_ONEWAY_TWO_KEYTAB, + ONEWAY_PRINC, + IPA_SUBDOM_TWO_REALM); + } + } + + /* No more trust objects */ + assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next->next->next); +} + static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) { struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; struct sss_domain_info *child_dom; - struct ipa_ad_server_ctx *s_trust; - struct ipa_ad_server_ctx *c_trust; + struct ipa_subdom_server_ctx *iter; ret = ipa_server_create_trusts_recv(req); talloc_zfree(req); @@ -478,50 +616,46 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); - if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, - SUBDOM_NAME) == 0) { - s_trust = test_ctx->ipa_ctx->server_mode->trusts; - c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - } else { - s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - c_trust = test_ctx->ipa_ctx->server_mode->trusts; - } - assert_trust_object(c_trust, - CHILD_NAME, - CHILD_REALM, - CHILD_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - - - assert_trust_object(s_trust, - SUBDOM_NAME, - SUBDOM_REALM, - SUBDOM_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - - /* No more trust objects */ - assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); + assert_trusts(test_ctx); - ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, CHILD_NAME); + ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, AD_CHILD_NAME); assert_int_equal(ret, EOK); - child_dom = find_domain_by_name(test_ctx->be_ctx->domain, CHILD_NAME, true); + child_dom = find_domain_by_name(test_ctx->be_ctx->domain, AD_CHILD_NAME, true); assert_non_null(child_dom); ipa_ad_subdom_remove(test_ctx->be_ctx, test_ctx->ipa_ctx, child_dom); - assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, - SUBDOM_NAME, - SUBDOM_REALM, - SUBDOM_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - assert_null(test_ctx->ipa_ctx->server_mode->trusts->next); + /* No child dom */ + DLIST_FOR_EACH(iter, test_ctx->ipa_ctx->server_mode->trusts) { + if (strcmp(iter->dom->name, AD_SUBDOM_NAME) == 0) { + assert_trust_object(iter, + AD_SUBDOM_NAME, + AD_SUBDOM_REALM, + AD_SUBDOM_SID, + AD_ONEWAY_KEYTAB, + ONEWAY_PRINC, + AD_SUBDOM_REALM); + } else if (strcmp(iter->dom->name, IPA_SUBDOM_NAME) == 0) { /* IPA_SUBDOM */ + assert_trust_object(iter, + IPA_SUBDOM_NAME, + IPA_SUBDOM_REALM, + IPA_SUBDOM_SID, + IPA_ONEWAY_KEYTAB, + ONEWAY_PRINC, + IPA_SUBDOM_REALM); + } else if (strcmp(iter->dom->name, IPA_SUBDOM_TWO_NAME) == 0) { + assert_trust_object(iter, + IPA_SUBDOM_TWO_NAME, + IPA_SUBDOM_TWO_REALM, + IPA_SUBDOM_TWO_SID, + IPA_ONEWAY_TWO_KEYTAB, + ONEWAY_PRINC, + IPA_SUBDOM_TWO_REALM); + } + } + + assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next->next); test_ev_done(test_ctx->tctx, EOK); } @@ -544,12 +678,10 @@ static void test_ipa_server_trust_init(void **state) errno_t ret; struct tevent_timer *timeout_handler; struct timeval tv; - struct ipa_ad_server_ctx *s_trust; - struct ipa_ad_server_ctx *c_trust; add_test_2way_subdomains(test_ctx); - ret = ipa_ad_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); + ret = ipa_trusted_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); assert_int_equal(ret, EOK); tv = tevent_timeval_current_ofs(1, 0); @@ -560,37 +692,7 @@ static void test_ipa_server_trust_init(void **state) ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); - /* Trust object should be around now */ - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); - - if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, - SUBDOM_NAME) == 0) { - s_trust = test_ctx->ipa_ctx->server_mode->trusts; - c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - } else { - s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - c_trust = test_ctx->ipa_ctx->server_mode->trusts; - } - - assert_trust_object(c_trust, - CHILD_NAME, - CHILD_REALM, - CHILD_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - - assert_trust_object(s_trust, - SUBDOM_NAME, - SUBDOM_REALM, - SUBDOM_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - - /* No more trust objects */ - assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); + assert_trusts(test_ctx); } struct dir_test_ctx { @@ -711,7 +813,10 @@ static void test_ipa_server_create_oneway(void **state) add_test_1way_subdomains(test_ctx); - ret = access(ONEWAY_KEYTAB, R_OK); + ret = access(AD_ONEWAY_KEYTAB, R_OK); + assert_int_not_equal(ret, 0); + + ret = access(IPA_ONEWAY_KEYTAB, R_OK); assert_int_not_equal(ret, 0); assert_null(test_ctx->ipa_ctx->server_mode->trusts); @@ -736,8 +841,6 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; - struct ipa_ad_server_ctx *s_trust; - struct ipa_ad_server_ctx *c_trust; ret = ipa_server_create_trusts_recv(req); talloc_zfree(req); @@ -745,41 +848,13 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) assert_true(test_ctx->expect_rename == global_rename_called); - ret = access(ONEWAY_KEYTAB, R_OK); + ret = access(AD_ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); - /* Trust object should be around now */ - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); - - if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, - SUBDOM_NAME) == 0) { - s_trust = test_ctx->ipa_ctx->server_mode->trusts; - c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - } else { - s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; - c_trust = test_ctx->ipa_ctx->server_mode->trusts; - } + ret = access(IPA_ONEWAY_KEYTAB, R_OK); + assert_int_equal(ret, 0); - assert_trust_object( - c_trust, - CHILD_NAME, /* AD domain name */ - CHILD_REALM, /* AD realm can be child if SDAP realm is parent's */ - CHILD_SID, - ONEWAY_KEYTAB, /* Keytab shared with parent AD dom */ - ONEWAY_PRINC, /* Principal shared with parent AD dom */ - SUBDOM_REALM); /* SDAP realm must be AD root domain */ - - /* Here all properties point to the AD domain */ - assert_trust_object(s_trust, - SUBDOM_NAME, - SUBDOM_REALM, - SUBDOM_SID, - ONEWAY_KEYTAB, - ONEWAY_PRINC, - SUBDOM_REALM); - - assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); + assert_trusts(test_ctx); test_ev_done(test_ctx->tctx, EOK); } @@ -792,8 +867,12 @@ static void test_ipa_server_create_oneway_kt_exists(void **state) add_test_1way_subdomains(test_ctx); - create_dummy_keytab(ONEWAY_KEYTAB); - ret = access(ONEWAY_KEYTAB, R_OK); + create_dummy_keytab(AD_ONEWAY_KEYTAB); + ret = access(AD_ONEWAY_KEYTAB, R_OK); + assert_int_equal(ret, 0); + + create_dummy_keytab(IPA_ONEWAY_KEYTAB); + ret = access(IPA_ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); test_ctx->expect_rename = true; @@ -825,8 +904,12 @@ static void test_ipa_server_create_oneway_kt_refresh_fallback(void **state) add_test_1way_subdomains(test_ctx); - create_dummy_keytab(ONEWAY_KEYTAB); - ret = access(ONEWAY_KEYTAB, R_OK); + create_dummy_keytab(AD_ONEWAY_KEYTAB); + ret = access(AD_ONEWAY_KEYTAB, R_OK); + assert_int_equal(ret, 0); + + create_dummy_keytab(IPA_ONEWAY_KEYTAB); + ret = access(IPA_ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); setenv("KT_CREATE_FAIL", "1", 1); @@ -905,7 +988,7 @@ static void test_ipa_server_trust_oneway_init(void **state) add_test_1way_subdomains(test_ctx); - ret = ipa_ad_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); + ret = ipa_trusted_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); assert_int_equal(ret, EOK); tv = tevent_timeval_current_ofs(1, 0); @@ -960,7 +1043,6 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_ipa_server_trust_oneway_init, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), - cmocka_unit_test_setup_teardown(test_ipa_server_trust_init, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c index d2c0342472..e900fa2e09 100644 --- a/src/tests/cmocka/test_negcache.c +++ b/src/tests/cmocka/test_negcache.c @@ -40,6 +40,7 @@ #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/negcache.h" +#include "providers/ipa/ipa_subdomains.h" int test_ncache_setup(void **state); int test_ncache_teardown(void **state); @@ -657,12 +658,13 @@ static void test_sss_ncache_prepopulate(void **state) subdomain = new_subdomain(tc, tc->dom, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], false, false, NULL, NULL, 0, - tc->confdb, true); + IPA_TRUST_UNKNOWN, tc->confdb, true); assert_non_null(subdomain); ret = sysdb_subdomain_store(tc->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], false, false, NULL, 0, NULL); + testdom[3], false, false, NULL, 0, + IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(tc->dom, tc->confdb); diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index c17a4973fa..1dabb743cf 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -31,6 +31,7 @@ #include "responder/common/negcache.h" #include "responder/nss/nss_private.h" #include "responder/nss/nss_protocol.h" +#include "providers/ipa/ipa_subdomains.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/util_sss_idmap.h" #include "util/crypto/sss_crypto.h" @@ -3688,12 +3689,14 @@ static int sss_nss_subdom_test_setup_common(void **state, bool nonfqnames) subdomain = new_subdomain(sss_nss_test_ctx, sss_nss_test_ctx->tctx->dom, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], false, false, NULL, NULL, 0, - sss_nss_test_ctx->tctx->confdb, true); + IPA_TRUST_UNKNOWN, sss_nss_test_ctx->tctx->confdb, + true); assert_non_null(subdomain); ret = sysdb_subdomain_store(sss_nss_test_ctx->tctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, 0, NULL); + testdom[3], MPG_DISABLED, false, NULL, 0, + IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(sss_nss_test_ctx->tctx->dom, diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c index b208136277..32718c1f14 100644 --- a/src/tests/cmocka/test_responder_cache_req.c +++ b/src/tests/cmocka/test_responder_cache_req.c @@ -27,6 +27,7 @@ #include "tests/cmocka/common_mock_resp.h" #include "db/sysdb.h" #include "responder/common/cache_req/cache_req.h" +#include "providers/ipa/ipa_subdomains.h" #define LDAP_ID_PROVIDER "ldap" #define TESTS_PATH "tp_" BASE_FILE_STEM @@ -728,12 +729,13 @@ int test_subdomain_setup(void **state) test_ctx->subdomain = new_subdomain(test_ctx, test_ctx->tctx->dom, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], MPG_DISABLED, false, NULL, NULL, 0, - test_ctx->tctx->confdb, true); + IPA_TRUST_UNKNOWN, test_ctx->tctx->confdb, true); assert_non_null(test_ctx->subdomain); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, 0, NULL); + testdom[3], MPG_DISABLED, false, NULL, 0, + IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c index d61cc14968..15f1ffbbe6 100644 --- a/src/tests/cmocka/test_sysdb_subdomains.c +++ b/src/tests/cmocka/test_sysdb_subdomains.c @@ -30,6 +30,7 @@ #include "tests/cmocka/common_mock.h" #include "tests/common.h" +#include "providers/ipa/ipa_subdomains.h" #include "db/sysdb_private.h" /* for sysdb->ldb member */ #define TESTS_PATH "tp_" BASE_FILE_STEM @@ -100,7 +101,8 @@ static void test_sysdb_subdomain_create(void **state) ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[0], dom1[3], - MPG_DISABLED, false, NULL, 0, NULL); + MPG_DISABLED, false, NULL, 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -113,7 +115,8 @@ static void test_sysdb_subdomain_create(void **state) ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[0], dom2[3], - MPG_DISABLED, false, NULL, 1, NULL); + MPG_DISABLED, false, NULL, 1, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -127,12 +130,14 @@ static void test_sysdb_subdomain_create(void **state) /* Reverse the trust directions */ ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[0], dom1[3], - MPG_DISABLED, false, NULL, 1, NULL); + MPG_DISABLED, false, NULL, 1, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[0], dom2[3], - MPG_DISABLED, false, NULL, 0, NULL); + MPG_DISABLED, false, NULL, 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -159,12 +164,14 @@ static void test_sysdb_subdomain_create(void **state) /* Test that changing the MPG status works */ ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[0], dom1[3], - MPG_ENABLED, false, NULL, 1, NULL); + MPG_ENABLED, false, NULL, 1, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[0], dom2[3], - MPG_ENABLED, false, NULL, 0, NULL); + MPG_ENABLED, false, NULL, 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -175,12 +182,14 @@ static void test_sysdb_subdomain_create(void **state) ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[0], dom1[3], - MPG_HYBRID, false, NULL, 1, NULL); + MPG_HYBRID, false, NULL, 1, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[0], dom2[3], - MPG_HYBRID, false, NULL, 0, NULL); + MPG_HYBRID, false, NULL, 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -247,27 +256,28 @@ static void test_sysdb_link_forest_root_ipa(void **state) ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[0], dom1[3], - MPG_DISABLED, false, dom1[4], 0, NULL); + MPG_DISABLED, false, dom1[4], 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, child_dom1[0], child_dom1[1], child_dom1[2], child_dom1[0], child_dom1[3], MPG_DISABLED, false, child_dom1[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[0], dom2[3], MPG_DISABLED, false, dom2[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, child_dom2[0], child_dom2[1], child_dom2[2], child_dom2[0], child_dom2[3], MPG_DISABLED, false, child_dom2[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -341,14 +351,14 @@ static void test_sysdb_link_forest_root_ad(void **state) child_dom[0], child_dom[1], child_dom[2], child_dom[0], child_dom[3], MPG_DISABLED, false, child_dom[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, sub_dom[0], sub_dom[1], sub_dom[2], sub_dom[0], sub_dom[3], MPG_DISABLED, false, sub_dom[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); @@ -419,14 +429,14 @@ static void test_sysdb_link_forest_member_ad(void **state) sub_dom[0], sub_dom[1], sub_dom[2], sub_dom[0], sub_dom[3], MPG_DISABLED, false, sub_dom[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, forest_root[0], forest_root[1], forest_root[2], forest_root[0], forest_root[3], MPG_DISABLED, false, forest_root[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(test_ctx->tctx->dom); @@ -505,7 +515,7 @@ static void test_sysdb_link_ad_multidom(void **state) child_dom[0], child_dom[1], child_dom[2], child_dom[0], child_dom[3], MPG_DISABLED, false, child_dom[4], - 0, NULL); + 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(main_dom1); @@ -526,7 +536,8 @@ static void test_sysdb_link_ad_multidom(void **state) ret = sysdb_subdomain_store(main_dom2->sysdb, dom2_forest_root[0], dom2_forest_root[1], dom2_forest_root[2], dom2_forest_root[0], dom2_forest_root[3], - MPG_DISABLED, false, dom2_forest_root[4], 0, NULL); + MPG_DISABLED, false, dom2_forest_root[4], 0, IPA_TRUST_UNKNOWN, + NULL); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(main_dom2); diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 45fb9e3a81..fef9b92962 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -30,6 +30,7 @@ #include #include "util/util.h" #include "util/crypto/sss_crypto.h" +#include "providers/ipa/ipa_subdomains.h" #include "db/sysdb_private.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" @@ -1601,7 +1602,7 @@ START_TEST (test_sysdb_get_user_attr_subdomain) /* Create subdomain */ subdomain = new_subdomain(test_ctx, test_ctx->domain, "test.sub", "TEST.SUB", "test", "test.sub", "S-3", - MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + MPG_DISABLED, false, NULL, NULL, 0, IPA_TRUST_UNKNOWN, NULL, true); sss_ck_fail_if_msg(subdomain == NULL, "Failed to create new subdomain."); ret = sss_names_init_from_args(test_ctx, @@ -6401,11 +6402,11 @@ START_TEST(test_sysdb_subdomain_store_user) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + testdom[3], MPG_DISABLED, false, NULL, NULL, 0, IPA_TRUST_UNKNOWN, NULL, true); ck_assert_msg(subdomain != NULL, "Failed to create new subdomain."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], - false, false, NULL, 0, NULL); + false, false, NULL, 0, IPA_TRUST_UNKNOWN, NULL); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain, NULL); @@ -6479,11 +6480,11 @@ START_TEST(test_sysdb_subdomain_content_delete) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + testdom[3], MPG_DISABLED, false, NULL, NULL, 0, IPA_TRUST_UNKNOWN, NULL, true); ck_assert_msg(subdomain != NULL, "Failed to create new subdomain."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], - false, false, NULL, 0, NULL); + false, false, NULL, 0, IPA_TRUST_UNKNOWN, NULL); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain, NULL); @@ -6567,11 +6568,11 @@ START_TEST(test_sysdb_subdomain_user_ops) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + testdom[3], MPG_DISABLED, false, NULL, NULL, 0, IPA_TRUST_UNKNOWN, NULL, true); ck_assert_msg(subdomain != NULL, "Failed to create new subdomain."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], - false, false, NULL, 0, NULL); + false, false, NULL, 0, IPA_TRUST_UNKNOWN, NULL); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain, NULL); @@ -6640,11 +6641,11 @@ START_TEST(test_sysdb_subdomain_group_ops) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[0], - testdom[3], MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + testdom[3], MPG_DISABLED, false, NULL, NULL, 0, IPA_TRUST_UNKNOWN, NULL, true); ck_assert_msg(subdomain != NULL, "Failed to create new subdomain."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], - false, false, NULL, 0, NULL); + false, false, NULL, 0, IPA_TRUST_UNKNOWN, NULL); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain, NULL);