From 4cba79d103eaccf4432d22305c5caa973f3ab4e6 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 12 Nov 2014 16:30:57 +0100 Subject: [PATCH 3/3] views: allow view name change at startup Currently some manual steps are needed on a FreeIPA to switch from one view to another. With this patch the IPA provider checks at startup if the view name changed and does the needed steps automatically. Besides saving the new view name this includes removing the old view data and marking the user and group entries as invalid. --- src/db/sysdb_views.c | 12 ++--- src/providers/ipa/ipa_subdomains.c | 92 +++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c index f7899b2..5721a43 100644 --- a/src/db/sysdb_views.c +++ b/src/db/sysdb_views.c @@ -123,17 +123,13 @@ errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, goto done; } else { /* view name changed */ - /* not supported atm */ - DEBUG(SSSDBG_CRIT_FAILURE, - "View name changed from [%s] to [%s]. NOT SUPPORTED.\n", - tmp_str, view_name); - ret = ENOTSUP; - goto done; + DEBUG(SSSDBG_CONF_SETTINGS, + "View name changed from [%s] to [%s].\n", tmp_str, view_name); } + } else { + add_view_name = true; } - add_view_name = true; - msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 9281aab..63f64c2 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -80,8 +80,17 @@ struct ipa_subdomains_ctx { struct tevent_timer *timer_event; bool configured_explicit; time_t disabled_until; + bool view_read_at_init; }; +static void ipa_subdomains_done(struct ipa_subdomains_ctx *sd_ctx, + struct be_req *req, int dp_err, + int error, const char *errstr) +{ + sd_ctx->view_read_at_init = true; + return be_req_terminate(req, dp_err, error, errstr); +} + struct be_ctx *ipa_get_subdomains_be_ctx(struct be_ctx *be_ctx) { struct ipa_subdomains_ctx *subdom_ctx; @@ -895,7 +904,7 @@ done: if (ret == EOK) { dp_error = DP_ERR_OK; } - be_req_terminate(be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx, be_req, dp_error, ret, NULL); } static void ipa_subdomains_get_conn_done(struct tevent_req *req) @@ -930,7 +939,7 @@ static void ipa_subdomains_get_conn_done(struct tevent_req *req) return; fail: - be_req_terminate(ctx->be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static errno_t @@ -1022,6 +1031,7 @@ static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx) static void ipa_get_view_name_done(struct tevent_req *req) { int ret; + int sret; struct ipa_subdomains_req_ctx *ctx; size_t reply_count; struct sdap_deref_attrs **reply = NULL; @@ -1081,24 +1091,76 @@ static void ipa_get_view_name_done(struct tevent_req *req) view_name = SYSDB_DEFAULT_VIEW_NAME; } + DEBUG(SSSDBG_TRACE_ALL, "read_at_init [%s] current view [%s].\n", ctx->sd_ctx->view_read_at_init ? "true" : "false", ctx->sd_ctx->id_ctx->view_name); + if (ctx->sd_ctx->id_ctx->view_name != NULL - && strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0) { + && strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0 + && ctx->sd_ctx->view_read_at_init) { DEBUG(SSSDBG_CRIT_FAILURE, "View name changed, this is currently not supported!\n"); } else { + ctx->sd_ctx->view_read_at_init = true; + /* View name changed */ + if (ctx->sd_ctx->id_ctx->view_name != NULL) { + ret = sysdb_transaction_start(ctx->sd_ctx->be_ctx->domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); + goto done; + } + + if (strcmp(ctx->sd_ctx->id_ctx->view_name, + SYSDB_DEFAULT_VIEW_NAME) != 0) { + /* Old view was not the default view, delete view tree */ + ret = sysdb_delete_view_tree(ctx->sd_ctx->be_ctx->domain->sysdb, + ctx->sd_ctx->id_ctx->view_name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_delete_view_tree failed.\n"); + sret = sysdb_transaction_cancel( + ctx->sd_ctx->be_ctx->domain->sysdb); + if (sret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_transaction_cancel failed.\n"); + goto done; + } + goto done; + } + } + + ret = sysdb_invalidate_overrides( + ctx->sd_ctx->be_ctx->domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_invalidate_overrides failed.\n"); + sret = sysdb_transaction_cancel( + ctx->sd_ctx->be_ctx->domain->sysdb); + if (sret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed.\n"); + goto done; + } + goto done; + } + + ret = sysdb_transaction_commit(ctx->sd_ctx->be_ctx->domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed.\n"); + goto done; + } + + /* TODO: start referesh task */ + } + ret = sysdb_update_view_name(ctx->sd_ctx->be_ctx->domain->sysdb, view_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add/update view name to sysdb.\n"); } else { + talloc_free(ctx->sd_ctx->id_ctx->view_name); + ctx->sd_ctx->id_ctx->view_name = talloc_strdup(ctx->sd_ctx->id_ctx, + view_name); if (ctx->sd_ctx->id_ctx->view_name == NULL) { - ctx->sd_ctx->id_ctx->view_name = - talloc_strdup(ctx->sd_ctx->id_ctx, - view_name); - if (ctx->sd_ctx->id_ctx->view_name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Cannot copy view name.\n"); - } + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot copy view name.\n"); } } } @@ -1114,7 +1176,7 @@ done: if (ret == EOK) { dp_error = DP_ERR_OK; } - be_req_terminate(ctx->be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdomains_handler_done(struct tevent_req *req) @@ -1214,7 +1276,7 @@ done: if (ret == EOK) { dp_error = DP_ERR_OK; } - be_req_terminate(ctx->be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx) @@ -1300,7 +1362,7 @@ done: if (ret == EOK) { dp_error = DP_ERR_OK; } - be_req_terminate(ctx->be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdomains_handler_master_done(struct tevent_req *req) @@ -1362,7 +1424,7 @@ done: if (ret == EOK) { dp_error = DP_ERR_OK; } - be_req_terminate(ctx->be_req, dp_error, ret, NULL); + ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdom_online_cb(void *pvt); @@ -1497,12 +1559,12 @@ void ipa_subdomains_handler(struct be_req *be_req) if (ctx->disabled_until > now) { DEBUG(SSSDBG_TRACE_ALL, "Subdomain provider disabled.\n"); - be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); + ipa_subdomains_done(ctx, be_req, DP_ERR_OK, EOK, NULL); return; } if (ctx->last_refreshed > now - IPA_SUBDOMAIN_REFRESH_LIMIT) { - be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); + ipa_subdomains_done(ctx, be_req, DP_ERR_OK, EOK, NULL); return; } -- 1.8.3.1