>From 6e2f09bf0c3bd4ad4f9246166ce02deb6f0a9ec7 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 12 May 2015 14:24:00 +0200 Subject: [PATCH 01/29] SYSDB: Store trust direction for subdomains We need to store the subdomain trust direction in order to recover the structure after SSSD restart. --- src/confdb/confdb.h | 8 ++++++ src/db/sysdb.h | 4 ++- src/db/sysdb_subdomains.c | 51 ++++++++++++++++++++++++++++++++--- src/providers/ad/ad_subdomains.c | 3 ++- src/providers/ipa/ipa_subdomains.c | 3 ++- src/tests/cmocka/test_fqnames.c | 3 ++- src/tests/cmocka/test_nss_srv.c | 6 +++-- src/tests/sysdb-tests.c | 55 +++++++++++++++++++++++++++++++------- src/util/domain_info_utils.c | 4 ++- src/util/util.h | 3 ++- 10 files changed, 118 insertions(+), 22 deletions(-) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index c8c91288cd63df7629a98802b7b5373df92d6ca4..03dc27195d43ed4758c84eede19941869abad7c7 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -206,6 +206,13 @@ struct confdb_ctx; struct config_file_ctx; +enum trust_direction { + SD_TRUST_DIRECTION_NOT_SET, + SD_TRUST_DIRECTION_OUTBOUND, + SD_TRUST_DIRECTION_TWOWAY +}; + + /** * Data structure storing all of the basic features * of a domain. @@ -259,6 +266,7 @@ struct sss_domain_info { char *flat_name; char *domain_id; char *forest; + enum trust_direction trust_direction; struct timeval subdomains_last_checked; bool has_views; diff --git a/src/db/sysdb.h b/src/db/sysdb.h index c3d2c1406321e01b325e04e0e3f263893eb91b2e..3d0d07c6a56f2168ffe26f46d17973bc09330aaf 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -138,6 +138,7 @@ #define SYSDB_SUBDOMAIN_MPG "mpg" #define SYSDB_SUBDOMAIN_ENUM "enumerate" #define SYSDB_SUBDOMAIN_FOREST "memberOfForest" +#define SYSDB_SUBDOMAIN_TRUST_DIRECTION "trustDirection" #define SYSDB_BASE_ID "baseID" #define SYSDB_ID_RANGE_SIZE "idRangeSize" @@ -430,7 +431,8 @@ errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name); errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, - bool mpg, bool enumerate, const char *forest); + bool mpg, bool enumerate, const char *forest, + enum trust_direction trust_direction); errno_t sysdb_update_subdomains(struct sss_domain_info *domain); diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index 06e9e094e79df3ed554eb7f57579ec10e5b963bd..85edd859f269976713b6f35c37dc0bab3d1b6e2e 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -36,6 +36,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) SYSDB_SUBDOMAIN_MPG, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, + SYSDB_SUBDOMAIN_TRUST_DIRECTION, NULL}; struct sss_domain_info *dom; struct ldb_dn *basedn; @@ -46,6 +47,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) const char *forest; bool mpg; bool enumerate; + int trust_direction; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -106,6 +108,10 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) forest = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_FOREST, NULL); + trust_direction = ldb_msg_find_attr_as_int(res->msgs[i], + SYSDB_SUBDOMAIN_TRUST_DIRECTION, + SD_TRUST_DIRECTION_NOT_SET); + /* explicitly use dom->next as we need to check 'disabled' domains */ for (dom = domain->subdomains; dom; dom = dom->next) { if (strcasecmp(dom->name, name) == 0) { @@ -155,7 +161,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) if (dom->enumerate != enumerate) { DEBUG(SSSDBG_TRACE_INTERNAL, - "MPG state change from [%s] to [%s]!\n", + "enumerate state change from [%s] to [%s]!\n", dom->enumerate ? "true" : "false", enumerate ? "true" : "false"); dom->enumerate = enumerate; @@ -204,13 +210,21 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) } } + if (dom->trust_direction != trust_direction) { + DEBUG(SSSDBG_TRACE_INTERNAL, + "Trust direction change from [%d] to [%d]!\n", + dom->trust_direction, trust_direction); + dom->trust_direction = trust_direction; + } + break; } } /* If not found in loop it is a new subdomain */ if (dom == NULL) { dom = new_subdomain(domain, domain, name, realm, - flat, id, mpg, enumerate, forest); + flat, id, mpg, enumerate, forest, + trust_direction); if (dom == NULL) { ret = ENOMEM; goto done; @@ -524,7 +538,8 @@ done: errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, - bool mpg, bool enumerate, const char *forest) + bool mpg, bool enumerate, const char *forest, + enum trust_direction trust_direction) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; @@ -537,6 +552,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, SYSDB_SUBDOMAIN_MPG, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, + SYSDB_SUBDOMAIN_TRUST_DIRECTION, NULL}; const char *tmp_str; bool tmp_bool; @@ -547,6 +563,8 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, int mpg_flags = 0; int enum_flags = 0; int forest_flags = 0; + int td_flags = 0; + enum trust_direction tmp_td; int ret; tmp_ctx = talloc_new(NULL); @@ -578,6 +596,7 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, mpg_flags = LDB_FLAG_MOD_ADD; enum_flags = LDB_FLAG_MOD_ADD; if (forest) forest_flags = LDB_FLAG_MOD_ADD; + if (trust_direction) td_flags = LDB_FLAG_MOD_ADD; } else if (res->count != 1) { ret = EINVAL; goto done; @@ -622,10 +641,18 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, forest_flags = LDB_FLAG_MOD_REPLACE; } } + + tmp_td = ldb_msg_find_attr_as_uint(res->msgs[0], + SYSDB_SUBDOMAIN_TRUST_DIRECTION, + SD_TRUST_DIRECTION_NOT_SET); + if (tmp_td != trust_direction) { + td_flags = LDB_FLAG_MOD_REPLACE; + } } if (!store && realm_flags == 0 && flat_flags == 0 && id_flags == 0 - && mpg_flags == 0 && enum_flags == 0 && forest_flags == 0) { + && mpg_flags == 0 && enum_flags == 0 && forest_flags == 0 + && td_flags == 0) { ret = EOK; goto done; } @@ -738,6 +765,22 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, } } + if (td_flags) { + ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_TRUST_DIRECTION, + td_flags, NULL); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = ldb_msg_add_fmt(msg, SYSDB_SUBDOMAIN_TRUST_DIRECTION, + "%u", trust_direction); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + } + ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add subdomain attributes to " diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index 5a6e9338d6dc581fba4f76e8b28f92a558eb6294..da496b6dea63cfddf1c6a456a76c9547a0fca116 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -309,7 +309,8 @@ ad_subdom_store(struct ad_subdomains_ctx *ctx, sid_str); ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str, - mpg, enumerate, domain->forest); + mpg, enumerate, domain->forest, + SD_TRUST_DIRECTION_NOT_SET); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index f863b806c8fed01f498d18b953832ebeba7a85d3..b82bda23a9b5ae133cb2a6d67aae2f74e5a1f206 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -693,7 +693,8 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent, } ret = sysdb_subdomain_store(parent->sysdb, name, realm, flat, - id, mpg, enumerate, forest); + id, mpg, enumerate, forest, + SD_TRUST_DIRECTION_NOT_SET); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; diff --git a/src/tests/cmocka/test_fqnames.c b/src/tests/cmocka/test_fqnames.c index 0326d5a645bad0396d8b20f635e6ee6b3e4b5587..a85e8337c333b8ad846ba39da6b8167193fc542b 100644 --- a/src/tests/cmocka/test_fqnames.c +++ b/src/tests/cmocka/test_fqnames.c @@ -309,7 +309,8 @@ static int parse_name_test_setup(void **state) * discovered */ test_ctx->subdom = new_subdomain(dom, dom, SUBDOMNAME, NULL, SUBFLATNAME, - NULL, false, false, NULL); + NULL, false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); assert_non_null(test_ctx->subdom); check_leaks_push(test_ctx); diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index 9119d4b154473e1df72d23a795cc5bc2efd24d2a..659cfc68c54f2a1a162970a75f3fbccbeeeb8eaa 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -2666,12 +2666,14 @@ static int nss_subdom_test_setup(void **state) subdomain = new_subdomain(nss_test_ctx, nss_test_ctx->tctx->dom, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); assert_non_null(subdomain); ret = sysdb_subdomain_store(nss_test_ctx->tctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom); diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 6a77c6eebc4d8e29c09d67f9b1de17939591410a..1dc228df2c4a0c5dbada32ac8bf6efcfbdb080bd 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -1312,7 +1312,8 @@ START_TEST (test_sysdb_get_user_attr_subdomain) /* Create subdomain */ subdomain = new_subdomain(test_ctx, test_ctx->domain, "test.sub", "TEST.SUB", "test", "S-3", - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_if(subdomain == NULL, "Failed to create new subdomain."); ret = sss_names_init_from_args(test_ctx, @@ -5235,21 +5236,25 @@ START_TEST(test_sysdb_subdomain_create) ret = sysdb_subdomain_store(test_ctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_OUTBOUND); fail_if(ret != EOK, "Could not set up the test (dom1)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); - fail_if(test_ctx->domain->subdomains == NULL, "Empyt sub-domain list."); + fail_if(test_ctx->domain->subdomains == NULL, "Empty sub-domain list."); fail_if(strcmp(test_ctx->domain->subdomains->name, dom1[0]) != 0, "Unexpected sub-domain found, expected [%s], got [%s]", dom1[0], test_ctx->domain->subdomains->name); + fail_unless(test_ctx->domain->subdomains->trust_direction == \ + SD_TRUST_DIRECTION_OUTBOUND); ret = sysdb_subdomain_store(test_ctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_TWOWAY); fail_if(ret != EOK, "Could not set up the test (dom2)"); ret = sysdb_update_subdomains(test_ctx->domain); @@ -5260,6 +5265,30 @@ START_TEST(test_sysdb_subdomain_create) fail_if(strcmp(test_ctx->domain->subdomains->next->name, dom2[0]) != 0, "Unexpected sub-domain found, expected [%s], got [%s]", dom2[0], test_ctx->domain->subdomains->next->name); + fail_unless(test_ctx->domain->subdomains->next->trust_direction == \ + SD_TRUST_DIRECTION_TWOWAY); + + /* Reverse the trust directions */ + ret = sysdb_subdomain_store(test_ctx->sysdb, + dom1[0], dom1[1], dom1[2], dom1[3], + false, false, NULL, + SD_TRUST_DIRECTION_TWOWAY); + fail_if(ret != EOK, "Could not set up the test (dom1)"); + + ret = sysdb_subdomain_store(test_ctx->sysdb, + dom2[0], dom2[1], dom2[2], dom2[3], + false, false, NULL, + SD_TRUST_DIRECTION_OUTBOUND); + fail_if(ret != EOK, "Could not set up the test (dom2)"); + + ret = sysdb_update_subdomains(test_ctx->domain); + fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", + ret, strerror(ret)); + + fail_unless(test_ctx->domain->subdomains->trust_direction == \ + SD_TRUST_DIRECTION_TWOWAY); + fail_unless(test_ctx->domain->subdomains->next->trust_direction == \ + SD_TRUST_DIRECTION_OUTBOUND); ret = sysdb_subdomain_delete(test_ctx->sysdb, dom2[0]); fail_if(ret != EOK, "Could not delete subdomain"); @@ -5294,11 +5323,13 @@ START_TEST(test_sysdb_subdomain_store_user) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); @@ -5365,11 +5396,13 @@ START_TEST(test_sysdb_subdomain_user_ops) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); @@ -5420,11 +5453,13 @@ START_TEST(test_sysdb_subdomain_group_ops) subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], - false, false, NULL); + false, false, NULL, + SD_TRUST_DIRECTION_NOT_SET); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index dc306848c3b3ba87a5ada1867878e13826da00a8..aa79a3a374f2ac8d060b5d81ca093670dbb4e4d3 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -203,7 +203,8 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, const char *id, bool mpg, bool enumerate, - const char *forest) + const char *forest, + enum trust_direction trust_direction) { struct sss_domain_info *dom; @@ -281,6 +282,7 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, dom->enumerate = enumerate; dom->fqnames = true; dom->mpg = mpg; + dom->trust_direction = trust_direction; /* If the parent domain explicitly limits ID ranges, the subdomain * should honour the limits as well. */ diff --git a/src/util/util.h b/src/util/util.h index c86bcea5b01f6bc02d18b17a2660262105648cf9..5be1c816b7566ff4ae97b5ff61a5824d982475f9 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -577,7 +577,8 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, const char *id, bool mpg, bool enumerate, - const char *forest); + const char *forest, + enum trust_direction trust_direction); errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, -- 2.1.0