On 11/12/2012 02:33 PM, Pavel Březina wrote:
On 11/09/2012 03:18 PM, Simo Sorce wrote:
On Fri, 2012-11-09 at 14:28 +0100, Pavel Březina wrote:
 From 724ebcafa2d4e54df048ca2a578b03281fb7fe6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 9 Nov 2012 13:31:52 +0100
Subject: [PATCH 1/6] sudo: fix missing parameter in two debug messages

---
  src/responder/sudo/sudosrv_get_sudorules.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/responder/sudo/sudosrv_get_sudorules.c
b/src/responder/sudo/sudosrv_get_sudorules.c
index
b6e016c73cba6c86b9f20af63357c6fcc2b5508b..0e0437622e94a234b1597bcd272633f6944d4762
100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -369,7 +369,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx
*cmd_ctx)
                                     NULL, &groupnames);
      if (ret != EOK) {
          DEBUG(SSSDBG_CRIT_FAILURE,
-             ("Unable to retrieve user info [%d]: %s\n",
strerror(ret)));
+             ("Unable to retrieve user info [%d]: %s\n", ret,
strerror(ret)));
          goto done;
      }

The comment says 2 debug messages, but the patch only has one, which is
wrong ?

Simo.


Hi,
thank you. Looks like I forgot to modify the second message. New patches
are attached.

I'm attaching a new set of patches base on IRC discussion with Simo
and Jakub.

Domain name is no longer sent to sudo. This was done without changing the protocol.

From 0046cce0cf0cc7ebedeb365e5f920f6c4beb4fb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 9 Nov 2012 13:31:52 +0100
Subject: [PATCH 1/7] sudo: fix missing parameter in two debug messages

---
 src/responder/sudo/sudosrv_get_sudorules.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index b6e016c73cba6c86b9f20af63357c6fcc2b5508b..e7b9ca8c52baecb518b5dbdf41437d900034f61b 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -369,7 +369,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
                                    NULL, &groupnames);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
-             ("Unable to retrieve user info [%d]: %s\n", strerror(ret)));
+             ("Unable to retrieve user info [%d]: %s\n", ret, strerror(ret)));
         goto done;
     }
 
@@ -382,8 +382,8 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
                                             cmd_ctx->uid, groupnames,
                                             &expired_rules, &expired_rules_num);
     if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-             ("Unable to retrieve expired sudo rules [%d]: %s\n", strerror(ret)));
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve expired sudo rules "
+                                    "[%d]: %s\n", ret, strerror(ret)));
         goto done;
     }
 
-- 
1.7.11.7

From dff6c42ce72a2de0003d0bbd14a6904100620043 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Wed, 7 Nov 2012 18:24:46 +0100
Subject: [PATCH 2/7] use tmp_ctx in sudosrv_get_sudorules_from_cache()

---
 src/responder/sudo/sudosrv_get_sudorules.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index e7b9ca8c52baecb518b5dbdf41437d900034f61b..9081cbd7075fd305becd8b36b5c7e077607d0952 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -301,7 +301,9 @@ done:
     sudosrv_cmd_done(dctx->cmd_ctx, ret);
 }
 
-static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx,
+static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
+                                                struct sudo_cmd_ctx *cmd_ctx,
+                                                struct sysdb_attrs ***_rules,
                                                 size_t *_num_rules);
 static void
 sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
@@ -421,7 +423,9 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
     } else {
         /* nothing is expired return what we have in the cache */
         DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n"));
-        ret = sudosrv_get_sudorules_from_cache(cmd_ctx, NULL);
+        ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx,
+                                               &cmd_ctx->rules,
+                                               &cmd_ctx->num_rules);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE,
                   ("Failed to make a request to our cache [%d]: %s\n",
@@ -482,7 +486,6 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
     struct sudo_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct sudo_cmd_ctx);
     struct tevent_req *dpreq = NULL;
     errno_t ret;
-    size_t num_rules;
 
     if (err_maj) {
         DEBUG(SSSDBG_CRIT_FAILURE,
@@ -493,7 +496,8 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
     }
 
     DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n"));
-    ret = sudosrv_get_sudorules_from_cache(cmd_ctx, &num_rules);
+    ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx, &cmd_ctx->rules,
+                                           &cmd_ctx->num_rules);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               ("Failed to make a request to our cache [%d]: %s\n",
@@ -524,7 +528,9 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
     sudosrv_cmd_done(cmd_ctx, ret);
 }
 
