static int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx) { struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; time_t smart_default; time_t smart_interval; time_t full_interval; time_t last_full; time_t delay; int ret; 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 (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 (%ld).\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 (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; } } ret = sysdb_sudo_get_last_full_refresh(id_ctx->be->domain, &last_full); 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 */ delay = 0; } 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. */ /* delay at least by 10s */ delay = 10; } ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx, SDAP_SUDO_REFRESH_FULL, sdap_sudo_periodical_first_refresh_done, delay, full_interval, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to schedule full refresh of sudo " "rules! Periodical updates will not work!\n"); return ret; } return EOK; }
errno_t sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, struct dp_option *opts, be_ptask_send_t full_send_fn, be_ptask_recv_t full_recv_fn, be_ptask_send_t smart_send_fn, be_ptask_recv_t smart_recv_fn, void *pvt) { time_t smart; time_t full; time_t delay; time_t last_refresh; errno_t ret; smart = dp_opt_get_int(opts, SDAP_SUDO_SMART_REFRESH_INTERVAL); full = dp_opt_get_int(opts, SDAP_SUDO_FULL_REFRESH_INTERVAL); if (smart == 0 && full == 0) { /* We don't allow both types to be disabled. At least smart refresh * needs to be enabled. In this case smart refresh will catch up new * and modified rules and deleted rules are caught when expired. */ smart = opts[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number; DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be " "enabled. Setting smart refresh interval to default value " "(%ld) seconds.\n", smart); } else if (full > 0 && full <= smart) { /* In this case it does not make any sense to run smart refresh. */ smart = 0; DEBUG(SSSDBG_CONF_SETTINGS, "Smart refresh interval has to be lower " "than full refresh interval. Periodical smart refresh will be " "disabled.\n"); } ret = sysdb_sudo_get_last_full_refresh(be_ctx->domain, &last_refresh); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to obtain time of last full " "refresh. Assuming none was performed so far.\n"); last_refresh = 0; } if (last_refresh == 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 */ delay = 0; } 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. */ delay = 10; } /* Full refresh. * * Disable when offline and run immediately when SSSD goes back online. * Since we have periodical online check we don't have to run this task * when offline. */ if (full > 0) { ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full, BE_PTASK_OFFLINE_DISABLE, 0, full_send_fn, full_recv_fn, pvt, "SUDO Full Refresh", NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } } /* Smart refresh. * * Disable when offline and reschedule normally when SSSD goes back online. * Since we have periodical online check we don't have to run this task * when offline. */ if (smart > 0) { ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, smart, BE_PTASK_OFFLINE_DISABLE, 0, smart_send_fn, smart_recv_fn, pvt, "SUDO Smart Refresh", NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } } return EOK; }
static int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx) { struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; struct tevent_req *req; time_t smart_default; time_t smart_interval; time_t full_interval; time_t last_full; struct timeval tv; int ret; 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 (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 (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; } } ret = sysdb_sudo_get_last_full_refresh(id_ctx->be->sysdb, &last_full); 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. */ /* delay at least by 10s */ tv = tevent_timeval_current_ofs(10, 0); } req = sdap_sudo_timer_send(sudo_ctx, id_ctx->be->ev, sudo_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, sudo_ctx); DEBUG(SSSDBG_TRACE_FUNC, ("Full refresh scheduled at: %lld\n", (long long)tv.tv_sec)); return EOK; }