>From 32f57db9f9060a29a1c1e0540b05ee066229933e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 2 Jun 2015 13:34:20 +0200 Subject: [PATCH 04/29] SYSDB: Add realm to sysdb_master_domain_add_info Adding realm to both master domain and subdomain will make it easier to set and select forest roots. Even master domains can be forest members, it's preferable to avoid special-casing as much as possible. Includes a unit test. --- src/db/sysdb.h | 4 +++- src/db/sysdb_subdomains.c | 22 +++++++++++++++++++- src/providers/ad/ad_id.c | 11 +++++++++- src/providers/ad/ad_subdomains.c | 10 +++++++++ src/providers/ipa/ipa_subdomains.c | 10 ++++++++- src/tests/cmocka/test_sysdb_subdomains.c | 35 ++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 3d0d07c6a56f2168ffe26f46d17973bc09330aaf..9ee7ff541f731814c204fafc832f39da3ff7af9a 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -439,7 +439,9 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain); errno_t sysdb_master_domain_update(struct sss_domain_info *domain); errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, - const char *flat, const char *id, + const char *realm, + const char *flat, + const char *id, const char* forest); errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name); diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index 816dd5d2c211bc0c3180a1489eab6799e9b70f57..05ec414d93764277bb19045da9fed354b0b2f2b7 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -552,7 +552,9 @@ done: } errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, - const char *flat, const char *id, + const char *realm, + const char *flat, + const char *id, const char* forest) { TALLOC_CTX *tmp_ctx; @@ -632,6 +634,24 @@ errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, do_update = true; } + if (realm != NULL && (domain->realm == NULL || + strcmp(domain->realm, realm) != 0)) { + ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, + LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM, realm); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + do_update = true; + } + if (do_update == false) { ret = EOK; goto done; diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c index d8ea26875daf1ad38131eef7c1dd9957e776000f..3df91dfd5a7882de8e30d3bbcca7f69cef2c5a17 100644 --- a/src/providers/ad/ad_id.c +++ b/src/providers/ad/ad_id.c @@ -454,6 +454,7 @@ struct ad_enumeration_state { struct sdap_id_op *sdap_op; struct tevent_context *ev; + const char *realm; struct sdap_domain *sdom; struct sdap_domain *sditer; }; @@ -493,6 +494,14 @@ ad_enumeration_send(TALLOC_CTX *mem_ctx, state->sditer = state->sdom; state->id_ctx = talloc_get_type(ectx->pvt, struct ad_id_ctx); + state->realm = dp_opt_get_cstring(state->id_ctx->ad_options->basic, + AD_KRB5_REALM); + if (state->realm == NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm or hostname.\n"); + ret = EINVAL; + goto fail; + } + state->sdap_op = sdap_id_op_create(state, state->id_ctx->ldap_ctx->conn_cache); if (state->sdap_op == NULL) { @@ -575,7 +584,7 @@ ad_enumeration_master_done(struct tevent_req *subreq) return; } - ret = sysdb_master_domain_add_info(state->sdom->dom, + ret = sysdb_master_domain_add_info(state->sdom->dom, state->realm, flat_name, master_sid, forest); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info\n"); diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index da496b6dea63cfddf1c6a456a76c9547a0fca116..8e69cef18cd2f64ee3860bcc328b76789312ccad 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -595,6 +595,7 @@ static void ad_subdomains_master_dom_done(struct tevent_req *req) { struct ad_subdomains_req_ctx *ctx; errno_t ret; + const char *realm; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); @@ -607,7 +608,16 @@ static void ad_subdomains_master_dom_done(struct tevent_req *req) goto done; } + realm = dp_opt_get_cstring(ctx->sd_ctx->ad_id_ctx->ad_options->basic, + AD_KRB5_REALM); + if (realm == NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm or hostname.\n"); + ret = EINVAL; + goto done; + } + ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain, + realm, ctx->flat_name, ctx->master_sid, ctx->forest); if (ret != EOK) { diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index b82bda23a9b5ae133cb2a6d67aae2f74e5a1f206..7587aabe5a768e1817e5857f7e27fbfe1a8b455b 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -1416,6 +1416,7 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req) if (reply_count) { const char *flat = NULL; const char *id = NULL; + const char *realm; ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &flat); if (ret != EOK) { @@ -1427,8 +1428,15 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req) goto done; } + realm = dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic, + IPA_KRB5_REALM); + if (realm == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); + goto done; + } + ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain, - flat, id, NULL); + realm, flat, id, NULL); } else { ctx->search_base_iter++; ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER); diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c index 441537467e98c58051e0cf91c6b1c243d6326ab3..6744a4226bcd3bb3b8c8c712830d79d7f43b62ae 100644 --- a/src/tests/cmocka/test_sysdb_subdomains.c +++ b/src/tests/cmocka/test_sysdb_subdomains.c @@ -143,6 +143,38 @@ static void test_sysdb_subdomain_create(void **state) assert_true(test_ctx->tctx->dom->subdomains->disabled); } +static void test_sysdb_master_domain_ops(void **state) +{ + errno_t ret; + struct subdom_test_ctx *test_ctx = + talloc_get_type(*state, struct subdom_test_ctx); + + + ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, + "realm1", "flat1", "id1", "forest1"); + assert_int_equal(ret, EOK); + + ret = sysdb_master_domain_update(test_ctx->tctx->dom); + assert_int_equal(ret, EOK); + + assert_string_equal(test_ctx->tctx->dom->realm, "realm1"); + assert_string_equal(test_ctx->tctx->dom->flat_name, "flat1"); + assert_string_equal(test_ctx->tctx->dom->domain_id, "id1"); + assert_string_equal(test_ctx->tctx->dom->forest, "forest1"); + + ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, + "realm2", "flat2", "id2", "forest2"); + assert_int_equal(ret, EOK); + + ret = sysdb_master_domain_update(test_ctx->tctx->dom); + assert_int_equal(ret, EOK); + + assert_string_equal(test_ctx->tctx->dom->realm, "realm2"); + assert_string_equal(test_ctx->tctx->dom->flat_name, "flat2"); + assert_string_equal(test_ctx->tctx->dom->domain_id, "id2"); + assert_string_equal(test_ctx->tctx->dom->forest, "forest2"); +} + int main(int argc, const char *argv[]) { int rv; @@ -158,6 +190,9 @@ int main(int argc, const char *argv[]) }; const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_sysdb_master_domain_ops, + test_sysdb_subdom_setup, + test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_subdomain_create, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), -- 2.1.0