-static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx,
+static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
+                                                struct sudo_cmd_ctx *cmd_ctx,
+                                                struct sysdb_attrs ***_rules,
                                                 size_t *_num_rules)
 {
     TALLOC_CTX *tmp_ctx;
@@ -533,6 +539,8 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx,
     char **groupnames = NULL;
     const char *debug_name = NULL;
     unsigned int flags = SYSDB_SUDO_FILTER_NONE;
+    struct sysdb_attrs **rules = NULL;
+    size_t num_rules = 0;
     const char *attrs[] = { SYSDB_OBJECTCLASS
                             SYSDB_SUDO_CACHE_AT_CN,
                             SYSDB_SUDO_CACHE_AT_USER,
@@ -583,10 +591,10 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx,
         break;
     }
 
-    ret = sudosrv_get_sudorules_query_cache(cmd_ctx, sysdb, cmd_ctx->type,
+    ret = sudosrv_get_sudorules_query_cache(tmp_ctx, sysdb, cmd_ctx->type,
                                             attrs, flags, cmd_ctx->orig_username,
                                             cmd_ctx->uid, groupnames,
-                                            &cmd_ctx->rules, &cmd_ctx->num_rules);
+                                            &rules, &num_rules);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
              ("Unable to retrieve sudo rules [%d]: %s\n", strerror(ret)));
@@ -596,8 +604,12 @@ static errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx,
     DEBUG(SSSDBG_TRACE_FUNC, ("Returning rules for [%s@%s]\n",
           debug_name, cmd_ctx->domain->name));
 
+    if (_rules != NULL) {
+        *_rules = talloc_steal(mem_ctx, rules);
+    }
+
     if (_num_rules != NULL) {
-        *_num_rules = cmd_ctx->num_rules;
+        *_num_rules = num_rules;
     }
 
     ret = EOK;
-- 
1.7.11.7

From b5cd6dc4f16647a6e6d755c07315d3b41a447221 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 30 Oct 2012 12:01:51 +0100
Subject: [PATCH 3/7] sudo: support users from subdomains

https://fedorahosted.org/sssd/ticket/1616
---
 src/responder/sudo/sudosrv_cmd.c           |  41 ++++++--
 src/responder/sudo/sudosrv_get_sudorules.c |  64 +++++++++---
 src/responder/sudo/sudosrv_private.h       |  17 ++--
 src/responder/sudo/sudosrv_query.c         | 152 ++++++++++++++++++++++-------
 4 files changed, 214 insertions(+), 60 deletions(-)

diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c
index 9a87ed7d768b0bf35b1d1980895d08e4cf08d5f7..440c8c5da4a56105c1cb83fb6a7e8a79dd0c9289 100644
--- a/src/responder/sudo/sudosrv_cmd.c
+++ b/src/responder/sudo/sudosrv_cmd.c
@@ -156,10 +156,12 @@ 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 int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
 {
+    struct tevent_req *req = NULL;
     struct sudo_cmd_ctx *cmd_ctx = NULL;
-    struct sudo_dom_ctx *dom_ctx = NULL;
     uint8_t *query_body = NULL;
     size_t query_len = 0;
     errno_t ret;
@@ -199,11 +201,35 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
         goto done;
     }
 
-    ret = sudosrv_parse_query(cmd_ctx, cli_ctx->rctx,
-                              query_body, query_len,
-                              &cmd_ctx->uid, &cmd_ctx->username, &cmd_ctx->domain);
+    req = sudosrv_parse_query_send(cmd_ctx, cli_ctx->rctx,
+                                   query_body, query_len);
+    if (req == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    tevent_req_set_callback(req, sudosrv_cmd_parse_query_done, cmd_ctx);
+
+    ret = EAGAIN;
+
+done:
+    return sudosrv_cmd_done(cmd_ctx, ret);
+}
+
+static void sudosrv_cmd_parse_query_done(struct tevent_req *req)
+{
+    struct sudo_cmd_ctx *cmd_ctx = NULL;
+    struct sudo_dom_ctx *dom_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);
+    talloc_zfree(req);
     if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query: %s\n", strerror(ret)));
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query [%d]: %s\n",
+                                    ret, strerror(ret)));
         goto done;
     }
 
