diff options
-rw-r--r-- | src/responder/sudo/sudosrv_cache.c | 39 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_cmd.c | 4 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_get_sudorules.c | 76 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_private.h | 2 |
4 files changed, 100 insertions, 21 deletions
diff --git a/src/responder/sudo/sudosrv_cache.c b/src/responder/sudo/sudosrv_cache.c index a3a13cadf..ee44a5ad6 100644 --- a/src/responder/sudo/sudosrv_cache.c +++ b/src/responder/sudo/sudosrv_cache.c @@ -266,11 +266,23 @@ errno_t sudosrv_cache_lookup(hash_table_t *table, struct sysdb_attrs ***rules) { struct sss_domain_info *domain = dctx->domain; + char *name = NULL; errno_t ret; if (!check_next) { - return sudosrv_cache_lookup_internal(table, dctx->domain, username, - num_rules, rules); + if (username != NULL) { + name = sss_get_cased_name(NULL, username, + dctx->domain->case_sensitive); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n")); + ret = ENOMEM; + goto done; + } + } + + ret = sudosrv_cache_lookup_internal(table, dctx->domain, name, + num_rules, rules); + goto done; } while (domain != NULL) { @@ -279,15 +291,26 @@ errno_t sudosrv_cache_lookup(hash_table_t *table, continue; } - ret = sudosrv_cache_lookup_internal(table, domain, username, + if (username != NULL) { + talloc_free(name); + name = sss_get_cased_name(NULL, username, + dctx->domain->case_sensitive); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n")); + ret = ENOMEM; + goto done; + } + } + + ret = sudosrv_cache_lookup_internal(table, domain, name, num_rules, rules); if (ret == EOK) { /* user is in this domain */ dctx->domain = domain; - return ret; + goto done; } else if (ret != ENOENT) { /* error */ - return ret; + goto done; } /* user is not in this domain cache, check next */ @@ -295,5 +318,9 @@ errno_t sudosrv_cache_lookup(hash_table_t *table, } /* user is not in cache */ - return ENOENT; + ret = ENOENT; + +done: + talloc_free(name); + return ret; } diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c index 52023bec3..8920ca282 100644 --- a/src/responder/sudo/sudosrv_cmd.c +++ b/src/responder/sudo/sudosrv_cmd.c @@ -185,6 +185,8 @@ static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx) goto done; } dctx->cmd_ctx = cmd_ctx; + dctx->orig_username = NULL; + dctx->cased_username = NULL; /* get query */ sss_packet_get_body(cli_ctx->creq->in, &query_body, &query_len); @@ -284,6 +286,8 @@ static int sudosrv_cmd_get_defaults(struct cli_ctx *cli_ctx) goto done; } dctx->cmd_ctx = cmd_ctx; + dctx->orig_username = NULL; + dctx->cased_username = NULL; DEBUG(SSSDBG_FUNC_DATA, ("Requesting cn=defaults\n")); diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index cecede016..ba91df8cc 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -68,6 +68,7 @@ static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) { + TALLOC_CTX *tmp_ctx = NULL; struct sss_domain_info *dom = dctx->domain; struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx; struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx; @@ -75,8 +76,16 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) time_t cache_expire = 0; struct tevent_req *dpreq; struct dp_callback_ctx *cb_ctx; + const char *original_name = NULL; + char *name = NULL; errno_t ret; + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); + return ENOMEM; + } + while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ @@ -89,28 +98,40 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) /* make sure to update the dctx if we changed domain */ dctx->domain = dom; + talloc_free(name); + name = sss_get_cased_name(tmp_ctx, cmd_ctx->username, + dom->case_sensitive); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n")); + ret = ENOMEM; + goto done; + } + DEBUG(SSSDBG_FUNC_DATA, ("Requesting info about [%s@%s]\n", - cmd_ctx->username, dom->name)); + name, dom->name)); ret = sysdb_get_ctx_from_list(cli_ctx->rctx->db_list, dctx->domain, &sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("sysdb context not found for this domain!\n")); - return EIO; + ret = EIO; + goto done; } - ret = sysdb_getpwnam(dctx, sysdb, cmd_ctx->username, &dctx->user); + ret = sysdb_getpwnam(dctx, sysdb, name, &dctx->user); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to make request to our cache!\n")); - return EIO; + ret = EIO; + goto done; } if (dctx->user->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, ("getpwnam call returned more than one result !?!\n")); - return EIO; + ret = EIO; + goto done; } if (dctx->user->count == 0 && !dctx->check_provider) { @@ -122,7 +143,8 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) } DEBUG(SSSDBG_MINOR_FAILURE, ("No results for getpwnam call\n")); - return ENOENT; + ret = ENOENT; + goto done; } /* One result found, check cache expiry */ @@ -141,13 +163,15 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) if (!dpreq) { DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory sending data provider request\n")); - return ENOMEM; + ret = ENOMEM; + goto done; } cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(dpreq); - return ENOMEM; + ret = ENOMEM; + goto done; } cb_ctx->callback = sudosrv_check_user_dp_callback; @@ -158,15 +182,37 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx); /* tell caller we are in an async call */ - return EAGAIN; + ret = EAGAIN; + goto done; + } + + /* user is stored in cache, remember cased and original name */ + original_name = ldb_msg_find_attr_as_string(dctx->user->msgs[0], + SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n")); + ret = EFAULT; + goto done; + } + + dctx->cased_username = talloc_move(dctx, &name); + dctx->orig_username = talloc_strdup(dctx, original_name); + if (dctx->orig_username== NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n")); + ret = ENOMEM; + goto done; } DEBUG(SSSDBG_TRACE_FUNC, ("Returning info for user [%s@%s]\n", cmd_ctx->username, dctx->domain->name)); - return EOK; + ret = EOK; + goto done; } - return ENOENT; + ret = ENOENT; +done: + talloc_free(tmp_ctx); + return ret; } static void sudosrv_dp_send_acct_req_done(struct tevent_req *req) @@ -256,7 +302,7 @@ errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx) cmd_ctx->cli_ctx->rctx, dctx->domain, false, cmd_ctx->type, - cmd_ctx->username); + dctx->orig_username); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot issue DP request.\n")); @@ -373,7 +419,7 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx) } if (dctx->cmd_ctx->type == SSS_DP_SUDO_USER) { - ret = sysdb_get_sudo_user_info(tmp_ctx, dctx->cmd_ctx->username, + ret = sysdb_get_sudo_user_info(tmp_ctx, dctx->orig_username, sysdb, &uid, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -386,7 +432,7 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx) } ret = sudosrv_get_sudorules_query_cache(dctx, sysdb, dctx->cmd_ctx->type, - dctx->cmd_ctx->username, + dctx->orig_username, uid, groupnames, &dctx->res, &dctx->res_count); if (ret != EOK) { @@ -398,7 +444,7 @@ 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->cmd_ctx->username, dctx->res_count, + dctx->cased_username, dctx->res_count, dctx->res, sudo_ctx->cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Unable to store rules in cache for " diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 7a7acc0c5..1b4b604d6 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -65,6 +65,8 @@ 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 ldb_result *user; |