summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2015-05-26 12:41:36 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-06-14 21:47:11 +0200
commit05d935cc9d04f03522d0bb44598d22d99b085926 (patch)
tree7cc82e7037293d8ef9f037f837db52d266416376
parent89ddc9ed474e9ac2b1e7bccb0a58610babf26cf8 (diff)
downloadsssd-05d935cc9d04f03522d0bb44598d22d99b085926.tar.gz
sssd-05d935cc9d04f03522d0bb44598d22d99b085926.tar.xz
sssd-05d935cc9d04f03522d0bb44598d22d99b085926.zip
IPA: Include ipaNTTrustDirection in the attribute set for trusted domains
Allows to distinguish the trust directions for trusted domains. For domains where we don't know the direction in server mode, we assume two-way trusts. Member domains do not have the direction, but rather the forest root direction is used. Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r--src/providers/ipa/ipa_subdomains.c77
-rw-r--r--src/providers/ipa/ipa_subdomains.h9
-rw-r--r--src/providers/ipa/ipa_subdomains_server.c75
-rw-r--r--src/util/util_errors.c1
-rw-r--r--src/util/util_errors.h1
5 files changed, 142 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,
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index f219d9787..6bf3566f7 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -75,6 +75,7 @@ struct err_string error_to_str[] = {
{ "Unexpected cache entry type" }, /* ERR_UNEXPECTED_ENTRY_TYPE */
{ "Failed to resolve one of user groups" }, /* ERR_SIMPLE_GROUPS_MISSING */
{ "Home directory is NULL" }, /* ERR_HOMEDIR_IS_NULL */
+ { "Unsupported trust direction" }, /* ERR_TRUST_NOT_SUPPORTED */
{ "ERR_LAST" } /* ERR_LAST */
};
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 74f8e13db..86f6fa13b 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -97,6 +97,7 @@ enum sssd_errors {
ERR_UNEXPECTED_ENTRY_TYPE,
ERR_SIMPLE_GROUPS_MISSING,
ERR_HOMEDIR_IS_NULL,
+ ERR_TRUST_NOT_SUPPORTED,
ERR_LAST /* ALWAYS LAST */
};