@@ -231,15 +257,14 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
     }
     dom_ctx->cmd_ctx = cmd_ctx;
     dom_ctx->domain = cmd_ctx->domain != NULL ? cmd_ctx->domain
-                                              : cli_ctx->rctx->domains;
+                                              : cmd_ctx->cli_ctx->rctx->domains;
 
     ret = sudosrv_get_sudorules(dom_ctx);
 
 done:
-    return sudosrv_cmd_done(cmd_ctx, ret);
+    sudosrv_cmd_done(cmd_ctx, ret);
 }
 
-
 static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx)
 {
     return sudosrv_cmd(SSS_SUDO_USER, cli_ctx);
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 9081cbd7075fd305becd8b36b5c7e077607d0952..6d6b95d3fd04a20dceb16becc571403b85885d0e 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -29,6 +29,22 @@
 #include "db/sysdb_sudo.h"
 #include "responder/sudo/sudosrv_private.h"
 
+static struct sysdb_ctx* sudosrv_get_user_sysdb(struct sss_domain_info *domain)
+{
+    return domain->sysdb;
+}
+
+static struct sysdb_ctx* sudosrv_get_rules_sysdb(struct sss_domain_info *domain)
+{
+    if (domain->parent == NULL) {
+        return domain->sysdb;
+    } else {
+        /* sudo rules are stored under parent domain basedn, so we will return
+         * parent's sysdb context */
+        return domain->parent->sysdb;
+    }
+}
+
 static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx);
 
 errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx)
@@ -112,7 +128,7 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
         DEBUG(SSSDBG_FUNC_DATA, ("Requesting info about [%s@%s]\n",
               name, dom->name));
 
-        sysdb = dctx->domain->sysdb;
+        sysdb = sudosrv_get_user_sysdb(dctx->domain);
         if (sysdb == NULL) {
              DEBUG(SSSDBG_CRIT_FAILURE,
                    ("sysdb context not found for this domain!\n"));
@@ -327,7 +343,8 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
     TALLOC_CTX *tmp_ctx = NULL;
     struct tevent_req *dpreq = NULL;
     struct dp_callback_ctx *cb_ctx = NULL;
-    struct sysdb_ctx *sysdb;
+    struct sysdb_ctx *user_sysdb = NULL;
+    struct sysdb_ctx *rules_sysdb = NULL;
     char **groupnames = NULL;
     size_t expired_rules_num = 0;
     struct sysdb_attrs **expired_rules = NULL;
@@ -341,7 +358,21 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
         return EFAULT;
     }
 
-    sysdb = cmd_ctx->domain->sysdb;
+    user_sysdb = sudosrv_get_user_sysdb(cmd_ctx->domain);
+    if (user_sysdb == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("user sysdb context not found for this domain!\n"));
+        ret = EIO;
+        goto done;
+    }
+
+    rules_sysdb = sudosrv_get_rules_sysdb(cmd_ctx->domain);
+    if (rules_sysdb == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("rules sysdb context not found for this domain!\n"));
+        ret = EIO;
+        goto done;
+    }
 
     tmp_ctx = talloc_new(NULL);
     if (tmp_ctx == NULL) {
@@ -367,7 +398,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
      * expired rules for this user and defaults at once we will save one
      * provider call
      */
-    ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, sysdb,
+    ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, user_sysdb,
                                    NULL, &groupnames);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
@@ -379,7 +410,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
             | SYSDB_SUDO_FILTER_INCLUDE_DFL
             | SYSDB_SUDO_FILTER_ONLY_EXPIRED
             | SYSDB_SUDO_FILTER_USERINFO;
