summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-05-11 14:15:38 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-06-29 11:37:18 -0400
commit010c35e66398bbeb82fb1b31fc619b1a9eaf2d3d (patch)
tree6c31088a5922fac81ca62d0a599b822b093658ca
parente5b34f0166ae61468e53f369578e691ddb09cdd0 (diff)
downloadsssd-010c35e66398bbeb82fb1b31fc619b1a9eaf2d3d.tar.gz
sssd-010c35e66398bbeb82fb1b31fc619b1a9eaf2d3d.tar.xz
sssd-010c35e66398bbeb82fb1b31fc619b1a9eaf2d3d.zip
sudo responder: refresh expired rules
-rw-r--r--src/responder/sudo/sudosrv_get_sudorules.c137
1 files changed, 106 insertions, 31 deletions
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 6b8ee3692..c38c4da41 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -308,10 +308,41 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
static void
sudosrv_dp_req_done(struct tevent_req *req);
+static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ enum sss_dp_sudo_type type,
+ const char **attrs,
+ unsigned int flags,
+ const char *username,
+ uid_t uid,
+ char **groupnames,
+ struct sysdb_attrs ***_rules,
+ size_t *_count);
+
errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
{
- struct tevent_req *dpreq;
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct tevent_req *dpreq = NULL;
struct dp_callback_ctx *cb_ctx = NULL;
+ struct sysdb_ctx *sysdb = cmd_ctx->domain->sysdb;
+ char **groupnames = NULL;
+ size_t expired_rules_num = 0;
+ struct sysdb_attrs **expired_rules = NULL;
+ errno_t ret;
+ unsigned int flags = SYSDB_SUDO_FILTER_NONE;
+ const char *attrs[] = { SYSDB_NAME,
+ NULL };
+
+ if (cmd_ctx->domain == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Domain is not set!\n"));
+ return EFAULT;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+ return ENOMEM;
+ }
switch (cmd_ctx->type) {
case SSS_SUDO_DEFAULTS:
@@ -326,31 +357,86 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
break;
}
- dpreq = sss_dp_get_sudoers_send(cmd_ctx->cli_ctx,
- cmd_ctx->cli_ctx->rctx,
- cmd_ctx->domain, false,
- cmd_ctx->type,
- cmd_ctx->orig_username,
- 0, NULL);
- if (dpreq == NULL) {
+ /* Fetch all expired rules:
+ * sudo asks sssd twice - for defaults and for rules. If we refresh all
+ * expired rules for this user and defaults at once we will save one
+ * provider call
+ */
+ ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, sysdb,
+ NULL, &groupnames);
+ if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
- ("Cannot issue DP request.\n"));
- return EIO;
+ ("Unable to retrieve user info [%d]: %s\n", strerror(ret)));
+ goto done;
}
- cb_ctx = talloc_zero(cmd_ctx, struct dp_callback_ctx);
- if (!cb_ctx) {
- talloc_zfree(dpreq);
- return ENOMEM;
+ flags = SYSDB_SUDO_FILTER_INCLUDE_ALL
+ | SYSDB_SUDO_FILTER_INCLUDE_DFL
+ | SYSDB_SUDO_FILTER_ONLY_EXPIRED
+ | SYSDB_SUDO_FILTER_USERINFO;
+ ret = sudosrv_get_sudorules_query_cache(tmp_ctx, sysdb, cmd_ctx->type,
+ attrs, flags, cmd_ctx->orig_username,
+ cmd_ctx->uid, groupnames,
+ &expired_rules, &expired_rules_num);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to retrieve expired sudo rules [%d]: %s\n", strerror(ret)));
+ goto done;
}
- cb_ctx->callback = sudosrv_get_sudorules_dp_callback;
- cb_ctx->ptr = cmd_ctx;
- cb_ctx->cctx = cmd_ctx->cli_ctx;
- cb_ctx->mem_ctx = cmd_ctx;
+ if (expired_rules_num > 0) {
+ /* refresh expired rules then continue */
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Refreshing expired rules\n"));
+ dpreq = sss_dp_get_sudoers_send(tmp_ctx, cmd_ctx->cli_ctx->rctx,
+ cmd_ctx->domain, false,
+ SSS_DP_SUDO_REFRESH_RULES,
+ cmd_ctx->orig_username,
+ expired_rules_num, expired_rules);
+ if (dpreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Cannot issue DP request.\n"));
+ ret = EIO;
+ goto done;
+ }
+
+ cb_ctx = talloc_zero(tmp_ctx, struct dp_callback_ctx);
+ if (!cb_ctx) {
+ talloc_zfree(dpreq);
+ ret = ENOMEM;
+ goto done;
+ }
+
+ cb_ctx->callback = sudosrv_get_sudorules_dp_callback;
+ cb_ctx->ptr = cmd_ctx;
+ cb_ctx->cctx = cmd_ctx->cli_ctx;
+ cb_ctx->mem_ctx = cmd_ctx;
+
+ tevent_req_set_callback(dpreq, sudosrv_dp_req_done, cb_ctx);
+ ret = EAGAIN;
- tevent_req_set_callback(dpreq, sudosrv_dp_req_done, cb_ctx);
- return EAGAIN;
+ } else {
+ /* nothing is expired return what we have in the cache */
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n"));
+ ret = sudosrv_get_sudorules_from_cache(cmd_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Failed to make a request to our cache [%d]: %s\n",
+ ret, strerror(ret)));
+ goto done;
+ }
+ }
+
+ if (dpreq != NULL) {
+ talloc_steal(cmd_ctx->cli_ctx, dpreq);
+ }
+
+ if (cb_ctx != NULL) {
+ talloc_steal(cmd_ctx, cb_ctx);
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
}
static void
@@ -406,17 +492,6 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
sudosrv_cmd_done(cmd_ctx, ret);
}
-static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
- struct sysdb_ctx *sysdb,
- enum sss_dp_sudo_type type,
- const char **attrs,
- unsigned int flags,
- const char *username,
- uid_t uid,
- char **groupnames,
- struct sysdb_attrs ***_rules,
- size_t *_count);
-
static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx)
{
TALLOC_CTX *tmp_ctx;