summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/providers/ldap/sdap_sudo.c250
1 files changed, 177 insertions, 73 deletions
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 8cc449f4..a0bba0d0 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -71,10 +71,18 @@ static int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
int *dp_error,
int *error);
+static void sdap_sudo_periodical_first_refresh_done(struct tevent_req *req);
+
static void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req);
static void sdap_sudo_periodical_smart_refresh_done(struct tevent_req *req);
+static int sdap_sudo_schedule_full_refresh(struct sdap_id_ctx *id_ctx,
+ time_t delay);
+
+static int sdap_sudo_schedule_smart_refresh(struct sdap_id_ctx *id_ctx,
+ time_t delay);
+
static void
sdap_sudo_shutdown(struct be_req *req)
{
@@ -86,7 +94,7 @@ struct bet_ops sdap_sudo_ops = {
.finalize = sdap_sudo_shutdown
};
-int sdap_sudo_setup_periodical_full_refresh(struct sdap_id_ctx *id_ctx);
+int sdap_sudo_setup_periodical_refresh(struct sdap_id_ctx *id_ctx);
int sdap_sudo_init(struct be_ctx *be_ctx,
struct sdap_id_ctx *id_ctx,
@@ -108,76 +116,97 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
return ret;
}
- ret = sdap_sudo_setup_periodical_full_refresh(id_ctx);
+ ret = sdap_sudo_setup_periodical_refresh(id_ctx);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, ("Unable to setup periodical full refresh"
+ DEBUG(SSSDBG_OP_FAILURE, ("Unable to setup periodical refresh"
"of sudo rules [%d]: %s\n", ret, strerror(ret)));
}
return EOK;
}
-int sdap_sudo_setup_periodical_full_refresh(struct sdap_id_ctx *id_ctx)
+int sdap_sudo_setup_periodical_refresh(struct sdap_id_ctx *id_ctx)
{
struct tevent_req *req;
+ time_t smart_default;
+ time_t smart_interval;
time_t full_interval;
time_t last_full;
- time_t now;
struct timeval tv;
int ret;
- /* setup periodical full refresh */
+ smart_interval = dp_opt_get_int(id_ctx->opts->basic,
+ SDAP_SUDO_SMART_REFRESH_INTERVAL);
+
full_interval = dp_opt_get_int(id_ctx->opts->basic,
SDAP_SUDO_FULL_REFRESH_INTERVAL);
- if (full_interval != 0) {
- ret = sysdb_sudo_get_last_full_refresh(id_ctx->be->sysdb, &last_full);
+
+ if (smart_interval == 0 && full_interval == 0) {
+ smart_default = id_ctx->opts->basic[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number;
+
+ DEBUG(SSSDBG_MINOR_FAILURE, ("At least one periodical update has to be "
+ "enabled. Setting smart refresh interval to default value (%d).\n",
+ smart_default));
+
+ ret = dp_opt_set_int(id_ctx->opts->basic,
+ SDAP_SUDO_SMART_REFRESH_INTERVAL,
+ smart_default);
if (ret != EOK) {
return ret;
}
+ }
- if (last_full == 0) {
- /* If this is the first startup, we need to kick off
- * an refresh immediately, to close a window where
- * clients requesting sudo information won't get an
- * immediate reply with no entries
- */
- tv = tevent_timeval_current();
- } else {
- /* At least one update has previously run,
- * so clients will get cached data.
- * We will delay the refresh so we don't slow
- * down the startup process if this is happening
- * during system boot.
- */
-
- now = time(NULL);
- if (last_full + full_interval < now) {
- /* delay at least by 10s */
- tv = tevent_timeval_current_ofs(10, 0);
- } else {
- tv = tevent_timeval_set(last_full + full_interval, 0);
- }
- }
-
- req = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
- tv, full_interval,
- sdap_sudo_full_refresh_send);
- if (req == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
- "rules! Full periodical refresh will not work.\n"));
- return ENOMEM;
+ if (full_interval <= smart_interval) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Full refresh interval has to be greater"
+ "than smart refresh interval. Periodical full refresh will be "
+ "disabled.\n"));
+ ret = dp_opt_set_int(id_ctx->opts->basic,
+ SDAP_SUDO_FULL_REFRESH_INTERVAL,
+ 0);
+ if (ret != EOK) {
+ return ret;
}
+ }
- tevent_req_set_callback(req, sdap_sudo_periodical_full_refresh_done,
- id_ctx);
+ ret = sysdb_sudo_get_last_full_refresh(id_ctx->be->sysdb, &last_full);
+ if (ret != EOK) {
+ return ret;
+ }
- DEBUG(SSSDBG_TRACE_FUNC, ("Full refresh scheduled at: %lld\n",
- (long long)tv.tv_sec));
+ if (last_full == 0) {
+ /* If this is the first startup, we need to kick off
+ * an refresh immediately, to close a window where
+ * clients requesting sudo information won't get an
+ * immediate reply with no entries
+ */
+ tv = tevent_timeval_current();
} else {
- DEBUG(SSSDBG_CONF_SETTINGS, ("Periodical full refresh of sudo rules "
- "is disabled\n"));
+ /* At least one update has previously run,
+ * so clients will get cached data.
+ * We will delay the refresh so we don't slow
+ * down the startup process if this is happening
+ * during system boot.
+ */
+
+ /* delay at least by 10s */
+ tv = tevent_timeval_current_ofs(10, 0);
}
+ req = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
+ tv, full_interval,
+ sdap_sudo_full_refresh_send);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
+ "rules! Periodical updates will not work!\n"));
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(req, sdap_sudo_periodical_first_refresh_done,
+ id_ctx);
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Full refresh scheduled at: %lld\n",
+ (long long)tv.tv_sec));
+
return EOK;
}
@@ -594,12 +623,10 @@ static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-static void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req)
+static void sdap_sudo_periodical_first_refresh_done(struct tevent_req *req)
{
struct tevent_req *subreq = NULL; /* req from sdap_sudo_full_refresh_send() */
- struct tevent_req *newreq = NULL;
struct sdap_id_ctx *id_ctx = NULL;
- struct timeval tv;
time_t delay;
int dp_error;
int error;
@@ -624,6 +651,7 @@ schedule:
id_ctx = tevent_req_callback_data(req, struct sdap_id_ctx);
talloc_zfree(req);
+ /* full refresh */
delay = dp_opt_get_int(id_ctx->opts->basic, SDAP_SUDO_FULL_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
@@ -632,29 +660,72 @@ schedule:
return;
}
- /* schedule new refresh */
- tv = tevent_timeval_current_ofs(delay, 0);
- newreq = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
- tv, delay, sdap_sudo_full_refresh_send);
- if (newreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
- "rules! Full periodical refresh will not work.\n"));
+ ret = sdap_sudo_schedule_full_refresh(id_ctx, delay);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Full periodical refresh will not work.\n"));
+ }
+
+ /* smart refresh */
+ delay = dp_opt_get_int(id_ctx->opts->basic, SDAP_SUDO_SMART_REFRESH_INTERVAL);
+ if (delay == 0) {
+ /* runtime configuration change? */
+ DEBUG(SSSDBG_TRACE_FUNC, ("Periodical smart refresh of sudo rules "
+ "is disabled\n"));
return;
}
- tevent_req_set_callback(newreq, sdap_sudo_periodical_full_refresh_done,
- id_ctx);
+ ret = sdap_sudo_schedule_smart_refresh(id_ctx, delay);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Smart periodical refresh will not work.\n"));
+ }
+}
- DEBUG(SSSDBG_TRACE_FUNC, ("Full refresh scheduled at: %lld\n",
- (long long)tv.tv_sec));
+static void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req)
+{
+ struct tevent_req *subreq = NULL; /* req from sdap_sudo_full_refresh_send() */
+ struct sdap_id_ctx *id_ctx = NULL;
+ time_t delay;
+ int dp_error;
+ int error;
+ int ret;
+
+ ret = sdap_sudo_timer_recv(req, req, &subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Sudo timer failed [%d]: %s\n", ret, strerror(ret)));
+ goto schedule;
+ }
+
+ ret = sdap_sudo_full_refresh_recv(subreq, &dp_error, &error);
+ if (dp_error != DP_ERR_OK || error != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Periodical full refresh of sudo rules "
+ "failed [dp_error: %d] ([%d]: %s)",
+ dp_error, error, strerror(error)));
+ goto schedule;
+ }
+
+schedule:
+ id_ctx = tevent_req_callback_data(req, struct sdap_id_ctx);
+ talloc_zfree(req);
+
+ delay = dp_opt_get_int(id_ctx->opts->basic, SDAP_SUDO_FULL_REFRESH_INTERVAL);
+ if (delay == 0) {
+ /* runtime configuration change? */
+ DEBUG(SSSDBG_TRACE_FUNC, ("Periodical full refresh of sudo rules "
+ "is disabled\n"));
+ return;
+ }
+
+ ret = sdap_sudo_schedule_full_refresh(id_ctx, delay);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Full periodical refresh will not work.\n"));
+ }
}
static void sdap_sudo_periodical_smart_refresh_done(struct tevent_req *req)
{
struct tevent_req *subreq = NULL; /* req from sdap_sudo_smart_refresh_send() */
- struct tevent_req *newreq = NULL;
struct sdap_id_ctx *id_ctx = NULL;
- struct timeval tv;
time_t delay;
int dp_error;
int error;
@@ -679,12 +750,6 @@ schedule:
id_ctx = tevent_req_callback_data(req, struct sdap_id_ctx);
talloc_zfree(req);
- if (id_ctx->srv_opts == NULL || id_ctx->srv_opts->supports_usn == false) {
- DEBUG(SSSDBG_TRACE_FUNC, ("USN values are not supported by the server. "
- "Smart refresh of sudo rules will not work!\n"));
- return;
- }
-
delay = dp_opt_get_int(id_ctx->opts->basic, SDAP_SUDO_SMART_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
@@ -693,19 +758,58 @@ schedule:
return;
}
+ ret = sdap_sudo_schedule_smart_refresh(id_ctx, delay);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Smart periodical refresh will not work.\n"));
+ }
+}
+
+static int sdap_sudo_schedule_full_refresh(struct sdap_id_ctx *id_ctx,
+ time_t delay)
+{
+ struct tevent_req *req = NULL;
+ struct timeval tv;
+
+ /* schedule new refresh */
+ tv = tevent_timeval_current_ofs(delay, 0);
+ req = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
+ tv, delay, sdap_sudo_full_refresh_send);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
+ "rules!\n"));
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(req, sdap_sudo_periodical_full_refresh_done,
+ id_ctx);
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Full refresh scheduled at: %lld\n",
+ (long long)tv.tv_sec));
+
+ return EOK;
+}
+
+static int sdap_sudo_schedule_smart_refresh(struct sdap_id_ctx *id_ctx,
+ time_t delay)
+{
+ struct tevent_req *req = NULL;
+ struct timeval tv;
+
/* schedule new refresh */
tv = tevent_timeval_current_ofs(delay, 0);
- newreq = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
- tv, delay, sdap_sudo_smart_refresh_send);
- if (newreq == NULL) {
+ req = sdap_sudo_timer_send(id_ctx, id_ctx->be->ev, id_ctx,
+ tv, delay, sdap_sudo_smart_refresh_send);
+ if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule smart refresh of sudo "
- "rules! Smart periodical refresh will not work.\n"));
- return;
+ "rules!\n"));
+ return ENOMEM;
}
- tevent_req_set_callback(newreq, sdap_sudo_periodical_smart_refresh_done,
+ tevent_req_set_callback(req, sdap_sudo_periodical_smart_refresh_done,
id_ctx);
DEBUG(SSSDBG_TRACE_FUNC, ("Smart refresh scheduled at: %lld\n",
(long long)tv.tv_sec));
+
+ return EOK;
}