-    ret = sudosrv_get_sudorules_query_cache(tmp_ctx, sysdb, cmd_ctx->type,
+    ret = sudosrv_get_sudorules_query_cache(tmp_ctx, rules_sysdb, cmd_ctx->type,
                                             attrs, flags, cmd_ctx->orig_username,
                                             cmd_ctx->uid, groupnames,
                                             &expired_rules, &expired_rules_num);
@@ -535,7 +566,8 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
 {
     TALLOC_CTX *tmp_ctx;
     errno_t ret;
-    struct sysdb_ctx *sysdb;
+    struct sysdb_ctx *user_sysdb = NULL;
+    struct sysdb_ctx *rules_sysdb = NULL;
     char **groupnames = NULL;
     const char *debug_name = NULL;
     unsigned int flags = SYSDB_SUDO_FILTER_NONE;
@@ -565,10 +597,18 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    sysdb = cmd_ctx->domain->sysdb;
-    if (sysdb == NULL) {
+    user_sysdb = sudosrv_get_user_sysdb(cmd_ctx->domain);
+    if (user_sysdb == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE,
-              ("sysdb context not found for this domain!\n"));
+              ("user sysdb context not found for this domain!\n"));
+        ret = EIO;
+        goto done;
+    }
+
+    rules_sysdb = sudosrv_get_rules_sysdb(cmd_ctx->domain);
+    if (rules_sysdb == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("rules sysdb context not found for this domain!\n"));
         ret = EIO;
         goto done;
     }
@@ -576,8 +616,8 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
     switch (cmd_ctx->type) {
     case SSS_SUDO_USER:
         debug_name = cmd_ctx->cased_username;
-        ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, sysdb,
-                                       NULL, &groupnames);
+        ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username,
+                                       user_sysdb, NULL, &groupnames);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE,
                  ("Unable to retrieve user info [%d]: %s\n", strerror(ret)));
@@ -591,7 +631,7 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
         break;
     }
 
-    ret = sudosrv_get_sudorules_query_cache(tmp_ctx, sysdb, cmd_ctx->type,
+    ret = sudosrv_get_sudorules_query_cache(tmp_ctx, rules_sysdb, cmd_ctx->type,
                                             attrs, flags, cmd_ctx->orig_username,
                                             cmd_ctx->uid, groupnames,
                                             &rules, &num_rules);
diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h
index 55ea1383533188eaf8f3f731b24fe0cce3eb197d..b805940759f409ebd532707faf93d09dc3e51e04 100644
--- a/src/responder/sudo/sudosrv_private.h
+++ b/src/responder/sudo/sudosrv_private.h
@@ -90,13 +90,16 @@ errno_t sudosrv_get_sudorules(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,
-                            uint8_t *query_body,
-                            size_t query_len,
-                            uid_t *_uid,
-                            char **_username,
-                            struct sss_domain_info **_domain);
+struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx,
+                                            struct resp_ctx *rctx,
+                                            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_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 824f682c6c753bc47f303af09f03363ad79af987..d76ecbb9deb7a59adaa319fc7ef4ddb5e3071f4c 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include <errno.h>
 #include <talloc.h>
+#include <tevent.h>
 
 #include "util/util.h"
 #include "responder/sudo/sudosrv_private.h"
@@ -250,34 +251,38 @@ fail:
     return ret;
 }
 
