From 6d361fab09fea7945621afe43f70aa18f32937e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 23 Jul 2014 14:21:34 +0200
Subject: [PATCH] sudo: use dbus array for rules refresh

D-Bus only supports 255 signatures which caused a segmentation fault
when sudo responder tried to refresh more rules at once.

Resolves:
https://fedorahosted.org/sssd/ticket/2387
---
 src/providers/data_provider_be.c | 22 ++++++++++++++--------
 src/responder/sudo/sudosrv_dp.c  | 16 +++++++++++++++-
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index f3432492df4150b283dbaa16ec2abfc944a32d0e..faa9f7ae9700e550c5710bd7791bea329931831d 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1442,7 +1442,7 @@ static int be_sudo_handler(struct sbus_request *dbus_req, void *user_data)
 {
     DBusError dbus_error;
     DBusMessageIter iter;
-    dbus_bool_t iter_next = FALSE;
+    DBusMessageIter array_iter;
     struct be_client *be_cli = NULL;
     struct be_req *be_req = NULL;
     struct be_sudo_req *sudo_req = NULL;
@@ -1532,15 +1532,19 @@ static int be_sudo_handler(struct sbus_request *dbus_req, void *user_data)
             goto fail;
         }
 
+        dbus_message_iter_next(&iter);
+
+        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
+            ret = EIO;
+            err_msg = "Invalid D-Bus message format";
+            goto fail;
+        }
+
+        dbus_message_iter_recurse(&iter, &array_iter);
+
         /* read the rules */
         for (i = 0; i < rules_num; i++) {
-            iter_next = dbus_message_iter_next(&iter);
-            if (iter_next == FALSE) {
-                DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
-                ret = EIO;
-                err_msg = "Invalid D-Bus message format";
-                goto fail;
-            }
             if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
                 DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
                 ret = EIO;
@@ -1555,6 +1559,8 @@ static int be_sudo_handler(struct sbus_request *dbus_req, void *user_data)
                 ret = ENOMEM;
                 goto fail;
             }
+
+            dbus_message_iter_next(&iter);
         }
 
         sudo_req->rules[rules_num] = NULL;
diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c
index 18e51a92728df38af7ce960f5ef545647840cb25..95595fba2ad81e837de7222ece626d331299848c 100644
--- a/src/responder/sudo/sudosrv_dp.c
+++ b/src/responder/sudo/sudosrv_dp.c
@@ -117,6 +117,7 @@ sss_dp_get_sudoers_msg(void *pvt)
 {
     DBusMessage *msg;
     DBusMessageIter iter;
+    DBusMessageIter array_iter;
     dbus_bool_t dbret;
     errno_t ret;
     struct sss_dp_get_sudoers_info *info;
@@ -169,6 +170,13 @@ sss_dp_get_sudoers_msg(void *pvt)
             goto fail;
         }
 
+        dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+                                                 DBUS_TYPE_STRING_AS_STRING,
+                                                 &array_iter);
+        if (dbret == FALSE) {
+            goto fail;
+        }
+
         for (i = 0; i < info->num_rules; i++) {
             ret = sysdb_attrs_get_string(info->rules[i], SYSDB_NAME, &rule_name);
             if (ret != EOK) {
@@ -177,12 +185,18 @@ sss_dp_get_sudoers_msg(void *pvt)
                 goto fail;
             }
 
-            dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
+            dbret = dbus_message_iter_append_basic(&array_iter,
+                                                   DBUS_TYPE_STRING,
                                                    &rule_name);
             if (dbret == FALSE) {
                 goto fail;
             }
         }
+
+        dbret = dbus_message_iter_close_container(&iter, &array_iter);
+        if (dbret == FALSE) {
+            goto fail;
+        }
     }
 
     return msg;
-- 
1.7.11.7

