summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-11-12 16:30:57 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-11-25 19:38:54 +0100
commitcd5033e86bb4065d75188e2b6ef287a4421344c8 (patch)
treecb1f7f37664290dc406a222f37de59e7d34df17c
parent2fe140d3a41e1ac66400069d35adc9379348c1e5 (diff)
downloadsssd-cd5033e86bb4065d75188e2b6ef287a4421344c8.zip
sssd-cd5033e86bb4065d75188e2b6ef287a4421344c8.tar.gz
sssd-cd5033e86bb4065d75188e2b6ef287a4421344c8.tar.xz
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. Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--src/db/sysdb_views.c12
-rw-r--r--src/providers/ipa/ipa_subdomains.c97
2 files changed, 85 insertions, 24 deletions
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index 079e2bb..8cc279a 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 883558c..6fdb0be 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;
@@ -903,7 +912,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)
@@ -938,7 +947,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
@@ -1030,6 +1039,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;
@@ -1089,24 +1099,79 @@ 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");
+ "View name changed, this is not supported at runtime. " \
+ "Please restart SSSD to get the new view applied.\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");
}
}
}
@@ -1122,7 +1187,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)
@@ -1222,7 +1287,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)
@@ -1308,7 +1373,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)
@@ -1370,7 +1435,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);
@@ -1505,12 +1570,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;
}