-/*
- * Query format:
- * <uid><username[@domain]>
- */
-errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
-                            struct resp_ctx *rctx,
-                            uint8_t *query_body,
-                            size_t query_len,
-                            uid_t *_uid,
-                            char **_username,
-                            struct sss_domain_info **_domain)
+struct sudosrv_parse_query_state {
+    struct resp_ctx *rctx;
+    uid_t uid;
+    char *rawname;
+};
+
+static void sudosrv_parse_query_done(struct tevent_req *subreq);
+
+struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx,
+                                            struct resp_ctx *rctx,
+                                            uint8_t *query_body,
+                                            size_t query_len)
 {
-    TALLOC_CTX *tmp_ctx = NULL;
-    struct sss_domain_info *domain = NULL;
+    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;
     char *domainname = NULL;
-    char *username = NULL;
-    uid_t uid;
     errno_t ret;
 
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
-        return ENOMEM;
+    /* 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;
     }
 
+    state->rctx = rctx;
+
     /* uid */
 
     if (query_len < sizeof(uid_t)) {
@@ -285,7 +290,7 @@ errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
         ret = EINVAL;
         goto done;
     }
-    safealign_memcpy(&uid, query_body, sizeof(uid_t), &offset);
+    safealign_memcpy(&state->uid, query_body, sizeof(uid_t), &offset);
 
     /* username[@domain] */
 
@@ -312,31 +317,112 @@ errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
 
     /* parse username */
 
-    ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains,
-                                     rctx->default_domain, rawname,
-                                     &domainname, &username);
-    if (ret != EOK) {
+    state->rawname = rawname;
+    ret = sss_parse_name_for_domains(state, rctx->domains,
+                                     rctx->default_domain, state->rawname,
+                                     &domainname, NULL);
+    if (ret == EAGAIN) {
+        DEBUG(SSSDBG_TRACE_FUNC, ("Domain [%s] not found, "
+              "sending subdomain request\n", domainname));
+
+        subreq = sss_dp_get_domains_send(state, rctx, true, domainname);
+        if (req == NULL) {
+            ret = ENOMEM;
+        } else {
+            tevent_req_set_callback(subreq, sudosrv_parse_query_done, req);
+            ret = EAGAIN;
+        }
+        goto done;
+    } else if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid name received [%s]\n", rawname));
         goto done;
     }
 
+    ret = EOK;
+
+done:
+    if (ret != EAGAIN) {
+        if (ret == EOK) {
+            tevent_req_done(req);
+        } else {
+            tevent_req_error(req, ret);
+        }
+        tevent_req_post(req, rctx->ev);
+    }
+
+    return req;
+}
+
+static void sudosrv_parse_query_done(struct tevent_req *subreq)
+{
+    struct tevent_req *req = NULL;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+
+    ret = sss_dp_get_domains_recv(subreq);
+    talloc_free(subreq);
+    if (ret != EOK) {
+        tevent_req_error(req, ret);
+    }
+
+    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;
+    struct sss_domain_info *domain = NULL;
+    char *username = NULL;
+    char *domainname = NULL;
+    errno_t ret;
+
+    state = tevent_req_data(req, struct sudosrv_parse_query_state);
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    if (state->rawname == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("No query specified?!\n"));
+        return EINVAL;
+    }
+
+    /* Try to parse username@domain again because if the first call
+     * returned EAGAIN, then username is unset. If we get EAGAIN again,
+     * we will not search for it again.
+     */
+    ret = sss_parse_name_for_domains(state, state->rctx->domains,
+                                     state->rctx->default_domain,
+                                     state->rawname,
+                                     &domainname, &username);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_TRACE_FUNC, ("Unable to parse domain [%d]: %s\n",
+                                  ret, strerror(ret)));
+        return ret;
+    }
+
+    if (username == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("No username specified!\n"));
+        return EINVAL;
+    }
+
     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);
+        domain = responder_get_domain(mem_ctx, state->rctx, domainname);
         if (domain == NULL) {
-            ret = ENOENT;
-            goto done;
+            DEBUG(SSSDBG_OP_FAILURE, ("Corresponding domain [%s] has not been "
+                                      "found\n", domainname));
+            return ENOENT;
         }
     }
 
-    *_uid = uid;
+    *_uid = state->uid;
     *_username = talloc_steal(mem_ctx, username);
     *_domain = domain; /* do not steal on mem_ctx */
 
-    ret = EOK;
-
-done:
-    talloc_free(tmp_ctx);
-    return ret;
+    return EOK;
 }
-- 
1.7.11.7

From 12ea1c40b89b8c42ba46e57003abb14029231904 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 13 Nov 2012 15:42:48 +0100
Subject: [PATCH 4/7] sudo: do not send domain name with username

This caused troubles with subdomain users and it is not really
necessary. This patch does not change the protocol itself, that
should be done on the earliest possible occasion.

Part of https://fedorahosted.org/sssd/ticket/1616
---
 src/responder/sudo/sudosrv_cmd.c        |  4 ++--
 src/responder/sudo/sudosrv_private.h    |  1 -
 src/responder/sudo/sudosrv_query.c      |  6 +++---
 src/sss_client/sudo/sss_sudo.c          | 15 +--------------
 src/sss_client/sudo/sss_sudo_response.c |  7 +++++--
 5 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c
