diff options
-rw-r--r-- | src/responder/sudo/sudosrv_cmd.c | 61 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_get_sudorules.c | 114 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_private.h | 20 |
3 files changed, 102 insertions, 93 deletions
diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c index 8179ec0b..7fe02a2c 100644 --- a/src/responder/sudo/sudosrv_cmd.c +++ b/src/responder/sudo/sudosrv_cmd.c @@ -93,25 +93,22 @@ static errno_t sudosrv_cmd_send_error(TALLOC_CTX *mem_ctx, return sudosrv_cmd_send_reply(cmd_ctx, response_body, response_len); } -errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret) +errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret) { uint8_t *response_body = NULL; size_t response_len = 0; - size_t num_rules = dctx->res_count; - struct sysdb_attrs **rules = dctx->res; + size_t num_rules = cmd_ctx->num_rules; + struct sysdb_attrs **rules = cmd_ctx->rules; switch (ret) { case EOK: /* - * Parent of dctx->res is in-memory cache, we must not talloc_free it! + * Parent of cmd_ctx->rules is in-memory cache, we must not talloc_free it! */ - if (!dctx->cmd_ctx->sudo_ctx->timed) { - num_rules = dctx->res_count; - rules = dctx->res; - } else { + if (cmd_ctx->sudo_ctx->timed) { /* filter rules by time */ - ret = sysdb_sudo_filter_rules_by_time(dctx, dctx->res_count, - dctx->res, 0, + ret = sysdb_sudo_filter_rules_by_time(cmd_ctx, cmd_ctx->num_rules, + cmd_ctx->rules, 0, &num_rules, &rules); if (ret != EOK) { return EFAULT; @@ -119,14 +116,14 @@ errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret) } /* send result */ - ret = sudosrv_build_response(dctx->cmd_ctx, SSS_SUDO_ERROR_OK, + ret = sudosrv_build_response(cmd_ctx, SSS_SUDO_ERROR_OK, num_rules, rules, &response_body, &response_len); if (ret != EOK) { return EFAULT; } - ret = sudosrv_cmd_send_reply(dctx->cmd_ctx, response_body, response_len); + ret = sudosrv_cmd_send_reply(cmd_ctx, response_body, response_len); break; case EAGAIN: @@ -145,13 +142,13 @@ errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret) default: /* send error */ - ret = sudosrv_cmd_send_error(dctx->cmd_ctx, dctx->cmd_ctx, ret); + ret = sudosrv_cmd_send_error(cmd_ctx, cmd_ctx, ret); break; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n")); - talloc_free(dctx->cmd_ctx->cli_ctx); + talloc_free(cmd_ctx->cli_ctx); return EFAULT; } @@ -164,14 +161,15 @@ static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx) struct sudo_dom_ctx *dctx = NULL; uint8_t *query_body = NULL; size_t query_len = 0; - int ret = EOK; + errno_t ret = EOK; cmd_ctx = talloc_zero(cli_ctx, struct sudo_cmd_ctx); - if (!cmd_ctx) { + if (cmd_ctx == NULL) { /* kill the connection here as we have no context for reply */ DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory?\n")); return ENOMEM; } + cmd_ctx->domain = NULL; cmd_ctx->cli_ctx = cli_ctx; cmd_ctx->type = type; cmd_ctx->username = NULL; @@ -181,18 +179,17 @@ static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx) cmd_ctx->sudo_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct sudo_ctx); if (!cmd_ctx->sudo_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, ("sudo_ctx not set, killing connection!\n")); - talloc_free(cmd_ctx); - return EFAULT; + ret = EFAULT; + goto done; } /* create domain ctx */ dctx = talloc_zero(cmd_ctx, struct sudo_dom_ctx); - if (!dctx) { - return sudosrv_cmd_send_error(cmd_ctx, cmd_ctx, ENOMEM); + if (dctx == NULL) { + ret = ENOMEM; + goto done; } dctx->cmd_ctx = cmd_ctx; - dctx->orig_username = NULL; - dctx->cased_username = NULL; switch (cmd_ctx->type) { case SSS_DP_SUDO_USER: @@ -206,25 +203,28 @@ static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx) ret = sudosrv_parse_query(cmd_ctx, cli_ctx->rctx, query_body, query_len, - &cmd_ctx->username, &dctx->domain); + &cmd_ctx->username, &cmd_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query: %s\n", strerror(ret))); goto done; } DEBUG(SSSDBG_FUNC_DATA, ("Requesting sudo rules for [%s] from [%s]\n", - cmd_ctx->username, dctx->domain ? dctx->domain->name : "<ALL>")); + cmd_ctx->username, cmd_ctx->domain ? cmd_ctx->domain->name : "<ALL>")); - if (dctx->domain == NULL) { + if (cmd_ctx->domain == NULL) { /* this is a multidomain search */ dctx->domain = cli_ctx->rctx->domains; cmd_ctx->check_next = true; + } else { + dctx->domain = cmd_ctx->domain; + cmd_ctx->check_next = false; } /* try to find rules in in-memory cache */ ret = sudosrv_cache_lookup(cmd_ctx->sudo_ctx->cache, dctx, cmd_ctx->check_next, cmd_ctx->username, - &dctx->res_count, &dctx->res); + &cmd_ctx->num_rules, &cmd_ctx->rules); if (ret == EOK) { /* cache hit */ DEBUG(SSSDBG_FUNC_DATA, ("Returning rules for [%s@%s] " @@ -252,8 +252,8 @@ static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx) } ret = sudosrv_cache_lookup(cmd_ctx->sudo_ctx->cache, dctx, - cmd_ctx->check_next, cmd_ctx->username, - &dctx->res_count, &dctx->res); + cmd_ctx->check_next, cmd_ctx->username, + &cmd_ctx->num_rules, &cmd_ctx->rules); if (ret == EOK) { /* cache hit */ @@ -261,14 +261,15 @@ static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx) "from in-memory cache\n", dctx->domain->name)); } else if (ret == ENOENT) { /* cache expired or missed */ - ret = sudosrv_get_rules(dctx); + cmd_ctx->domain = dctx->domain; + ret = sudosrv_get_rules(cmd_ctx); } /* else error */ break; } done: - return sudosrv_cmd_done(dctx, ret); + return sudosrv_cmd_done(cmd_ctx, ret); } static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx) diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index e92e807f..c392027d 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -48,7 +48,7 @@ errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx) } /* OK, got the user from cache. Try to get the rules. */ - ret = sudosrv_get_rules(dctx); + ret = sudosrv_get_rules(dctx->cmd_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, ("Looking up the sudo rules from Data Provider\n")); @@ -195,14 +195,17 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) goto done; } - dctx->cased_username = talloc_move(dctx, &name); - dctx->orig_username = talloc_strdup(dctx, original_name); - if (dctx->orig_username== NULL) { + cmd_ctx->cased_username = talloc_move(cmd_ctx, &name); + cmd_ctx->orig_username = talloc_strdup(cmd_ctx, original_name); + if (cmd_ctx->orig_username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n")); ret = ENOMEM; goto done; } + /* and set domain */ + cmd_ctx->domain = dom; + DEBUG(SSSDBG_TRACE_FUNC, ("Returning info for user [%s@%s]\n", cmd_ctx->username, dctx->domain->name)); ret = EOK; @@ -262,37 +265,36 @@ static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, DEBUG(SSSDBG_OP_FAILURE, ("Could not look up the user [%d]: %s\n", ret, strerror(ret))); - sudosrv_cmd_done(dctx, EIO); + sudosrv_cmd_done(dctx->cmd_ctx, EIO); return; } DEBUG(SSSDBG_TRACE_INTERNAL, ("Looking up sudo rules..\n")); - ret = sudosrv_get_rules(dctx); + ret = sudosrv_get_rules(dctx->cmd_ctx); if (ret == EAGAIN) { goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Error getting sudo rules [%d]: %s\n", ret, strerror(ret))); - sudosrv_cmd_done(dctx, EIO); + sudosrv_cmd_done(dctx->cmd_ctx, EIO); return; } done: - sudosrv_cmd_done(dctx, ret); + sudosrv_cmd_done(dctx->cmd_ctx, ret); } -static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx); +static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx); static void sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void sudosrv_dp_req_done(struct tevent_req *req); -errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx) +errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) { struct tevent_req *dpreq; - struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx; struct dp_callback_ctx *cb_ctx = NULL; DEBUG(SSSDBG_TRACE_FUNC, ("getting rules for %s\n", @@ -300,25 +302,25 @@ errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx) dpreq = sss_dp_get_sudoers_send(cmd_ctx->cli_ctx, cmd_ctx->cli_ctx->rctx, - dctx->domain, false, + cmd_ctx->domain, false, cmd_ctx->type, - dctx->orig_username); + cmd_ctx->orig_username); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot issue DP request.\n")); return EIO; } - cb_ctx = talloc_zero(dctx, struct dp_callback_ctx); + cb_ctx = talloc_zero(cmd_ctx, struct dp_callback_ctx); if (!cb_ctx) { talloc_zfree(dpreq); return ENOMEM; } cb_ctx->callback = sudosrv_get_sudorules_dp_callback; - cb_ctx->ptr = dctx; - cb_ctx->cctx = dctx->cmd_ctx->cli_ctx; - cb_ctx->mem_ctx = dctx; + 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); return EAGAIN; @@ -329,8 +331,7 @@ sudosrv_dp_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); - struct sudo_dom_ctx *dctx = - talloc_get_type(cb_ctx->ptr, struct sudo_dom_ctx); + struct cli_ctx *cli_ctx = talloc_get_type(cb_ctx->cctx, struct cli_ctx); errno_t ret; dbus_uint16_t err_maj; @@ -343,7 +344,7 @@ sudosrv_dp_req_done(struct tevent_req *req) talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n")); - talloc_free(dctx->cmd_ctx->cli_ctx); + talloc_free(cli_ctx); return; } @@ -354,8 +355,7 @@ static void sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { - struct sudo_dom_ctx *dctx = - talloc_get_type(ptr, struct sudo_dom_ctx); + struct sudo_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct sudo_cmd_ctx); errno_t ret; if (err_maj) { @@ -364,25 +364,19 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg)); - - /* Loop to the next domain if possible */ - if (dctx->domain->next && dctx->cmd_ctx->check_next) { - dctx->domain = dctx->domain->next; - dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); - } } DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n")); - ret = sudosrv_get_sudorules_from_cache(dctx); + 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))); - sudosrv_cmd_done(dctx, EIO); + sudosrv_cmd_done(cmd_ctx, EIO); return; } - sudosrv_cmd_done(dctx, ret); + sudosrv_cmd_done(cmd_ctx, ret); } static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, @@ -394,21 +388,28 @@ static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, struct sysdb_attrs ***_rules, size_t *_count); -static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx) +static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx) { TALLOC_CTX *tmp_ctx; errno_t ret; struct sysdb_ctx *sysdb; - struct sudo_ctx *sudo_ctx = dctx->cmd_ctx->sudo_ctx; - uid_t uid; - char **groupnames; - const char *safe_name = dctx->cmd_ctx->username ? - dctx->cmd_ctx->username : "default rules"; + struct sudo_ctx *sudo_ctx = cmd_ctx->sudo_ctx; + uid_t uid = 0; + char **groupnames = NULL; + const char *debug_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) return ENOMEM; + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); + return ENOMEM; + } - sysdb = dctx->domain->sysdb; + sysdb = cmd_ctx->domain->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("sysdb context not found for this domain!\n")); @@ -416,23 +417,26 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx) goto done; } - if (dctx->cmd_ctx->type == SSS_DP_SUDO_USER) { - ret = sysdb_get_sudo_user_info(tmp_ctx, dctx->orig_username, - sysdb, &uid, &groupnames); + switch (cmd_ctx->type) { + case SSS_DP_SUDO_USER: + debug_name = cmd_ctx->cased_username; + ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, sysdb, + &uid, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve user info [%d]: %s\n", strerror(ret))); goto done; } - } else { - uid = 0; - groupnames = NULL; + break; + case SSS_DP_SUDO_DEFAULTS: + debug_name = "<default options>"; + break; } - ret = sudosrv_get_sudorules_query_cache(dctx, sysdb, dctx->cmd_ctx->type, - dctx->orig_username, + ret = sudosrv_get_sudorules_query_cache(cmd_ctx, sysdb, cmd_ctx->type, + cmd_ctx->orig_username, uid, groupnames, - &dctx->res, &dctx->res_count); + &cmd_ctx->rules, &cmd_ctx->num_rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve sudo rules [%d]: %s\n", strerror(ret))); @@ -440,20 +444,20 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx) } /* Store result in in-memory cache */ - ret = sudosrv_cache_set_entry(sudo_ctx->rctx->ev, sudo_ctx, - sudo_ctx->cache, dctx->domain, - dctx->cased_username, dctx->res_count, - dctx->res, sudo_ctx->cache_timeout); + ret = sudosrv_cache_set_entry(sudo_ctx->rctx->ev, sudo_ctx, sudo_ctx->cache, + cmd_ctx->domain, cmd_ctx->cased_username, + cmd_ctx->num_rules, cmd_ctx->rules, + sudo_ctx->cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Unable to store rules in cache for " - "[%s@%s]\n", safe_name, dctx->domain->name)); + "[%s@%s]\n", debug_name, cmd_ctx->domain->name)); } else { DEBUG(SSSDBG_FUNC_DATA, ("Rules for [%s@%s] stored in in-memory cache\n", - safe_name, dctx->domain->name)); + debug_name, cmd_ctx->domain->name)); } DEBUG(SSSDBG_TRACE_FUNC, ("Returning rules for [%s@%s]\n", - safe_name, dctx->domain->name)); + debug_name, cmd_ctx->domain->name)); ret = EOK; done: diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 03cc0a48..9c17c59d 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -23,6 +23,7 @@ #include <stdint.h> #include <talloc.h> +#include <sys/types.h> #include "src/db/sysdb.h" #include "responder/common/responder.h" @@ -57,20 +58,23 @@ struct sudo_cmd_ctx { struct cli_ctx *cli_ctx; struct sudo_ctx *sudo_ctx; enum sss_dp_sudo_type type; + + /* input data */ char *username; + const char *orig_username; + const char *cased_username; + struct sss_domain_info *domain; bool check_next; + + /* output data */ + struct sysdb_attrs **rules; + size_t num_rules; }; struct sudo_dom_ctx { struct sudo_cmd_ctx *cmd_ctx; struct sss_domain_info *domain; bool check_provider; - const char *orig_username; - const char *cased_username; - - /* cache results */ - struct sysdb_attrs **res; - size_t res_count; }; struct sudo_dp_request { @@ -80,11 +84,11 @@ struct sudo_dp_request { struct sss_cmd_table *get_sudo_cmds(void); -errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret); +errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret); errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx); -errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx); +errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx); errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, |