summaryrefslogtreecommitdiffstats
path: root/src/responder
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-04-13 09:50:55 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-06-29 11:37:16 -0400
commit710472d946f6c337a095699dfd79134fa8b9eab9 (patch)
treeee1425acc6d2a5d13a4ed8838ac13d17d792c936 /src/responder
parent60a729bfa2aee7529a0c9a276057a47a80381994 (diff)
downloadsssd-710472d946f6c337a095699dfd79134fa8b9eab9.tar.gz
sssd-710472d946f6c337a095699dfd79134fa8b9eab9.tar.xz
sssd-710472d946f6c337a095699dfd79134fa8b9eab9.zip
sudo responder: remove code duplication in commands
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/sudo/sudosrv_cmd.c210
-rw-r--r--src/responder/sudo/sudosrv_get_sudorules.c78
-rw-r--r--src/responder/sudo/sudosrv_private.h47
-rw-r--r--src/responder/sudo/sudosrv_query.c225
4 files changed, 283 insertions, 277 deletions
diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c
index f72e2be7b..8179ec0bd 100644
--- a/src/responder/sudo/sudosrv_cmd.c
+++ b/src/responder/sudo/sudosrv_cmd.c
@@ -78,8 +78,14 @@ static errno_t sudosrv_cmd_send_error(TALLOC_CTX *mem_ctx,
size_t response_len = 0;
int ret = EOK;
- ret = sudosrv_response_append_uint32(mem_ctx, error,
- &response_body, &response_len);
+ if (error == EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Everything is fine but we are "
+ "returning error?\n"));
+ return EFAULT;
+ }
+
+ ret = sudosrv_build_response(mem_ctx, error, 0, NULL,
+ &response_body, &response_len);
if (ret != EOK) {
return ret;
}
@@ -113,9 +119,9 @@ errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret)
}
/* send result */
- ret = sudosrv_get_sudorules_build_response(dctx->cmd_ctx, SSS_SUDO_ERROR_OK,
- num_rules, rules,
- &response_body, &response_len);
+ ret = sudosrv_build_response(dctx->cmd_ctx, SSS_SUDO_ERROR_OK,
+ num_rules, rules,
+ &response_body, &response_len);
if (ret != EOK) {
return EFAULT;
}
@@ -152,15 +158,13 @@ errno_t sudosrv_cmd_done(struct sudo_dom_ctx *dctx, int ret)
return EOK;
}
-static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx)
+static int sudosrv_cmd(enum sss_dp_sudo_type type, struct cli_ctx *cli_ctx)
{
- char *rawname = NULL;
- char *domname = NULL;
+ struct sudo_cmd_ctx *cmd_ctx = NULL;
+ struct sudo_dom_ctx *dctx = NULL;
uint8_t *query_body = NULL;
size_t query_len = 0;
int ret = EOK;
- struct sudo_cmd_ctx *cmd_ctx = NULL;
- struct sudo_dom_ctx *dctx = NULL;
cmd_ctx = talloc_zero(cli_ctx, struct sudo_cmd_ctx);
if (!cmd_ctx) {
@@ -169,12 +173,15 @@ static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx)
return ENOMEM;
}
cmd_ctx->cli_ctx = cli_ctx;
- cmd_ctx->type = SSS_DP_SUDO_USER;
+ cmd_ctx->type = type;
+ cmd_ctx->username = NULL;
+ cmd_ctx->check_next = false;
/* get responder 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;
}
@@ -187,136 +194,91 @@ static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx)
dctx->orig_username = NULL;
dctx->cased_username = NULL;
- /* get query */
- sss_packet_get_body(cli_ctx->creq->in, &query_body, &query_len);
- if (query_len <= 0 || query_body == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Query is empty\n"));
- ret = EINVAL;
- goto done;
- }
+ switch (cmd_ctx->type) {
+ case SSS_DP_SUDO_USER:
+ /* get query */
+ sss_packet_get_body(cli_ctx->creq->in, &query_body, &query_len);
+ if (query_len <= 0 || query_body == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Query is empty\n"));
+ ret = EINVAL;
+ goto done;
+ }
- /* If the body isn't valid UTF-8, fail */
- if (!sss_utf8_check(query_body, query_len - 1)) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Supplied data is not valid UTF-8 string\n"));
- ret = EINVAL;
- goto done;
- }
+ ret = sudosrv_parse_query(cmd_ctx, cli_ctx->rctx,
+ query_body, query_len,
+ &cmd_ctx->username, &dctx->domain);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query: %s\n", strerror(ret)));
+ goto done;
+ }
- /* parse query */
- rawname = sudosrv_get_sudorules_parse_query(cmd_ctx,
- (const char*)query_body,
- query_len);
- if (rawname == NULL) {
- ret = ENOMEM;
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Unable to parse 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>"));
- domname = NULL;
- ret = sss_parse_name_for_domains(cmd_ctx, cli_ctx->rctx->domains, rawname,
- &domname, &cmd_ctx->username);
- if (ret != EOK) {
- DEBUG(2, ("Invalid name received [%s]\n", rawname));
- ret = ENOENT;
- goto done;
- }
+ if (dctx->domain == NULL) {
+ /* this is a multidomain search */
+ dctx->domain = cli_ctx->rctx->domains;
+ cmd_ctx->check_next = true;
+ }
+
+ /* 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);
+ if (ret == EOK) {
+ /* cache hit */
+ DEBUG(SSSDBG_FUNC_DATA, ("Returning rules for [%s@%s] "
+ "from in-memory cache\n", cmd_ctx->username, dctx->domain->name));
+ } else if (ret == ENOENT) {
+ /* cache expired or missed */
+ ret = sudosrv_get_sudorules(dctx);
+ } /* else error */
- DEBUG(SSSDBG_FUNC_DATA, ("Requesting sudo rules for [%s] from [%s]\n",
- cmd_ctx->username, domname ? domname : "<ALL>"));
+ break;
+ case SSS_DP_SUDO_DEFAULTS:
+ DEBUG(SSSDBG_FUNC_DATA, ("Requesting cn=defaults\n"));
- if (domname) {
- dctx->domain = responder_get_domain(dctx, cli_ctx->rctx, domname);
+ /* sudo currently does not support domain selection
+ * so find first available domain
+ * TODO - support domain selection */
+ dctx->domain = cli_ctx->rctx->domains;
+ while (dctx->domain && dctx->domain->fqnames) {
+ dctx->domain = dctx->domain->next;
+ }
if (!dctx->domain) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("No valid domain found\n"));
ret = ENOENT;
goto done;
}
- } else {
- /* this is a multidomain search */
- dctx->domain = cli_ctx->rctx->domains;
- cmd_ctx->check_next = true;
- }
- /* 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);
- if (ret == EOK) {
- /* cache hit */
- DEBUG(SSSDBG_FUNC_DATA, ("Returning rules for [%s@%s] "
- "from in-memory cache\n", cmd_ctx->username, dctx->domain->name));
- } else if (ret == ENOENT) {
- /* cache expired or missed */
- ret = sudosrv_get_sudorules(dctx);
- } /* else error */
+ ret = sudosrv_cache_lookup(cmd_ctx->sudo_ctx->cache, dctx,
+ cmd_ctx->check_next, cmd_ctx->username,
+ &dctx->res_count, &dctx->res);
+
+ if (ret == EOK) {
+ /* cache hit */
+ DEBUG(SSSDBG_FUNC_DATA, ("Returning defaults settings for [%s] "
+ "from in-memory cache\n", dctx->domain->name));
+ } else if (ret == ENOENT) {
+ /* cache expired or missed */
+ ret = sudosrv_get_rules(dctx);
+ } /* else error */
+
+ break;
+ }
done:
return sudosrv_cmd_done(dctx, ret);
}
-static int sudosrv_cmd_get_defaults(struct cli_ctx *cli_ctx)
+static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx)
{
- int ret = EOK;
- struct sudo_cmd_ctx *cmd_ctx = NULL;
- struct sudo_dom_ctx *dctx = NULL;
-
- cmd_ctx = talloc_zero(cli_ctx, struct sudo_cmd_ctx);
- if (!cmd_ctx) {
- /* kill the connection here as we have no context for reply */
- DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory?\n"));
- return ENOMEM;
- }
- cmd_ctx->cli_ctx = cli_ctx;
- cmd_ctx->type = SSS_DP_SUDO_DEFAULTS;
- cmd_ctx->username = NULL;
- cmd_ctx->check_next = false;
-
- /* get responder 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"));
- return EFAULT;
- }
-
- /* create domain ctx */
- dctx = talloc_zero(cmd_ctx, struct sudo_dom_ctx);
- if (!dctx) {
- return sudosrv_cmd_send_error(cmd_ctx, cmd_ctx, ENOMEM);
- }
- dctx->cmd_ctx = cmd_ctx;
- dctx->orig_username = NULL;
- dctx->cased_username = NULL;
-
- DEBUG(SSSDBG_FUNC_DATA, ("Requesting cn=defaults\n"));
-
- /* sudo currently does not support domain selection
- * so find first available domain
- * TODO - support domain selection */
- dctx->domain = cli_ctx->rctx->domains;
- while (dctx->domain && dctx->domain->fqnames) {
- dctx->domain = dctx->domain->next;
- }
- if (!dctx->domain) {
- DEBUG(SSSDBG_MINOR_FAILURE, ("No valid domain found\n"));
- ret = ENOENT;
- goto done;
- }
-
- /* 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);
- if (ret == EOK) {
- /* cache hit */
- DEBUG(SSSDBG_FUNC_DATA, ("Returning defaults settings for [%s] "
- "from in-memory cache\n", dctx->domain->name));
- } else if (ret == ENOENT) {
- /* cache expired or missed */
- ret = sudosrv_get_rules(dctx);
- } /* else error */
+ return sudosrv_cmd(SSS_DP_SUDO_USER, cli_ctx);
+}
-done:
- return sudosrv_cmd_done(dctx, ret);
+static int sudosrv_cmd_get_defaults(struct cli_ctx *cli_ctx)
+{
+ return sudosrv_cmd(SSS_DP_SUDO_DEFAULTS, cli_ctx);
}
struct cli_protocol_version *register_cli_protocol_version(void)
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index abdf3e76f..e92e807f8 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -602,81 +602,3 @@ sort_sudo_rules(struct sysdb_attrs **rules, size_t count)
sudo_order_cmp_fn);
return EOK;
}
-
-char * sudosrv_get_sudorules_parse_query(TALLOC_CTX *mem_ctx,
- const char *query_body,
- int query_len)
-{
- /* empty string or not NULL terminated */
- if (query_len < 2 || strnlen(query_body, query_len) == query_len) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query.\n"));
- return NULL;
- }
-
- return talloc_strdup(mem_ctx, query_body);
-}
-
-/*
- * Response format:
- * <error_code(uint32_t)><num_entries(uint32_t)><rule1><rule2>...
- * <ruleN> = <num_attrs(uint32_t)><attr1><attr2>...
- * <attrN> = <name(char*)>\0<num_values(uint32_t)><value1(char*)>\0<value2(char*)>\0...
- *
- * if <error_code> is not SSS_SUDO_ERROR_OK, the rest of the data is skipped.
- */
-int sudosrv_get_sudorules_build_response(TALLOC_CTX *mem_ctx,
- uint32_t error,
- int rules_num,
- struct sysdb_attrs **rules,
- uint8_t **_response_body,
- size_t *_response_len)
-{
- uint8_t *response_body = NULL;
- size_t response_len = 0;
- TALLOC_CTX *tmp_ctx = NULL;
- int i = 0;
- int ret = EOK;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
- return ENOMEM;
- }
-
- /* error code */
- ret = sudosrv_response_append_uint32(tmp_ctx, error,
- &response_body, &response_len);
- if (ret != EOK) {
- goto fail;
- }
-
- if (error != SSS_SUDO_ERROR_OK) {
- goto done;
- }
-
- /* rules count */
- ret = sudosrv_response_append_uint32(tmp_ctx, (uint32_t)rules_num,
- &response_body, &response_len);
- if (ret != EOK) {
- goto fail;
- }
-
- /* rules */
- for (i = 0; i < rules_num; i++) {
- ret = sudosrv_response_append_rule(tmp_ctx, rules[i]->num, rules[i]->a,
- &response_body, &response_len);
- if (ret != EOK) {
- goto fail;
- }
- }
-
-done:
- *_response_body = talloc_steal(mem_ctx, response_body);
- *_response_len = response_len;
-
- ret = EOK;
-
-fail:
- talloc_free(tmp_ctx);
- return ret;
-}
diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h
index fd96ba9a8..03cc0a48c 100644
--- a/src/responder/sudo/sudosrv_private.h
+++ b/src/responder/sudo/sudosrv_private.h
@@ -86,40 +86,19 @@ errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx);
errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx);
-char * sudosrv_get_sudorules_parse_query(TALLOC_CTX *mem_ctx,
- const char *query_body,
- int query_len);
-
-int sudosrv_get_sudorules_build_response(TALLOC_CTX *mem_ctx,
- uint32_t error,
- int rules_num,
- struct sysdb_attrs **rules,
- uint8_t **_response_body,
- size_t *_response_len);
-
-int sudosrv_response_append_string(TALLOC_CTX *mem_ctx,
- const char *str,
- size_t str_len,
- uint8_t **_response_body,
- size_t *_response_len);
-
-int sudosrv_response_append_uint32(TALLOC_CTX *mem_ctx,
- uint32_t number,
- uint8_t **_response_body,
- size_t *_response_len);
-
-int sudosrv_response_append_rule(TALLOC_CTX *mem_ctx,
- int attrs_num,
- struct ldb_message_element *attrs,
- uint8_t **_response_body,
- size_t *_response_len);
-
-int sudosrv_response_append_attr(TALLOC_CTX *mem_ctx,
- const char *name,
- unsigned int values_num,
- struct ldb_val *values,
- uint8_t **_response_body,
- size_t *_response_len);
+errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
+ struct resp_ctx *rctx,
+ uint8_t *query_body,
+ size_t query_len,
+ char **_username,
+ struct sss_domain_info **_domain);
+
+errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
+ uint32_t error,
+ int rules_num,
+ struct sysdb_attrs **rules,
+ uint8_t **_response_body,
+ size_t *_response_len);
struct tevent_req *
sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx,
diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c
index 8b98da6e8..dd9e1e880 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -26,11 +26,11 @@
#include "util/util.h"
#include "responder/sudo/sudosrv_private.h"
-int sudosrv_response_append_string(TALLOC_CTX *mem_ctx,
- const char *str,
- size_t str_len,
- uint8_t **_response_body,
- size_t *_response_len)
+static int sudosrv_response_append_string(TALLOC_CTX *mem_ctx,
+ const char *str,
+ size_t str_len,
+ uint8_t **_response_body,
+ size_t *_response_len)
{
size_t response_len = *_response_len;
uint8_t *response_body = *_response_body;
@@ -50,10 +50,10 @@ int sudosrv_response_append_string(TALLOC_CTX *mem_ctx,
return EOK;
}
-int sudosrv_response_append_uint32(TALLOC_CTX *mem_ctx,
- uint32_t number,
- uint8_t **_response_body,
- size_t *_response_len)
+static int sudosrv_response_append_uint32(TALLOC_CTX *mem_ctx,
+ uint32_t number,
+ uint8_t **_response_body,
+ size_t *_response_len)
{
size_t response_len = *_response_len;
uint8_t *response_body = *_response_body;
@@ -72,11 +72,71 @@ int sudosrv_response_append_uint32(TALLOC_CTX *mem_ctx,
return EOK;
}
-int sudosrv_response_append_rule(TALLOC_CTX *mem_ctx,
- int attrs_num,
- struct ldb_message_element *attrs,
- uint8_t **_response_body,
- size_t *_response_len)
+static int sudosrv_response_append_attr(TALLOC_CTX *mem_ctx,
+ const char *name,
+ unsigned int values_num,
+ struct ldb_val *values,
+ uint8_t **_response_body,
+ size_t *_response_len)
+{
+ uint8_t *response_body = *_response_body;
+ size_t response_len = *_response_len;
+ TALLOC_CTX *tmp_ctx = NULL;
+ int i = 0;
+ int ret = EOK;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+ return ENOMEM;
+ }
+
+ /* attr name */
+ ret = sudosrv_response_append_string(tmp_ctx, name, strlen(name) + 1,
+ &response_body, &response_len);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ /* values count */
+ ret = sudosrv_response_append_uint32(tmp_ctx, values_num,
+ &response_body, &response_len);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ /* values */
+ for (i = 0; i < values_num; i++) {
+ if (strlen((char*)(values[i].data)) != values[i].length) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("value is not a string"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sudosrv_response_append_string(tmp_ctx,
+ (const char*)values[i].data,
+ values[i].length + 1,
+ &response_body, &response_len);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ *_response_body = talloc_steal(mem_ctx, response_body);
+ *_response_len = response_len;
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static int sudosrv_response_append_rule(TALLOC_CTX *mem_ctx,
+ int attrs_num,
+ struct ldb_message_element *attrs,
+ uint8_t **_response_body,
+ size_t *_response_len)
{
uint8_t *response_body = *_response_body;
size_t response_len = *_response_len;
@@ -117,18 +177,26 @@ done:
return ret;
}
-int sudosrv_response_append_attr(TALLOC_CTX *mem_ctx,
- const char *name,
- unsigned int values_num,
- struct ldb_val *values,
- uint8_t **_response_body,
- size_t *_response_len)
+/*
+ * Response format:
+ * <error_code(uint32_t)><num_entries(uint32_t)><rule1><rule2>...
+ * <ruleN> = <num_attrs(uint32_t)><attr1><attr2>...
+ * <attrN> = <name(char*)>\0<num_values(uint32_t)><value1(char*)>\0<value2(char*)>\0...
+ *
+ * if <error_code> is not SSS_SUDO_ERROR_OK, the rest of the data is skipped.
+ */
+errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
+ uint32_t error,
+ int rules_num,
+ struct sysdb_attrs **rules,
+ uint8_t **_response_body,
+ size_t *_response_len)
{
- uint8_t *response_body = *_response_body;
- size_t response_len = *_response_len;
+ uint8_t *response_body = NULL;
+ size_t response_len = 0;
TALLOC_CTX *tmp_ctx = NULL;
int i = 0;
- int ret = EOK;
+ errno_t ret = EOK;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -136,42 +204,117 @@ int sudosrv_response_append_attr(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- /* attr name */
- ret = sudosrv_response_append_string(tmp_ctx, name, strlen(name) + 1,
+ /* error code */
+ ret = sudosrv_response_append_uint32(tmp_ctx, error,
&response_body, &response_len);
if (ret != EOK) {
+ goto fail;
+ }
+
+ if (error != SSS_SUDO_ERROR_OK) {
goto done;
}
- /* values count */
- ret = sudosrv_response_append_uint32(tmp_ctx, values_num,
+ /* rules count */
+ ret = sudosrv_response_append_uint32(tmp_ctx, (uint32_t)rules_num,
&response_body, &response_len);
if (ret != EOK) {
- goto done;
+ goto fail;
}
- /* values */
- for (i = 0; i < values_num; i++) {
- if (strlen((char*)(values[i].data)) != values[i].length) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("value is not a string"));
- ret = EINVAL;
- goto done;
- }
-
- ret = sudosrv_response_append_string(tmp_ctx,
- (const char*)values[i].data,
- values[i].length + 1,
- &response_body, &response_len);
+ /* rules */
+ for (i = 0; i < rules_num; i++) {
+ ret = sudosrv_response_append_rule(tmp_ctx, rules[i]->num, rules[i]->a,
+ &response_body, &response_len);
if (ret != EOK) {
- goto done;
+ goto fail;
}
}
+done:
*_response_body = talloc_steal(mem_ctx, response_body);
*_response_len = response_len;
ret = EOK;
+fail:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/*
+ * Query format:
+ * <username[@domain]>
+ */
+errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
+ struct resp_ctx *rctx,
+ uint8_t *query_body,
+ size_t query_len,
+ char **_username,
+ struct sss_domain_info **_domain)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct sss_domain_info *domain = NULL;
+ size_t offset = 0;
+ size_t rawname_len = 0;
+ char *rawname = NULL;
+ char *domainname = NULL;
+ char *username = NULL;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+ return ENOMEM;
+ }
+
+ /* username[@domain] */
+
+ rawname = (char*)(query_body + offset);
+ rawname_len = query_len - offset; /* strlen + zero */
+
+ if (rawname[rawname_len - 1] != '\0') {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Username is not zero terminated\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (rawname_len < 2) { /* at least one character and zero */
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Query does not contain username\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (!sss_utf8_check((uint8_t*)rawname, rawname_len - 1)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Supplied data is not valid UTF-8 string\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ /* parse username */
+
+ ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains, rawname,
+ &domainname, &username);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid name received [%s]\n", rawname));
+ goto done;
+ }
+
+ if (domainname != NULL) {
+ /* mem_ctx because it duplicates only subdomains not domains
+ * so I cannot easily steal it */
+ domain = responder_get_domain(mem_ctx, rctx, domainname);
+ if (domain == NULL) {
+ ret = ENOENT;
+ goto done;
+ }
+ }
+
+ *_username = talloc_steal(mem_ctx, username);
+ *_domain = domain; /* do not steal on mem_ctx */
+
+ ret = EOK;
+
done:
talloc_free(tmp_ctx);
return ret;