index 440c8c5da4a56105c1cb83fb6a7e8a79dd0c9289..eb421373f394e59db7db615da17ef7370c375746 100644
--- a/src/responder/sudo/sudosrv_cmd.c
+++ b/src/responder/sudo/sudosrv_cmd.c
@@ -85,7 +85,7 @@ static errno_t sudosrv_cmd_send_error(TALLOC_CTX *mem_ctx,
         return EFAULT;
     }
 
-    ret = sudosrv_build_response(mem_ctx, error, NULL, 0, NULL,
+    ret = sudosrv_build_response(mem_ctx, error, 0, NULL,
                                  &response_body, &response_len);
     if (ret != EOK) {
         return ret;
@@ -118,7 +118,7 @@ errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret)
 
         /* send result */
         ret = sudosrv_build_response(cmd_ctx, SSS_SUDO_ERROR_OK,
-                                     cmd_ctx->domain->name, num_rules, rules,
+                                     num_rules, rules,
                                      &response_body, &response_len);
         if (ret != EOK) {
             return EFAULT;
diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h
index b805940759f409ebd532707faf93d09dc3e51e04..c9eae57b8f2d03852dfed7689e9ca18d0b4afe6d 100644
--- a/src/responder/sudo/sudosrv_private.h
+++ b/src/responder/sudo/sudosrv_private.h
@@ -103,7 +103,6 @@ errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx,
 
 errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
                                uint32_t error,
-                               const char *domain,
                                int rules_num,
                                struct sysdb_attrs **rules,
                                uint8_t **_response_body,
diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c
index d76ecbb9deb7a59adaa319fc7ef4ddb5e3071f4c..998b60235db0c28a1a5c4d964264b1e0bacc0aa1 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -188,7 +188,6 @@ done:
  */
 errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
                                uint32_t error,
-                               const char *domain,
                                int rules_num,
                                struct sysdb_attrs **rules,
                                uint8_t **_response_body,
@@ -217,8 +216,9 @@ errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    /* domain name */
-    ret = sudosrv_response_append_string(tmp_ctx, domain, strlen(domain) + 1,
+    /* domain name - deprecated
+     * TODO: when possible change the protocol */
+    ret = sudosrv_response_append_string(tmp_ctx, "\0", 1,
                                          &response_body, &response_len);
     if (ret != EOK) {
         goto fail;
diff --git a/src/sss_client/sudo/sss_sudo.c b/src/sss_client/sudo/sss_sudo.c
index e2bb3e00d123bfbfecef91ce2d01edaf7b7d1a76..92f575411421b5aba999f0c0ab60d9ff8ed57656 100644
--- a/src/sss_client/sudo/sss_sudo.c
+++ b/src/sss_client/sudo/sss_sudo.c
@@ -100,23 +100,10 @@ int sss_sudo_send_recv(uid_t uid,
         return EINVAL;
     }
 
-    if (domainname != NULL) {
-        ret = asprintf(&fullname, "%s@%s", username, domainname);
-        if (ret == -1) {
-            return ENOMEM;
-        }
-    } else {
-        fullname = strdup(username);
-        if (fullname == NULL) {
-            return ENOMEM;
-        }
-    }
-
     /* send query and receive response */
 
-    ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, fullname,
+    ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, username,
                                      _error, NULL, _result);
-    free(fullname);
     return ret;
 }
 
diff --git a/src/sss_client/sudo/sss_sudo_response.c b/src/sss_client/sudo/sss_sudo_response.c
index 471d42ed4d6f92a6df462b8ccb32f865e25e76b8..7d4bcc5d24e028f5b7bfba56214df28cd1a2a7ee 100644
--- a/src/sss_client/sudo/sss_sudo_response.c
+++ b/src/sss_client/sudo/sss_sudo_response.c
@@ -67,14 +67,17 @@ int sss_sudo_parse_response(const char *message,
         return ret;
     }
 
-    /* domain name */
+    /* domain name - deprecated
+     * it won't be used, but we will read it anyway to ease parsing
+     * TODO: when possible change the protocol */
     ret = sss_sudo_parse_string(message, message_len, &cursor, &domainname);
     if (ret != EOK) {
         return ret;
     }
 
+    free(domainname);
     if (_domainname != NULL) {
-        *_domainname = domainname;
+        *_domainname = NULL;
     }
 
     /* result */
-- 
1.7.11.7

From cf5c642d3cbae6780983cba44bb10170abc7d842 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 9 Nov 2012 14:16:38 +0100
Subject: [PATCH 5/7] libsss_sudo: bump version to 2:1:1 (revision)

We changed source code of libsss_sudo. The interface remains
intact so it will not break current users.

The version string is changed according to following rules:
http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index ce3f94f635f918438bf856c523e47c0f09fc328a..ea868c52a8a2440e3b073e76be00835d16414dfd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1186,7 +1186,7 @@ libsss_sudo_la_SOURCES = \
 libsss_sudo_la_LDFLAGS = \
     $(CLIENT_LIBS) \
     -Wl,--version-script,$(srcdir)/src/sss_client/sss_sudo.exports \
-    -version-info 2:0:1
+    -version-info 2:1:1
 
 sudolib_LTLIBRARIES = libsss_sudo.la
 
-- 
1.7.11.7

From ff6db4e50fdc57209d302ad5226659fafa165678 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 13 Nov 2012 13:31:56 +0100
Subject: [PATCH 6/7] sudo: print message if old protocol is used

---
 src/responder/sudo/sudosrv_cmd.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c
index eb421373f394e59db7db615da17ef7370c375746..d5b73641760d9c574c79e11cb4992def60310679 100644
--- a/src/responder/sudo/sudosrv_cmd.c
+++ b/src/responder/sudo/sudosrv_cmd.c
@@ -164,6 +164,7 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
     struct sudo_cmd_ctx *cmd_ctx = NULL;
     uint8_t *query_body = NULL;
     size_t query_len = 0;
+    uint32_t protocol = cli_ctx->cli_protocol_version->version;
     errno_t ret;
 
     /* create cmd_ctx */
@@ -185,9 +186,9 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx)
     }
 
     /* if protocol is invalid return */
