summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-02-22 16:41:45 +0100
committerStephen Gallagher <sgallagh@redhat.com>2012-02-23 20:53:46 -0500
commit278284224aa10805d58c978977e43b1d1126f9b1 (patch)
treef3f55699f37ef2bb95b006c81e74921f00f57635
parentb4adc08bcc1cc225133146163989301b607c79b5 (diff)
downloadsssd-278284224aa10805d58c978977e43b1d1126f9b1.tar.gz
sssd-278284224aa10805d58c978977e43b1d1126f9b1.tar.bz2
sssd-278284224aa10805d58c978977e43b1d1126f9b1.zip
Honor case_sensitive option in sudo responder
https://fedorahosted.org/sssd/ticket/1205
-rw-r--r--src/responder/sudo/sudosrv_cache.c39
-rw-r--r--src/responder/sudo/sudosrv_cmd.c4
-rw-r--r--src/responder/sudo/sudosrv_get_sudorules.c76
-rw-r--r--src/responder/sudo/sudosrv_private.h2
4 files changed, 100 insertions, 21 deletions
diff --git a/src/responder/sudo/sudosrv_cache.c b/src/responder/sudo/sudosrv_cache.c
index a3a13cad..ee44a5ad 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 52023bec..8920ca28 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 cecede01..ba91df8c 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 7a7acc0c..1b4b604d 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;