From 414e89774091c97393676a945d7fdcbcd03df6b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 9 Feb 2016 10:52:51 +0100
Subject: [PATCH 3/4] sudo: do not use tevent when parsing query

---
 src/responder/sudo/sudosrv_cmd.c           |  30 +++++---
 src/responder/sudo/sudosrv_get_sudorules.c |   2 +-
 src/responder/sudo/sudosrv_private.h       |  16 ++--
 src/responder/sudo/sudosrv_query.c         | 115 +++++------------------------
 4 files changed, 45 insertions(+), 118 deletions(-)

diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c
index c68a6980ba817071e3766a0ddf7c158499d47aec..bdf01fac73886ed91507f318575c4af546ad7528 100644
--- a/src/responder/sudo/sudosrv_cmd.c
+++ b/src/responder/sudo/sudosrv_cmd.c
@@ -25,6 +25,7 @@
 #include "util/util.h"
 #include "responder/common/responder.h"
 #include "responder/common/responder_packet.h"
+#include "responder/common/responder_cache_req.h"
 #include "responder/sudo/sudosrv_private.h"
 #include "db/sysdb_sudo.h"
 #include "sss_client/sss_cli.h"
@@ -164,7 +165,7 @@ errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret)
     return EOK;
 }
 
-static void sudosrv_cmd_parse_query_done(struct tevent_req *req);
+static void sudosrv_cmd_initgr_done(struct tevent_req *req);
 
 static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
 {
@@ -213,7 +214,6 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
     }
 
     /* parse 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");
@@ -221,14 +221,24 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
         goto done;
     }
 
-    req = sudosrv_parse_query_send(cmd_ctx, cmd_ctx->sudo_ctx,
-                                   query_body, query_len);
+    ret = sudosrv_parse_query(cmd_ctx, query_body, query_len,
+                              &cmd_ctx->rawname, &cmd_ctx->uid);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse sudo query [%d]: %s\n",
+              ret, sss_strerror(ret));
+        goto done;
+    }
+
+    req = cache_req_initgr_by_name_send(cmd_ctx, cli_ctx->ev, cli_ctx->rctx,
+                                        cmd_ctx->sudo_ctx->ncache,
+                                        cmd_ctx->sudo_ctx->neg_timeout,
+                                        0, NULL, cmd_ctx->rawname);
     if (req == NULL) {
         ret = ENOMEM;
         goto done;
     }
 
-    tevent_req_set_callback(req, sudosrv_cmd_parse_query_done, cmd_ctx);
+    tevent_req_set_callback(req, sudosrv_cmd_initgr_done, cmd_ctx);
 
     ret = EAGAIN;
 
@@ -236,19 +246,19 @@ done:
     return sudosrv_cmd_done(cmd_ctx, ret);
 }
 
-static void sudosrv_cmd_parse_query_done(struct tevent_req *req)
+static void sudosrv_cmd_initgr_done(struct tevent_req *req)
 {
     struct sudo_cmd_ctx *cmd_ctx = NULL;
     errno_t ret;
 
     cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx);
 
-    ret = sudosrv_parse_query_recv(cmd_ctx, req, &cmd_ctx->uid,
-                                   &cmd_ctx->username, &cmd_ctx->domain);
+    ret = cache_req_initgr_by_name_recv(cmd_ctx, req, NULL, &cmd_ctx->domain,
+                                        &cmd_ctx->username);
     talloc_zfree(req);
     if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Invalid query [%d]: %s\n",
-                                    ret, strerror(ret));
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform initgroups [%d]: %s\n",
+              ret, strerror(ret));
         goto done;
     }
 
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 13015072e6daf1455b0b8e66a225f84c94280958..c81c990ac07d949ade47bbaf5b26f56117b5bfe7 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <talloc.h>
+#include <tevent.h>
 
 #include "util/util.h"
 #include "db/sysdb_sudo.h"
@@ -34,7 +35,6 @@ errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx)
 {
     errno_t ret;
 
-    /* OK, got the user from cache. Try to get the rules. */
     ret = sudosrv_get_rules(cmd_ctx);
     if (ret == EAGAIN) {
         DEBUG(SSSDBG_TRACE_INTERNAL,
diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h
index dceb113b530c8adfdb361cafff95b49d7dc323b5..38de16960d9eaff38b92cddb859fcb8ef2c90c5d 100644
--- a/src/responder/sudo/sudosrv_private.h
+++ b/src/responder/sudo/sudosrv_private.h
@@ -60,6 +60,7 @@ struct sudo_cmd_ctx {
 
     /* input data */
     uid_t uid;
+    char *rawname;
     char *username;
     struct sss_domain_info *domain;
 
@@ -78,16 +79,11 @@ errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx);
 
 errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx);
 
-struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx,
-                                            struct sudo_ctx *sudo_ctx,
-                                            uint8_t *query_body,
-                                            size_t query_len);
-
-errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx,
-                                 struct tevent_req *req,
-                                 uid_t *_uid,
-                                 char **_username,
-                                 struct sss_domain_info **_domain);
+errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
+                            uint8_t *query_body,
+                            size_t query_len,
+                            char **_rawname,
+                            uid_t *_uid);
 
 errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
                                uint32_t error,
diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c
index 08b359c0464f1cc00866e46634e571562910018d..36d777eb52e8fa7f1d366433b56d37431bf0bb7c 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -25,7 +25,6 @@
 #include <tevent.h>
 
 #include "util/util.h"
-#include "responder/common/responder_cache_req.h"
 #include "responder/sudo/sudosrv_private.h"
 
 static int sudosrv_response_append_string(TALLOC_CTX *mem_ctx,
@@ -252,128 +251,50 @@ fail:
     return ret;
 }
 
-struct sudosrv_parse_query_state {
-    uid_t uid;
-    char *username;
-    struct sss_domain_info *domain;
-};
-
-static void sudosrv_parse_query_done(struct tevent_req *subreq);
-
-struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx,
-                                            struct sudo_ctx *sudo_ctx,
-                                            uint8_t *query_body,
-                                            size_t query_len)
+errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
+                            uint8_t *query_body,
+                            size_t query_len,
+                            char **_rawname,
+                            uid_t *_uid)
 {
-    struct tevent_req *req = NULL;
-    struct tevent_req *subreq = NULL;
-    struct sudosrv_parse_query_state *state = NULL;
     size_t offset = 0;
-    size_t rawname_len = 0;
-    char *rawname = NULL;
-    errno_t ret;
-
-    /* create request */
-    req = tevent_req_create(mem_ctx, &state,
-                            struct sudosrv_parse_query_state);
-    if (req == NULL) {
-        DEBUG(SSSDBG_FATAL_FAILURE, "tevent_req_create() failed\n");
-        return NULL;
-    }
+    size_t rawname_len;
+    char *rawname;
+    uid_t uid;
 
     /* uid */
-
     if (query_len < sizeof(uid_t)) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Query is too small\n");
-        ret = EINVAL;
-        goto immediately;
+        return EINVAL;
     }
-    safealign_memcpy(&state->uid, query_body, sizeof(uid_t), &offset);
+    safealign_memcpy(&uid, query_body, sizeof(uid_t), &offset);
 
     /* 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 immediately;
+        return EINVAL;
     }
 
     if (rawname_len < 2) { /* at least one character and zero */
         DEBUG(SSSDBG_CRIT_FAILURE, "Query does not contain username\n");
-        ret = EINVAL;
-        goto immediately;
+        return EINVAL;
     }
 
     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 immediately;
+        return EINVAL;
     }
 
-    /* parse username */
-
-    subreq = cache_req_initgr_by_name_send(state, sudo_ctx->rctx->ev,
-                                           sudo_ctx->rctx, sudo_ctx->ncache,
-                                           sudo_ctx->neg_timeout, 0,
-                                           NULL, rawname);
-    if (subreq == NULL) {
-        ret = ENOMEM;
-        goto immediately;
-    }
-
-    tevent_req_set_callback(subreq, sudosrv_parse_query_done, req);
-
-    return req;
-
-immediately:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-    tevent_req_post(req, sudo_ctx->rctx->ev);
-
-    return req;
-}
-
-static void sudosrv_parse_query_done(struct tevent_req *subreq)
-{
-    struct sudosrv_parse_query_state *state;
-    struct tevent_req *req;
-    errno_t ret;
-
-    req = tevent_req_callback_data(subreq, struct tevent_req);
-    state = tevent_req_data(req, struct sudosrv_parse_query_state);
-
-    ret = cache_req_initgr_by_name_recv(state, subreq, NULL,
-                                        &state->domain, &state->username);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        tevent_req_error(req, ret);
-        return;
+    rawname = talloc_strdup(mem_ctx, rawname);
+    if (rawname == NULL) {
+        return ENOMEM;
     }
 
-    tevent_req_done(req);
-}
-
-errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx,
-                                 struct tevent_req *req,
-                                 uid_t *_uid,
-                                 char **_username,
-                                 struct sss_domain_info **_domain)
-{
-    struct sudosrv_parse_query_state *state = NULL;
-
-    state = tevent_req_data(req, struct sudosrv_parse_query_state);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *_uid = state->uid;
-    *_username = talloc_steal(mem_ctx, state->username);
-    *_domain = state->domain; /* do not steal on mem_ctx */
+    *_uid = uid;
+    *_rawname = rawname;
 
     return EOK;
 }
-- 
2.1.0

