diff options
Diffstat (limited to 'src/providers')
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 77 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.h | 9 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains_server.c | 75 |
3 files changed, 140 insertions, 21 deletions
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 5a3f90fe3..b67f1d9ca 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -363,7 +363,24 @@ done: return ret; } +static errno_t ipa_get_sd_trust_direction(struct sysdb_attrs *sd, + struct ipa_id_ctx *id_ctx, + struct ldb_context *ldb_ctx, + uint32_t *_direction) +{ + if (id_ctx->server_mode != NULL) { + return ipa_server_get_trust_direction(sd, ldb_ctx, _direction); + } else { + /* Clients do not have access to the trust objects's trust direction + * and don't generally care + */ + *_direction = 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, struct sysdb_attrs *attrs) { @@ -376,6 +393,7 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, int ret; bool mpg; bool enumerate; + uint32_t direction; tmp_ctx = talloc_new(parent); if (tmp_ctx == NULL) { @@ -419,8 +437,20 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, goto done; } + ret = ipa_get_sd_trust_direction(attrs, id_ctx, + sysdb_ctx_get_ldb(parent->sysdb), + &direction); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "ipa_get_sd_trust_direction failed: %d\n", ret); + goto done; + } + + DEBUG(SSSDBG_FUNC_DATA, + "Trust direction of %s is %s\n", name, ipa_trust_dir2str(direction)); ret = sysdb_subdomain_store(parent->sysdb, name, realm, flat, - id, mpg, enumerate, forest, 0); + id, mpg, enumerate, forest, + direction); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; @@ -432,6 +462,23 @@ done: return ret; } +static void ipa_subdom_store_step(struct sss_domain_info *parent, + struct ipa_id_ctx *id_ctx, + struct sdap_idmap_ctx *sdap_idmap_ctx, + struct sysdb_attrs *attrs) +{ + int ret; + + ret = ipa_subdom_store(parent, id_ctx, sdap_idmap_ctx, attrs); + if (ret == ERR_TRUST_NOT_SUPPORTED) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unsupported trust type, skipping\n"); + } else if (ret) { + /* Nothing we can do about the error. */ + DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " + "will try to use cached subdomain\n"); + } +} + static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, int count, struct sysdb_attrs **reply, bool *changes) @@ -476,15 +523,9 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, ipa_ad_subdom_remove(ctx->be_ctx, ctx->id_ctx, dom); } else { /* ok let's try to update it */ - ret = ipa_subdom_store(parent, ctx->sdap_id_ctx->opts->idmap_ctx, - reply[c]); - if (ret) { - /* Nothing we can do about the errorr. Let's at least try - * to reuse the existing domain - */ - DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " - "will try to use cached subdomain\n"); - } + ipa_subdom_store_step(parent, ctx->id_ctx, + ctx->sdap_id_ctx->opts->idmap_ctx, + reply[c]); handled[c] = true; h++; } @@ -504,19 +545,12 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, continue; } - /* Nothing we can do about the errorr. Let's at least try - * to reuse the existing domain. - */ - ret = ipa_subdom_store(parent, ctx->sdap_id_ctx->opts->idmap_ctx, - reply[c]); - if (ret) { - DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " - "will try to use cached subdomain\n"); - } + ipa_subdom_store_step(parent, ctx->id_ctx, + ctx->sdap_id_ctx->opts->idmap_ctx, + reply[c]); } ret = EOK; - done: if (ret != EOK) { ctx->last_refreshed = 0; @@ -560,7 +594,8 @@ static struct ipa_subdomains_req_params subdomain_requests[] = { }, { SUBDOMAINS_FILTER, ipa_subdomains_handler_done, - { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, NULL } + { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, + IPA_TRUST_DIRECTION, NULL } }, { RANGE_FILTER, ipa_subdomains_handler_ranges_done, diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h index 94027c091..3c5161d14 100644 --- a/src/providers/ipa/ipa_subdomains.h +++ b/src/providers/ipa/ipa_subdomains.h @@ -59,6 +59,15 @@ void ipa_ad_subdom_remove(struct be_ctx *be_ctx, int ipa_ad_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); + +const char *ipa_trust_dir2str(uint32_t direction); + +/* Utilities */ +#define IPA_TRUST_DIRECTION "ipaNTTrustDirection" + struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs); diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c index 237f60e03..56cf0162a 100644 --- a/src/providers/ipa/ipa_subdomains_server.c +++ b/src/providers/ipa/ipa_subdomains_server.c @@ -28,6 +28,81 @@ #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" +/* These constants are defined in MS-ADTS 6.1.6.7.1 + * https://msdn.microsoft.com/en-us/library/cc223768.aspx + */ +#define LSA_TRUST_DIRECTION_INBOUND 0x00000001 +#define LSA_TRUST_DIRECTION_OUTBOUND 0x00000002 + +static uint32_t default_direction(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb_ctx, + struct sysdb_attrs *attrs) +{ + struct ldb_dn *dn = NULL; + uint32_t direction; + + dn = ipa_subdom_ldb_dn(mem_ctx, ldb_ctx, attrs); + if (dn == NULL) { + /* Shouldn't happen, but let's try system keytab in this case */ + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot determine subdomain DN, falling back to two-way trust\n"); + return (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND); + } + + if (ipa_subdom_is_member_dom(dn) == true) { + /* It's expected member domains do not have the direction */ + direction = 0; + } else { + /* Old server? Default to 2way trust */ + direction = (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND); + } + + talloc_free(dn); + return direction; +} + +errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd, + struct ldb_context *ldb_ctx, + uint32_t *_direction) +{ + uint32_t ipa_trust_direction = 0; + uint32_t direction; + int ret; + + ret = sysdb_attrs_get_uint32_t(sd, IPA_TRUST_DIRECTION, + &ipa_trust_direction); + DEBUG(SSSDBG_TRACE_INTERNAL, + "Raw %s value: %d\n", IPA_TRUST_DIRECTION, ipa_trust_direction); + if (ret == ENOENT) { + direction = default_direction(sd, ldb_ctx, sd); + } else if (ret == EOK) { + /* Just store the AD value in SYSDB, we will check it while we're + * trying to use the trust */ + direction = ipa_trust_direction; + } else { + return ret; + } + + *_direction = direction; + return EOK; +} + +const char *ipa_trust_dir2str(uint32_t direction) +{ + if ((direction & LSA_TRUST_DIRECTION_OUTBOUND) + && (direction & LSA_TRUST_DIRECTION_INBOUND)) { + return "two-way trust"; + } else if (direction & LSA_TRUST_DIRECTION_OUTBOUND) { + return "one-way outbound: local domain is trusted by remote domain"; + } else if (direction & LSA_TRUST_DIRECTION_INBOUND) { + return "one-way inbound: local domain trusts the remote domain"; + } else if (direction == 0) { + return "trust direction not set"; + } + + return "unknown"; +} + static errno_t ipa_ad_ctx_new(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, |