-    if (cli_ctx->cli_protocol_version->version != SSS_SUDO_PROTOCOL_VERSION) {
-        DEBUG(SSSDBG_FATAL_FAILURE, ("Invalid protocol! [%d]\n",
-              cli_ctx->cli_protocol_version->version));
+    if (protocol == 0) {
+        DEBUG(SSSDBG_FATAL_FAILURE, ("Protocol [%d] is not secure. "
+              "SSSD does not allow to use this protocol.\n", protocol));
         ret = EFAULT;
         goto done;
     }
-- 
1.7.11.7

From b731616f3344b6288ce8830acf0106033d5ede06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Wed, 7 Nov 2012 18:16:25 +0100
Subject: [PATCH 7/7] sudo: print how many rules we are refreshing or
 returning

---
 src/responder/sudo/sudosrv_get_sudorules.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 6d6b95d3fd04a20dceb16becc571403b85885d0e..f79d47dcb70b56c49154756e214d1d98a1bf3b27 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -423,7 +423,8 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
     cmd_ctx->expired_rules_num = expired_rules_num;
     if (expired_rules_num > 0) {
         /* refresh expired rules then continue */
-        DEBUG(SSSDBG_TRACE_INTERNAL, ("Refreshing expired rules\n"));
+        DEBUG(SSSDBG_TRACE_INTERNAL, ("Refreshing %d expired rules\n",
+                                      expired_rules_num));
         dpreq = sss_dp_get_sudoers_send(tmp_ctx, cmd_ctx->cli_ctx->rctx,
                                         cmd_ctx->domain, false,
                                         SSS_DP_SUDO_REFRESH_RULES,
@@ -641,8 +642,8 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    DEBUG(SSSDBG_TRACE_FUNC, ("Returning rules for [%s@%s]\n",
-          debug_name, cmd_ctx->domain->name));
+    DEBUG(SSSDBG_TRACE_FUNC, ("Returning %d rules for [%s@%s]\n",
+                              num_rules, debug_name, cmd_ctx->domain->name));
 
     if (_rules != NULL) {
         *_rules = talloc_steal(mem_ctx, rules);
-- 
1.7.11.7

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to