[SSSD] [PATCH] Implement org.freedesktop.DBus.Properties.GetAll for primitive types

Jakub Hrozek jhrozek at redhat.com
Mon May 26 16:39:44 UTC 2014


On Mon, May 26, 2014 at 05:30:05PM +0200, Lukas Slebodnik wrote:
> >Thanks, I didn't see this earlier because I never used --recurse.
> >
> >I modified the codegen a bit so than an invoker is called even if there
> >are no properties. The invoker creates an empty array, adds nothing (the
> >property getters would be inserted here by codegen) and returns.
> >
> >The other way I was considering was checking for properties in the
> >getall_handler in sssd, but I prefer to let the generated code do as
> >much work as possible.
> 
> Crash is fixed.
> Static analysers did not found any issues.
> 
> There are few gcc warnings.

Ah, I haven't seen any with clang..

> 
>   CC       src/tests/sbus_tests-sbus_tests.o
> src/tests/sbus_tests.c:105:1: error: missing initializer for field ‘invoker_get_all’ of ‘const struct sbus_interface_meta’ [-Werror=missing-field-initializers]
>  };
>  ^
> In file included from ../sssd/src/tests/sbus_tests.c:34:0:
> src/sbus/sssd_dbus_meta.h:83:28: note: ‘invoker_get_all’ declared here
>      sbus_method_invoker_fn invoker_get_all;
>                             ^
> cc1: all warnings being treated as errors
> 
> Warning can be fixed with diff:
> diff --git a/src/tests/sbus_tests.c b/src/tests/sbus_tests.c
> index 31b91c4..fe6ee05 100644
> --- a/src/tests/sbus_tests.c
> +++ b/src/tests/sbus_tests.c
> @@ -102,6 +102,7 @@ const struct sbus_interface_meta pilot_meta = {
>      pilot_methods,
>      NULL, /* no signals */
>      NULL, /* no properties */
> +    NULL, /* invoker function */
>  };

Thank you, I merged the diff.

>  
>  static int blink_handler(struct sbus_request *req, void *data)
> 
> 
> And the second warning:
> src/tests/sbus_codegen_tests.c: In function ‘check_arr_prop’:
> src/tests/sbus_codegen_tests.c:1226:30: error: ‘strings’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
>              ck_assert_str_eq(strings[1], pilot_path_array[1]);
>                               ^
> cc1: all warnings being treated as errors
> 
> I am not sure about solution :-)

I think the warning was bogus. I simply initialized strings to NULL and
then added some asserts to make sure that strings can be dereferenced
when we get to the comparison. I hope this would also silence gcc, at
least I haven't seen any warning with my test setup.
-------------- next part --------------
>From e17bebb2d5c8763f083338ff9d7e037bd14aac13 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 21 May 2014 16:48:45 +0200
Subject: [PATCH 1/5] SBUS: Add utility function sbus_add_variant_to_dict

---
 src/sbus/sssd_dbus.h            |   5 ++
 src/sbus/sssd_dbus_meta.h       |   1 +
 src/sbus/sssd_dbus_properties.c | 116 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+)

diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index 7d36703606d9d7204d0a945ce3f7ff9471560012..b2b6dd4a3233771391ea6ddcec516cb5f4d4a532 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -273,6 +273,11 @@ int sbus_request_return_and_finish(struct sbus_request *dbus_req,
                                    int first_arg_type,
                                    ...);
 
+int sbus_add_variant_to_dict(DBusMessageIter *iter_dict,
+                             const char *key,
+                             int type,
+                             const void *value);
+
 int sbus_request_return_as_variant(struct sbus_request *dbus_req,
                                    int type,
                                    const void *value);
diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h
index 4e170b7d6ce5fb8f68109e496ab96cfdf889d864..89f11224b9e077e5e9b2ce6b34fc5f93702a2dd4 100644
--- a/src/sbus/sssd_dbus_meta.h
+++ b/src/sbus/sssd_dbus_meta.h
@@ -76,6 +76,7 @@ struct sbus_interface_meta {
     const struct sbus_method_meta *methods;
     const struct sbus_signal_meta *signals;
     const struct sbus_property_meta *properties;
+    sbus_method_invoker_fn invoker_get_all;
 };
 
 const struct sbus_method_meta *
diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c
index bdd5b432fe57ca66a4d06f98720578b3a175a65c..07b33297b13782354cbcf812f129443a14c5d319 100644
--- a/src/sbus/sssd_dbus_properties.c
+++ b/src/sbus/sssd_dbus_properties.c
@@ -23,6 +23,74 @@
 #include "sbus/sssd_dbus_meta.h"
 #include "sbus/sssd_dbus_private.h"
 
+static char *
+type_to_string(char type, char *str)
+{
+    int l;
+
+    l = snprintf(str, 2, "%c", type);
+    if (l != 1) {
+        return NULL;
+    }
+
+    return str;
+}
+
+int sbus_add_variant_to_dict(DBusMessageIter *iter_dict,
+                             const char *key,
+                             int type,
+                             const void *value)
+{
+    DBusMessageIter iter_dict_entry;
+    DBusMessageIter iter_dict_val;
+    dbus_bool_t dbret;
+    char strtype[2];
+
+    type_to_string(type, strtype);
+
+    dbret = dbus_message_iter_open_container(iter_dict,
+                                             DBUS_TYPE_DICT_ENTRY, NULL,
+                                             &iter_dict_entry);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    /* Start by appending the key */
+    dbret = dbus_message_iter_append_basic(&iter_dict_entry,
+                                           DBUS_TYPE_STRING, &key);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_open_container(&iter_dict_entry,
+                                             DBUS_TYPE_VARIANT,
+                                             strtype,
+                                             &iter_dict_val);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    /* Now add the value */
+    dbret = dbus_message_iter_append_basic(&iter_dict_val, type, value);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_close_container(&iter_dict_entry,
+                                              &iter_dict_val);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_close_container(iter_dict,
+                                              &iter_dict_entry);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    return EOK;
+}
+
 static int
 dispatch_properties_set(struct sbus_connection *conn,
                         struct sbus_interface *intf,
@@ -176,6 +244,50 @@ dispatch_properties_get(struct sbus_connection *conn,
     return EOK;
 }
 
+static int
+dispatch_properties_get_all(struct sbus_connection *conn,
+                            struct sbus_interface *intf,
+                            DBusMessage *message)
+{
+    struct sbus_request *req;
+    const char *signature;
+    const struct sbus_interface_meta *meta;
+    const char *interface_name;
+    DBusMessageIter iter;
+
+    req = sbus_new_request(conn, intf, message);
+    if (req == NULL) {
+        return ENOMEM;
+    }
+
+    meta = intf->vtable->meta;
+
+    signature = dbus_message_get_signature(message);
+    /* Interface name */
+    if (strcmp(signature, "s") != 0) {
+        return sbus_request_fail_and_finish(req,
+                    sbus_error_new(req,
+                                   DBUS_ERROR_INVALID_ARGS,
+                                   "Invalid argument types passed " \
+                                   "to Set method"));
+    }
+
+    dbus_message_iter_init(message, &iter);
+    dbus_message_iter_get_basic(&iter, &interface_name);
+
+    if (strcmp(interface_name, meta->name) != 0) {
+        return sbus_request_fail_and_finish(req,
+                    sbus_error_new(req,
+                                   DBUS_ERROR_UNKNOWN_INTERFACE,
+                                   "No such interface"));
+    }
+
+    sbus_request_invoke_or_finish(req, NULL,
+                                  intf->instance_data,
+                                  meta->invoker_get_all);
+    return EOK;
+}
+
 int sbus_properties_dispatch(struct sbus_request *dbus_req)
 {
     const char *member;
@@ -191,6 +303,10 @@ int sbus_properties_dispatch(struct sbus_request *dbus_req)
         return dispatch_properties_get(dbus_req->conn,
                                        dbus_req->intf,
                                        dbus_req->message);
+    } else if (strcmp (member, "GetAll") == 0) {
+        return dispatch_properties_get_all(dbus_req->conn,
+                                            dbus_req->intf,
+                                            dbus_req->message);
     }
 
     return ERR_SBUS_NOSUP;
-- 
1.9.0

-------------- next part --------------
>From 39a09ec906742b1e9a700a29d662b6612bca9f0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina at redhat.com>
Date: Wed, 21 May 2014 16:41:13 +0200
Subject: [PATCH 2/5] SBUS: Add utility function
 sbus_add_array_as_variant_to_dict

---
 src/sbus/sssd_dbus.h            |  7 ++++
 src/sbus/sssd_dbus_properties.c | 76 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index b2b6dd4a3233771391ea6ddcec516cb5f4d4a532..372521a3575f967b751c9e13a7d830d9c3b43584 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -278,6 +278,13 @@ int sbus_add_variant_to_dict(DBusMessageIter *iter_dict,
                              int type,
                              const void *value);
 
+int sbus_add_array_as_variant_to_dict(DBusMessageIter *iter_dict,
+                                      const char *key,
+                                      int type,
+                                      uint8_t *values,
+                                      const int len,
+                                      const unsigned int item_size);
+
 int sbus_request_return_as_variant(struct sbus_request *dbus_req,
                                    int type,
                                    const void *value);
diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c
index 07b33297b13782354cbcf812f129443a14c5d319..a85f0d6e2e5ec40c50a960e0266d97326e1096a1 100644
--- a/src/sbus/sssd_dbus_properties.c
+++ b/src/sbus/sssd_dbus_properties.c
@@ -91,6 +91,82 @@ int sbus_add_variant_to_dict(DBusMessageIter *iter_dict,
     return EOK;
 }
 
+int sbus_add_array_as_variant_to_dict(DBusMessageIter *iter_dict,
+                                      const char *key,
+                                      int type,
+                                      uint8_t *values,
+                                      const int len,
+                                      const unsigned int item_size)
+{
+    DBusMessageIter iter_dict_entry;
+    DBusMessageIter iter_variant;
+    DBusMessageIter iter_array;
+    dbus_bool_t dbret;
+    char variant_type[] = {DBUS_TYPE_ARRAY, type, '\0'};
+    char array_type[] = {type, '\0'};
+    void *addr = NULL;
+    int i;
+
+    dbret = dbus_message_iter_open_container(iter_dict,
+                                             DBUS_TYPE_DICT_ENTRY, NULL,
+                                             &iter_dict_entry);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    /* Start by appending the key */
+    dbret = dbus_message_iter_append_basic(&iter_dict_entry,
+                                           DBUS_TYPE_STRING, &key);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_open_container(&iter_dict_entry,
+                                             DBUS_TYPE_VARIANT,
+                                             variant_type,
+                                             &iter_variant);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_open_container(&iter_variant,
+                                             DBUS_TYPE_ARRAY,
+                                             array_type,
+                                             &iter_array);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    /* Now add the value */
+    for (i = 0; i < len; i++) {
+        addr = values + i * item_size;
+        dbret = dbus_message_iter_append_basic(&iter_array, type, addr);
+        if (!dbret) {
+            return ENOMEM;
+        }
+    }
+
+    dbret = dbus_message_iter_close_container(&iter_variant,
+                                              &iter_array);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_close_container(&iter_dict_entry,
+                                              &iter_variant);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    dbret = dbus_message_iter_close_container(iter_dict,
+                                              &iter_dict_entry);
+    if (!dbret) {
+        return ENOMEM;
+    }
+
+    return EOK;
+}
+
 static int
 dispatch_properties_set(struct sbus_connection *conn,
                         struct sbus_interface *intf,
-- 
1.9.0

-------------- next part --------------
>From 531b1bd155b73ebdd53c8499683028ee0022664c Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 21 May 2014 21:24:42 +0200
Subject: [PATCH 3/5] SBUS: Consolidate VTABLE_FUNC definitions in
 sssd_dbus_meta.h

We had several duplicated declarations of the VTABLE_FUNC macro in the
SSSD source code. This patch consolidates on one definition in
sssd_dbus_meta.h that is usable by all consumers, including the upcoming
GetAll method implementation.
---
 src/sbus/sssd_dbus_connection.c | 4 ----
 src/sbus/sssd_dbus_meta.h       | 4 ++++
 src/sbus/sssd_dbus_private.h    | 4 ----
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index af1c8c56afee7a033e90bc6b2e92c7d8258139a0..06256a85b5e81b39d50923db6d41b64015114ce1 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -394,10 +394,6 @@ static bool sbus_iface_handles_path(struct sbus_interface_p *intf_p,
     return strcmp(path, intf_p->intf->path) == 0;
 }
 
-/* Looks up a vtable func, in a struct derived from struct sbus_vtable */
-#define VTABLE_FUNC(vtable, offset) \
-    (*((void **)((char *)(vtable) + (offset))))
-
 static void sbus_handler_got_caller_id(struct tevent_req *req);
 
 /* messsage_handler
diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h
index 89f11224b9e077e5e9b2ce6b34fc5f93702a2dd4..2cb9e95e3e12da55b1f101e076a0e05203984215 100644
--- a/src/sbus/sssd_dbus_meta.h
+++ b/src/sbus/sssd_dbus_meta.h
@@ -33,6 +33,10 @@
  * http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
  */
 
+/* Looks up a vtable func, in a struct derived from struct sbus_vtable */
+#define VTABLE_FUNC(vtable, offset) \
+    (*((void **)((char *)(vtable) + (offset))))
+
 struct sbus_arg_meta {
     const char *name;
     const char *type;
diff --git a/src/sbus/sssd_dbus_private.h b/src/sbus/sssd_dbus_private.h
index fa11bc1c8ef625ba6c6e9382d7ccd146eabdbb26..624448d30526eb4e927f22f133451c9a63c2cebd 100644
--- a/src/sbus/sssd_dbus_private.h
+++ b/src/sbus/sssd_dbus_private.h
@@ -68,10 +68,6 @@ struct sbus_connection {
     struct sbus_watch_ctx *watch_list;
 };
 
-/* Looks up a vtable func, in a struct derived from struct sbus_vtable */
-#define VTABLE_FUNC(vtable, offset) \
-    (*((void **)((char *)(vtable) + (offset))))
-
 /* =Watches=============================================================== */
 
 struct sbus_watch_ctx {
-- 
1.9.0

-------------- next part --------------
>From d83d66656dd094d2576f436c9c77dc2714b7da1f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 21 May 2014 21:29:15 +0200
Subject: [PATCH 4/5] SBUS: Implement org.freedesktop.DBus.Properties.GetAll
 for primitive types

This patch implements the GetAll method of the
org.freedesktop.DBus.Properties interface by iterating over the
available getters and putting all the results into a single getter.

The patch includes a unit test that exercies all currently supported
array types.
---
 src/monitor/monitor_iface_generated.c         |  58 +++-
 src/providers/data_provider_iface_generated.c |  58 +++-
 src/responder/ifp/ifp_iface_generated.c       |  29 +-
 src/sbus/sbus_codegen                         | 100 ++++++-
 src/sbus/sssd_dbus_properties.c               |   2 +-
 src/tests/sbus_codegen_tests.c                | 301 +++++++++++++++++++
 src/tests/sbus_codegen_tests_generated.c      | 415 +++++++++++++++++++++++++-
 src/tests/sbus_tests.c                        |   1 +
 8 files changed, 947 insertions(+), 17 deletions(-)

diff --git a/src/monitor/monitor_iface_generated.c b/src/monitor/monitor_iface_generated.c
index e9c3c1d52468ac6969498e79491a1d62dc75cc71..ee59242c1bc3b7b30fb5e086a142aedd6be71319 100644
--- a/src/monitor/monitor_iface_generated.c
+++ b/src/monitor/monitor_iface_generated.c
@@ -24,12 +24,39 @@ const struct sbus_method_meta mon_srv_iface__methods[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'org.freedesktop.sssd.monitor' interface */
+static int invoke_mon_srv_iface_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for org.freedesktop.sssd.monitor */
 const struct sbus_interface_meta mon_srv_iface_meta = {
     "org.freedesktop.sssd.monitor", /* name */
     mon_srv_iface__methods,
     NULL, /* no signals */
-    NULL, /* no propetries */
+    NULL, /* no properties */
+    invoke_mon_srv_iface_get_all, /* GetAll invoker */
 };
 
 /* methods for org.freedesktop.sssd.service */
@@ -93,10 +120,37 @@ const struct sbus_method_meta mon_cli_iface__methods[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'org.freedesktop.sssd.service' interface */
+static int invoke_mon_cli_iface_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for org.freedesktop.sssd.service */
 const struct sbus_interface_meta mon_cli_iface_meta = {
     "org.freedesktop.sssd.service", /* name */
     mon_cli_iface__methods,
     NULL, /* no signals */
-    NULL, /* no propetries */
+    NULL, /* no properties */
+    invoke_mon_cli_iface_get_all, /* GetAll invoker */
 };
diff --git a/src/providers/data_provider_iface_generated.c b/src/providers/data_provider_iface_generated.c
index e7eca7def576772a695457444de7aaf99795fb65..58813762570c12b17c26f8116ced347de540b263 100644
--- a/src/providers/data_provider_iface_generated.c
+++ b/src/providers/data_provider_iface_generated.c
@@ -59,12 +59,39 @@ const struct sbus_method_meta data_provider_iface__methods[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'org.freedesktop.sssd.dataprovider' interface */
+static int invoke_data_provider_iface_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for org.freedesktop.sssd.dataprovider */
 const struct sbus_interface_meta data_provider_iface_meta = {
     "org.freedesktop.sssd.dataprovider", /* name */
     data_provider_iface__methods,
     NULL, /* no signals */
-    NULL, /* no propetries */
+    NULL, /* no properties */
+    invoke_data_provider_iface_get_all, /* GetAll invoker */
 };
 
 /* methods for org.freedesktop.sssd.dataprovider_rev */
@@ -86,10 +113,37 @@ const struct sbus_method_meta data_provider_rev_iface__methods[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'org.freedesktop.sssd.dataprovider_rev' interface */
+static int invoke_data_provider_rev_iface_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for org.freedesktop.sssd.dataprovider_rev */
 const struct sbus_interface_meta data_provider_rev_iface_meta = {
     "org.freedesktop.sssd.dataprovider_rev", /* name */
     data_provider_rev_iface__methods,
     NULL, /* no signals */
-    NULL, /* no propetries */
+    NULL, /* no properties */
+    invoke_data_provider_rev_iface_get_all, /* GetAll invoker */
 };
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index d3cb4990cf13fd51621b7606371cdf3175bc789a..91efda251491216fee41663d88fd67b687d3a2cd 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -66,12 +66,39 @@ const struct sbus_method_meta infopipe_iface__methods[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'org.freedesktop.sssd.infopipe' interface */
+static int invoke_infopipe_iface_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for org.freedesktop.sssd.infopipe */
 const struct sbus_interface_meta infopipe_iface_meta = {
     "org.freedesktop.sssd.infopipe", /* name */
     infopipe_iface__methods,
     NULL, /* no signals */
-    NULL, /* no propetries */
+    NULL, /* no properties */
+    invoke_infopipe_iface_get_all, /* GetAll invoker */
 };
 
 /* invokes a handler with a 's' DBus signature */
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index 6507753f2797b354da8aaa2503b7d9bd701668c8..15a6cadacc62e6809a9c807d30a48d6689ec0fd5 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -291,6 +291,21 @@ def source_method_invoker(signature, args):
     out(");")
     out("}")
 
+def source_prop_types(prop, type_prefix=False):
+    prefix = "%s_" % prop.type if type_prefix else ""
+    if prop.is_array:
+        out("    %s *%sprop_val;", prop.sssd_type, prefix)
+        out("    int %sprop_len;", prefix)
+        out("    %s *%sout_val;", prop.dbus_type, prefix)
+    else:
+        out("    %s %sprop_val;", prop.sssd_type, prefix)
+        out("    %s %sout_val;", prop.dbus_type, prefix)
+
+def source_prop_handler(prop, type_prefix=False):
+    prefix = "%s_" % prop.type if type_prefix else ""
+    out("    %s", prop.getter_signature("%shandler" % prefix), new_line=False)
+    out(";")
+
 def source_getter_invoker(prop):
     out("")
     if prop.is_array:
@@ -300,13 +315,9 @@ def source_getter_invoker(prop):
     out("static int %s(struct sbus_request *dbus_req, void *function_ptr)",
         prop.getter_invoker_name())
     out("{")
-    if prop.is_array:
-        out("    %s *prop_val;", prop.sssd_type)
-        out("    int prop_len;")
-        out("    %s *out_val;", prop.dbus_type)
-    else:
-        out("    %s prop_val;", prop.sssd_type)
-        out("    %s out_val;", prop.dbus_type)
+
+    source_prop_types(prop)
+
     out("")
     out("    %s", prop.getter_signature("handler"), new_line=False)
     out(" = function_ptr;")
@@ -330,6 +341,73 @@ def source_getter_invoker(prop):
         out("    return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant)
     out("}")
 
+def source_getall_invoker(iface, prop_invokers):
+    out("")
+    out("/* invokes GetAll for the '%s' interface */", iface.name)
+    out("static int invoke_%s_get_all(struct sbus_request *dbus_req, void *function_ptr)",
+        iface.c_name())
+    out("{")
+    out("    DBusMessage *reply;")
+    out("    dbus_bool_t dbret;")
+    out("    DBusMessageIter iter;")
+    out("    DBusMessageIter iter_dict;")
+    if iface.properties:
+        out("    int ret;")
+        out("    struct sbus_interface *intf = dbus_req->intf;")
+        out("    const struct sbus_property_meta *property;")
+
+    iface_types = [ p.type for p in iface.properties ]
+    for prop in [ p for p in prop_invokers.values() if p.type in iface_types ]:
+        source_prop_types(prop, type_prefix=True)
+        source_prop_handler(prop, type_prefix=True)
+    out("")
+
+    out("    reply = dbus_message_new_method_return(dbus_req->message);")
+    out("    if (!reply) return ENOMEM;")
+    out("    dbus_message_iter_init_append(reply, &iter);")
+    out("    dbret = dbus_message_iter_open_container(")
+    out("                                     &iter, DBUS_TYPE_ARRAY,")
+    out("                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING")
+    out("                                     DBUS_TYPE_STRING_AS_STRING")
+    out("                                     DBUS_TYPE_VARIANT_AS_STRING")
+    out("                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,")
+    out("                                     &iter_dict);")
+    out("    if (!dbret) return ENOMEM;")
+    out("")
+
+    for prop in iface.properties:
+        out("    property = sbus_meta_find_property(intf->vtable->meta, \"%s\");", prop.c_name())
+        out("    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {")
+        out("        %s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);", prop.type)
+        out("        if (%s_handler) {", prop.type)
+        out("            (%s_handler)(dbus_req, dbus_req->intf->instance_data, &%s_prop_val", prop.type, prop.type, new_line=False)
+        if prop.is_array:
+            out(", &%s_prop_len", prop.type, new_line=False)
+        out(");")
+        if prop.type == "s":
+            out("            %s_out_val = %s_prop_val == NULL ? \"\" : %s_prop_val;",
+                prop.type, prop.type, prop.type)
+        elif prop.type == "o":
+            out("            %s_out_val = %s_prop_val == NULL ? \"/\" : %s_prop_val;",
+                prop.type, prop.type, prop.type)
+        else:
+            out("            %s_out_val = %s_prop_val;", prop.type, prop.type)
+        if prop.is_array:
+            out("            ret = sbus_add_array_as_variant_to_dict(&iter_dict, \"%s\", %s, (uint8_t*)%s_out_val, %s_prop_len, sizeof(%s));", prop.c_name(), prop.dbus_constant, prop.type, prop.type, prop.sssd_type)
+        else:
+            out("            ret = sbus_add_variant_to_dict(&iter_dict, \"%s\", %s, &%s_out_val);", prop.c_name(), prop.dbus_constant, prop.type)
+        out("            if (ret != EOK) return ret;")
+        out("        }")
+        out("    }")
+        out("")
+
+    out("    dbret = dbus_message_iter_close_container(&iter, &iter_dict);")
+    out("    if (!dbret) return ENOMEM;")
+    out("")
+
+    out("    return sbus_request_finish(dbus_req, reply);")
+    out("}")
+
 def forward_method_invokers(ifaces):
     invokers = { }
     for iface in ifaces:
@@ -509,9 +587,10 @@ def source_interface(iface):
     else:
         out("    NULL, /* no signals */")
     if iface.properties:
-        out("    %s__properties", iface.c_name())
+        out("    %s__properties,", iface.c_name())
     else:
-        out("    NULL, /* no propetries */")
+        out("    NULL, /* no properties */")
+    out("    invoke_%s_get_all, /* GetAll invoker */", iface.c_name())
     out("};")
 
 def generate_source(ifaces, filename, include_header=None):
@@ -543,6 +622,9 @@ def generate_source(ifaces, filename, include_header=None):
         if iface.properties:
             source_properties(iface, iface.properties)
 
+        # always generate getall, for interfaces without properties
+        # let's return an empty array
+        source_getall_invoker(iface, prop_invokers)
         # The sbus_interface structure
         source_interface(iface)
 
diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c
index a85f0d6e2e5ec40c50a960e0266d97326e1096a1..703f6eb81d8d788b7e9e46d68265b4e6136c0089 100644
--- a/src/sbus/sssd_dbus_properties.c
+++ b/src/sbus/sssd_dbus_properties.c
@@ -345,7 +345,7 @@ dispatch_properties_get_all(struct sbus_connection *conn,
                     sbus_error_new(req,
                                    DBUS_ERROR_INVALID_ARGS,
                                    "Invalid argument types passed " \
-                                   "to Set method"));
+                                   "to GetAll method"));
     }
 
     dbus_message_iter_init(message, &iter);
diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c
index c7da414fe30f46d9d317f3a4205ab38c4e905081..ba972a9ea89dff501df6ada021004725d9005797 100644
--- a/src/tests/sbus_codegen_tests.c
+++ b/src/tests/sbus_codegen_tests.c
@@ -1033,12 +1033,313 @@ START_TEST(test_get_basic_array_types)
 }
 END_TEST
 
+struct prop_test {
+    const char *name;
+    bool handled;
+    int length;
+    int type;
+    union prop_value {
+        bool bool_val;
+        const char *string_val;
+        const char *path_val;
+        uint8_t byte_val;
+        int16_t int16_val;
+        uint16_t uint16_val;
+        int32_t int32_val;
+        uint32_t uint32_val;
+        int64_t int64_val;
+        uint64_t uint64_val;
+        double double_val;
+
+        const char **string_arr_val;
+        const char **path_arr_val;
+        uint8_t *byte_arr_val;
+        int16_t *int16_arr_val;
+        uint16_t *uint16_arr_val;
+        int32_t *int32_arr_val;
+        uint32_t *uint32_arr_val;
+        int64_t *int64_arr_val;
+        uint64_t *uint64_arr_val;
+        double *double_arr_val;
+    } value;
+};
+
+void check_prop(DBusMessageIter *variter, struct prop_test *p)
+{
+    dbus_bool_t bool_val;
+    const char *string_val;
+    const char *path_val;
+    uint8_t byte_val;
+    int16_t int16_val;
+    uint16_t uint16_val;
+    int32_t int32_val;
+    uint32_t uint32_val;
+    int64_t int64_val;
+    uint64_t uint64_val;
+    double double_val;
+    int type;
+
+    type = dbus_message_iter_get_arg_type(variter);
+
+    /* No property should be returned twice */
+    ck_assert(p->handled == false);
+    ck_assert(p->type == type);
+    switch (p->type) {
+        case DBUS_TYPE_BOOLEAN:
+            dbus_message_iter_get_basic(variter, &bool_val);
+            ck_assert(bool_val == p->value.bool_val);
+            break;
+        case DBUS_TYPE_STRING:
+            dbus_message_iter_get_basic(variter, &string_val);
+            ck_assert_str_eq(string_val, p->value.string_val);
+            break;
+        case DBUS_TYPE_BYTE:
+            dbus_message_iter_get_basic(variter, &byte_val);
+            ck_assert_int_eq(byte_val, p->value.byte_val);
+            break;
+        case DBUS_TYPE_INT16:
+            dbus_message_iter_get_basic(variter, &int16_val);
+            ck_assert_int_eq(int16_val, p->value.int16_val);
+            break;
+        case DBUS_TYPE_UINT16:
+            dbus_message_iter_get_basic(variter, &uint16_val);
+            ck_assert_int_eq(uint16_val, p->value.uint16_val);
+            break;
+        case DBUS_TYPE_INT32:
+            dbus_message_iter_get_basic(variter, &int32_val);
+            ck_assert_int_eq(int32_val, p->value.int32_val);
+            break;
+        case DBUS_TYPE_UINT32:
+            dbus_message_iter_get_basic(variter, &uint32_val);
+            ck_assert_int_eq(uint32_val, p->value.uint32_val);
+            break;
+        case DBUS_TYPE_INT64:
+            dbus_message_iter_get_basic(variter, &int64_val);
+            ck_assert_int_eq(int64_val, p->value.int64_val);
+            break;
+        case DBUS_TYPE_UINT64:
+            dbus_message_iter_get_basic(variter, &uint64_val);
+            ck_assert_int_eq(uint64_val, p->value.uint64_val);
+            break;
+        case DBUS_TYPE_DOUBLE:
+            dbus_message_iter_get_basic(variter, &double_val);
+            ck_assert_int_eq(double_val, p->value.double_val);
+            break;
+        case DBUS_TYPE_OBJECT_PATH:
+            dbus_message_iter_get_basic(variter, &path_val);
+            ck_assert_str_eq(path_val, p->value.path_val);
+            break;
+        default:
+            /* Not handled */
+            return;
+    }
+
+    /* This attribute was handled, get the next one */
+    p->handled = true;
+}
+
+void check_arr_prop(DBusMessageIter *variter, struct prop_test *p)
+{
+    DBusMessageIter arriter;
+    const char **strings = NULL;
+    uint8_t *byte_arr_val;
+    int16_t *int16_arr_val;
+    uint16_t *uint16_arr_val;
+    int32_t *int32_arr_val;
+    uint32_t *uint32_arr_val;
+    int64_t *int64_arr_val;
+    uint64_t *uint64_arr_val;
+    double *double_arr_val;
+    int len;
+    int type;
+
+    ck_assert_int_eq(dbus_message_iter_get_arg_type(variter), DBUS_TYPE_ARRAY);
+    type = dbus_message_iter_get_element_type(variter);
+    ck_assert_int_eq(type, p->type);
+
+    dbus_message_iter_recurse(variter, &arriter);
+    if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
+        int n = 0, i = 0;;
+        const char *s;
+
+        do {
+            n++;
+        } while (dbus_message_iter_next(&arriter));
+
+        /* Allocating on NULL is bad, but this is unit test */
+        strings = talloc_array(NULL, const char *, n);
+        ck_assert(strings != NULL);
+
+        dbus_message_iter_recurse(variter, &arriter);
+        do {
+            dbus_message_iter_get_basic(&arriter, &s);
+            strings[i] = talloc_strdup(strings, s);
+            ck_assert(strings[i] != NULL);
+            i++;
+        } while (dbus_message_iter_next(&arriter));
+
+        len = n;
+    }
+
+    switch (p->type) {
+        case DBUS_TYPE_STRING:
+            ck_assert_int_eq(len, 2);
+            ck_assert(strings != NULL);
+            ck_assert_str_eq(strings[0], pilot_string_array[0]);
+            ck_assert_str_eq(strings[1], pilot_string_array[1]);
+            break;
+        case DBUS_TYPE_BYTE:
+            dbus_message_iter_get_fixed_array(&arriter, &byte_arr_val, &len);
+            check_uint_array(byte_arr_val, len, p->value.byte_arr_val);
+            break;
+        case DBUS_TYPE_INT16:
+            dbus_message_iter_get_fixed_array(&arriter, &int16_arr_val, &len);
+            check_int_array(int16_arr_val, len, p->value.int16_arr_val);
+            break;
+        case DBUS_TYPE_UINT16:
+            dbus_message_iter_get_fixed_array(&arriter, &uint16_arr_val, &len);
+            check_uint_array(uint16_arr_val, len, p->value.uint16_arr_val);
+            break;
+        case DBUS_TYPE_INT32:
+            dbus_message_iter_get_fixed_array(&arriter, &int32_arr_val, &len);
+            check_int_array(int32_arr_val, len, p->value.int32_arr_val);
+            break;
+        case DBUS_TYPE_UINT32:
+            dbus_message_iter_get_fixed_array(&arriter, &uint32_arr_val, &len);
+            check_uint_array(uint32_arr_val, len, p->value.uint32_arr_val);
+            break;
+        case DBUS_TYPE_INT64:
+            dbus_message_iter_get_fixed_array(&arriter, &int64_arr_val, &len);
+            check_int_array(int64_arr_val, len, p->value.int64_arr_val);
+            break;
+        case DBUS_TYPE_UINT64:
+            dbus_message_iter_get_fixed_array(&arriter, &uint64_arr_val, &len);
+            check_uint_array(uint64_arr_val, len, p->value.uint64_arr_val);
+            break;
+        case DBUS_TYPE_DOUBLE:
+            dbus_message_iter_get_fixed_array(&arriter, &double_arr_val, &len);
+            check_int_array(double_arr_val, len, p->value.double_arr_val);
+            break;
+        case DBUS_TYPE_OBJECT_PATH:
+            ck_assert_int_eq(len, 2);
+            ck_assert(strings != NULL);
+            ck_assert_str_eq(strings[0], pilot_path_array[0]);
+            ck_assert_str_eq(strings[1], pilot_path_array[1]);
+            break;
+        default:
+            /* Not handled */
+            return;
+    }
+
+
+    p->handled = true;
+}
+
+START_TEST(test_getall_basic_types)
+{
+    DBusMessage *reply;
+    DBusMessageIter iter;
+    DBusMessageIter arriter;
+    DBusMessageIter dictiter;
+    DBusMessageIter variter;
+    dbus_bool_t dbret;
+    DBusError error = DBUS_ERROR_INIT;
+    TALLOC_CTX *ctx;
+    DBusConnection *client;
+    char *attr_name;
+    int i;
+    int num_prop;
+
+    struct prop_test pilot_properties[] = {
+      { "boolean", false, 0, DBUS_TYPE_BOOLEAN, { .bool_val = pilot_bool } },
+      { "FullName", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_full_name } },
+      { "byte", false, 0, DBUS_TYPE_BYTE, { .byte_val = pilot_byte } },
+      { "int16", false, 0, DBUS_TYPE_INT16, { .int16_val = pilot_int16 } },
+      { "uint16", false, 0, DBUS_TYPE_UINT16, { .uint16_val = pilot_uint16 } },
+      { "int32", false, 0, DBUS_TYPE_INT32, { .int32_val = pilot_int32 } },
+      { "uint32", false, 0, DBUS_TYPE_UINT32, { .uint32_val = pilot_uint32 } },
+      { "int64", false, 0, DBUS_TYPE_INT64, { .int64_val = pilot_int64 } },
+      { "uint64", false, 0, DBUS_TYPE_UINT64, { .uint64_val = pilot_uint64 } },
+      { "double", false, 0, DBUS_TYPE_DOUBLE, { .double_val = pilot_double } },
+      { "string", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_string } },
+      { "object_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = pilot_path } },
+      { "null_string", false, 0, DBUS_TYPE_STRING, { .string_val = "" } },
+      { "null_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = "/" } },
+
+      { "byte_array", false, N_ELEMENTS(pilot_byte_array), DBUS_TYPE_BYTE, { .byte_arr_val = pilot_byte_array } },
+      { "int16_array", false, N_ELEMENTS(pilot_int16_array), DBUS_TYPE_INT16, { .int16_arr_val = pilot_int16_array } },
+      { "uint16_array", false, N_ELEMENTS(pilot_uint16_array), DBUS_TYPE_UINT16, { .uint16_arr_val = pilot_uint16_array } },
+      { "int32_array", false, N_ELEMENTS(pilot_int32_array), DBUS_TYPE_INT32, { .int32_arr_val = pilot_int32_array } },
+      { "uint32_array", false, N_ELEMENTS(pilot_uint32_array), DBUS_TYPE_UINT32, { .uint32_arr_val = pilot_uint32_array } },
+      { "int64_array", false, N_ELEMENTS(pilot_int64_array), DBUS_TYPE_INT64, { .int64_arr_val = pilot_int64_array } },
+      { "uint64_array", false, N_ELEMENTS(pilot_uint64_array), DBUS_TYPE_UINT64, { .uint64_arr_val = pilot_uint64_array } },
+      { "double_array", false, N_ELEMENTS(pilot_double_array), DBUS_TYPE_DOUBLE, { .double_arr_val = pilot_double_array } },
+      { "string_array", false, N_ELEMENTS(pilot_string_array), DBUS_TYPE_STRING, { .string_arr_val = pilot_string_array } },
+      { "object_path_array", false, N_ELEMENTS(pilot_path_array), DBUS_TYPE_OBJECT_PATH, { .path_arr_val = pilot_path_array } },
+
+      { NULL, false, 0, 0, { .bool_val = false } }};
+
+    ctx = talloc_new(NULL);
+    client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
+
+    reply = test_dbus_call_sync(client,
+                                "/test/leela",
+                                DBUS_PROPERTIES_INTERFACE,
+                                "GetAll",
+                                &error,
+                                DBUS_TYPE_STRING,
+                                &test_pilot_meta.name,
+                                DBUS_TYPE_INVALID);
+    ck_assert(reply != NULL);
+
+    /* GetAll reply is an array of dictionaries */
+    dbret = dbus_message_iter_init(reply, &iter);
+    ck_assert(dbret == TRUE);
+    ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY);
+
+    dbus_message_iter_recurse(&iter, &arriter);
+    num_prop = 0;
+    do {
+        ck_assert_int_eq(dbus_message_iter_get_arg_type(&arriter),
+                         DBUS_TYPE_DICT_ENTRY);
+        dbus_message_iter_recurse(&arriter, &dictiter);
+        dbus_message_iter_get_basic(&dictiter, &attr_name);
+        ck_assert(dbus_message_iter_next(&dictiter) == TRUE);
+        ck_assert_int_eq(dbus_message_iter_get_arg_type(&dictiter),
+                         DBUS_TYPE_VARIANT);
+
+        dbus_message_iter_recurse(&dictiter, &variter);
+
+        for (i=0; pilot_properties[i].name; i++) {
+            if (strcmp(attr_name, pilot_properties[i].name) == 0) {
+                if (dbus_message_iter_get_arg_type(&variter) == DBUS_TYPE_ARRAY) {
+                    check_arr_prop(&variter, &pilot_properties[i]);
+                } else {
+                    check_prop(&variter, &pilot_properties[i]);
+                }
+                break;
+            }
+        }
+
+        num_prop++;
+    } while(dbus_message_iter_next(&arriter));
+
+    /* All known properties must be handled now */
+    for (i=0; pilot_properties[i].name; i++) {
+        ck_assert(pilot_properties[i].handled == true);
+    }
+    /* Also all properties returned from the bus must be accounted for */
+    ck_assert_uint_eq(num_prop, N_ELEMENTS(pilot_properties)-1);
+}
+END_TEST
+
 TCase *create_handler_tests(void)
 {
     TCase *tc = tcase_create("handler");
 
     tcase_add_test(tc, test_marshal_basic_types);
     tcase_add_test(tc, test_get_basic_types);
+    tcase_add_test(tc, test_getall_basic_types);
     tcase_add_test(tc, test_get_basic_array_types);
 
     return tc;
diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c
index 70302daff7c7a7f5b042428be7d994fa0cdd660a..502d6ce8a0436d5651e27e0ae6e8b87daa8715e3 100644
--- a/src/tests/sbus_codegen_tests_generated.c
+++ b/src/tests/sbus_codegen_tests_generated.c
@@ -125,12 +125,56 @@ const struct sbus_property_meta com_planetexpress_Ship__properties[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'com.planetexpress.Ship' interface */
+static int invoke_com_planetexpress_Ship_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+    int ret;
+    struct sbus_interface *intf = dbus_req->intf;
+    const struct sbus_property_meta *property;
+    const char * s_prop_val;
+    const char * s_out_val;
+    void (*s_handler)(struct sbus_request *, void *data, const char * *);
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    property = sbus_meta_find_property(intf->vtable->meta, "Color");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (s_handler) {
+            (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+            s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "Color", DBUS_TYPE_STRING, &s_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for com.planetexpress.Ship */
 const struct sbus_interface_meta com_planetexpress_Ship_meta = {
     "com.planetexpress.Ship", /* name */
     com_planetexpress_Ship__methods,
     com_planetexpress_Ship__signals,
-    com_planetexpress_Ship__properties
+    com_planetexpress_Ship__properties,
+    invoke_com_planetexpress_Ship_get_all, /* GetAll invoker */
 };
 
 /* arguments for com.planetexpress.Pilot.Blink */
@@ -473,12 +517,379 @@ const struct sbus_property_meta test_pilot__properties[] = {
     { NULL, }
 };
 
+/* invokes GetAll for the 'com.planetexpress.Pilot' interface */
+static int invoke_test_pilot_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+    DBusMessage *reply;
+    dbus_bool_t dbret;
+    DBusMessageIter iter;
+    DBusMessageIter iter_dict;
+    int ret;
+    struct sbus_interface *intf = dbus_req->intf;
+    const struct sbus_property_meta *property;
+    uint16_t *aq_prop_val;
+    int aq_prop_len;
+    uint16_t *aq_out_val;
+    void (*aq_handler)(struct sbus_request *, void *data, uint16_t * *, int *);
+    bool b_prop_val;
+    dbus_bool_t b_out_val;
+    void (*b_handler)(struct sbus_request *, void *data, bool *);
+    double d_prop_val;
+    double d_out_val;
+    void (*d_handler)(struct sbus_request *, void *data, double *);
+    const char * *ao_prop_val;
+    int ao_prop_len;
+    const char * *ao_out_val;
+    void (*ao_handler)(struct sbus_request *, void *data, const char * * *, int *);
+    int32_t i_prop_val;
+    int32_t i_out_val;
+    void (*i_handler)(struct sbus_request *, void *data, int32_t *);
+    const char * *as_prop_val;
+    int as_prop_len;
+    const char * *as_out_val;
+    void (*as_handler)(struct sbus_request *, void *data, const char * * *, int *);
+    const char * o_prop_val;
+    const char * o_out_val;
+    void (*o_handler)(struct sbus_request *, void *data, const char * *);
+    int16_t n_prop_val;
+    int16_t n_out_val;
+    void (*n_handler)(struct sbus_request *, void *data, int16_t *);
+    uint16_t q_prop_val;
+    uint16_t q_out_val;
+    void (*q_handler)(struct sbus_request *, void *data, uint16_t *);
+    uint8_t *ay_prop_val;
+    int ay_prop_len;
+    uint8_t *ay_out_val;
+    void (*ay_handler)(struct sbus_request *, void *data, uint8_t * *, int *);
+    const char * s_prop_val;
+    const char * s_out_val;
+    void (*s_handler)(struct sbus_request *, void *data, const char * *);
+    uint32_t u_prop_val;
+    uint32_t u_out_val;
+    void (*u_handler)(struct sbus_request *, void *data, uint32_t *);
+    uint64_t t_prop_val;
+    uint64_t t_out_val;
+    void (*t_handler)(struct sbus_request *, void *data, uint64_t *);
+    int64_t *ax_prop_val;
+    int ax_prop_len;
+    int64_t *ax_out_val;
+    void (*ax_handler)(struct sbus_request *, void *data, int64_t * *, int *);
+    uint8_t y_prop_val;
+    uint8_t y_out_val;
+    void (*y_handler)(struct sbus_request *, void *data, uint8_t *);
+    int64_t x_prop_val;
+    int64_t x_out_val;
+    void (*x_handler)(struct sbus_request *, void *data, int64_t *);
+    uint32_t *au_prop_val;
+    int au_prop_len;
+    uint32_t *au_out_val;
+    void (*au_handler)(struct sbus_request *, void *data, uint32_t * *, int *);
+    int16_t *an_prop_val;
+    int an_prop_len;
+    int16_t *an_out_val;
+    void (*an_handler)(struct sbus_request *, void *data, int16_t * *, int *);
+    double *ad_prop_val;
+    int ad_prop_len;
+    double *ad_out_val;
+    void (*ad_handler)(struct sbus_request *, void *data, double * *, int *);
+    int32_t *ai_prop_val;
+    int ai_prop_len;
+    int32_t *ai_out_val;
+    void (*ai_handler)(struct sbus_request *, void *data, int32_t * *, int *);
+    uint64_t *at_prop_val;
+    int at_prop_len;
+    uint64_t *at_out_val;
+    void (*at_handler)(struct sbus_request *, void *data, uint64_t * *, int *);
+
+    reply = dbus_message_new_method_return(dbus_req->message);
+    if (!reply) return ENOMEM;
+    dbus_message_iter_init_append(reply, &iter);
+    dbret = dbus_message_iter_open_container(
+                                     &iter, DBUS_TYPE_ARRAY,
+                                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                     DBUS_TYPE_STRING_AS_STRING
+                                     DBUS_TYPE_VARIANT_AS_STRING
+                                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                     &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    property = sbus_meta_find_property(intf->vtable->meta, "FullName");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (s_handler) {
+            (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+            s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "FullName", DBUS_TYPE_STRING, &s_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "byte");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        y_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (y_handler) {
+            (y_handler)(dbus_req, dbus_req->intf->instance_data, &y_prop_val);
+            y_out_val = y_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "byte", DBUS_TYPE_BYTE, &y_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "boolean");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        b_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (b_handler) {
+            (b_handler)(dbus_req, dbus_req->intf->instance_data, &b_prop_val);
+            b_out_val = b_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "boolean", DBUS_TYPE_BOOLEAN, &b_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int16");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        n_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (n_handler) {
+            (n_handler)(dbus_req, dbus_req->intf->instance_data, &n_prop_val);
+            n_out_val = n_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "int16", DBUS_TYPE_INT16, &n_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint16");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        q_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (q_handler) {
+            (q_handler)(dbus_req, dbus_req->intf->instance_data, &q_prop_val);
+            q_out_val = q_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "uint16", DBUS_TYPE_UINT16, &q_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int32");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        i_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (i_handler) {
+            (i_handler)(dbus_req, dbus_req->intf->instance_data, &i_prop_val);
+            i_out_val = i_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "int32", DBUS_TYPE_INT32, &i_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint32");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        u_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (u_handler) {
+            (u_handler)(dbus_req, dbus_req->intf->instance_data, &u_prop_val);
+            u_out_val = u_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "uint32", DBUS_TYPE_UINT32, &u_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int64");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        x_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (x_handler) {
+            (x_handler)(dbus_req, dbus_req->intf->instance_data, &x_prop_val);
+            x_out_val = x_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "int64", DBUS_TYPE_INT64, &x_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint64");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        t_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (t_handler) {
+            (t_handler)(dbus_req, dbus_req->intf->instance_data, &t_prop_val);
+            t_out_val = t_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "uint64", DBUS_TYPE_UINT64, &t_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "double");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        d_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (d_handler) {
+            (d_handler)(dbus_req, dbus_req->intf->instance_data, &d_prop_val);
+            d_out_val = d_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "double", DBUS_TYPE_DOUBLE, &d_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "string");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (s_handler) {
+            (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+            s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "string", DBUS_TYPE_STRING, &s_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "object_path");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        o_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (o_handler) {
+            (o_handler)(dbus_req, dbus_req->intf->instance_data, &o_prop_val);
+            o_out_val = o_prop_val == NULL ? "/" : o_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "object_path", DBUS_TYPE_OBJECT_PATH, &o_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "null_string");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (s_handler) {
+            (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+            s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "null_string", DBUS_TYPE_STRING, &s_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "null_path");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        o_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (o_handler) {
+            (o_handler)(dbus_req, dbus_req->intf->instance_data, &o_prop_val);
+            o_out_val = o_prop_val == NULL ? "/" : o_prop_val;
+            ret = sbus_add_variant_to_dict(&iter_dict, "null_path", DBUS_TYPE_OBJECT_PATH, &o_out_val);
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "byte_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        ay_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (ay_handler) {
+            (ay_handler)(dbus_req, dbus_req->intf->instance_data, &ay_prop_val, &ay_prop_len);
+            ay_out_val = ay_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "byte_array", DBUS_TYPE_BYTE, (uint8_t*)ay_out_val, ay_prop_len, sizeof(uint8_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int16_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        an_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (an_handler) {
+            (an_handler)(dbus_req, dbus_req->intf->instance_data, &an_prop_val, &an_prop_len);
+            an_out_val = an_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int16_array", DBUS_TYPE_INT16, (uint8_t*)an_out_val, an_prop_len, sizeof(int16_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint16_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        aq_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (aq_handler) {
+            (aq_handler)(dbus_req, dbus_req->intf->instance_data, &aq_prop_val, &aq_prop_len);
+            aq_out_val = aq_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint16_array", DBUS_TYPE_UINT16, (uint8_t*)aq_out_val, aq_prop_len, sizeof(uint16_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int32_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        ai_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (ai_handler) {
+            (ai_handler)(dbus_req, dbus_req->intf->instance_data, &ai_prop_val, &ai_prop_len);
+            ai_out_val = ai_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int32_array", DBUS_TYPE_INT32, (uint8_t*)ai_out_val, ai_prop_len, sizeof(int32_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint32_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        au_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (au_handler) {
+            (au_handler)(dbus_req, dbus_req->intf->instance_data, &au_prop_val, &au_prop_len);
+            au_out_val = au_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint32_array", DBUS_TYPE_UINT32, (uint8_t*)au_out_val, au_prop_len, sizeof(uint32_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "int64_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        ax_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (ax_handler) {
+            (ax_handler)(dbus_req, dbus_req->intf->instance_data, &ax_prop_val, &ax_prop_len);
+            ax_out_val = ax_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int64_array", DBUS_TYPE_INT64, (uint8_t*)ax_out_val, ax_prop_len, sizeof(int64_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "uint64_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        at_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (at_handler) {
+            (at_handler)(dbus_req, dbus_req->intf->instance_data, &at_prop_val, &at_prop_len);
+            at_out_val = at_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint64_array", DBUS_TYPE_UINT64, (uint8_t*)at_out_val, at_prop_len, sizeof(uint64_t));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "double_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        ad_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (ad_handler) {
+            (ad_handler)(dbus_req, dbus_req->intf->instance_data, &ad_prop_val, &ad_prop_len);
+            ad_out_val = ad_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "double_array", DBUS_TYPE_DOUBLE, (uint8_t*)ad_out_val, ad_prop_len, sizeof(double));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "string_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        as_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (as_handler) {
+            (as_handler)(dbus_req, dbus_req->intf->instance_data, &as_prop_val, &as_prop_len);
+            as_out_val = as_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "string_array", DBUS_TYPE_STRING, (uint8_t*)as_out_val, as_prop_len, sizeof(const char *));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    property = sbus_meta_find_property(intf->vtable->meta, "object_path_array");
+    if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+        ao_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+        if (ao_handler) {
+            (ao_handler)(dbus_req, dbus_req->intf->instance_data, &ao_prop_val, &ao_prop_len);
+            ao_out_val = ao_prop_val;
+            ret = sbus_add_array_as_variant_to_dict(&iter_dict, "object_path_array", DBUS_TYPE_OBJECT_PATH, (uint8_t*)ao_out_val, ao_prop_len, sizeof(const char *));
+            if (ret != EOK) return ret;
+        }
+    }
+
+    dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+    if (!dbret) return ENOMEM;
+
+    return sbus_request_finish(dbus_req, reply);
+}
+
 /* interface info for com.planetexpress.Pilot */
 const struct sbus_interface_meta test_pilot_meta = {
     "com.planetexpress.Pilot", /* name */
     test_pilot__methods,
     NULL, /* no signals */
-    test_pilot__properties
+    test_pilot__properties,
+    invoke_test_pilot_get_all, /* GetAll invoker */
 };
 
 /* invokes a handler with a 'bu' DBus signature */
diff --git a/src/tests/sbus_tests.c b/src/tests/sbus_tests.c
index d2725cf0e542f20bc1d22db91fa04e80392e7fa9..8572f3263e7b7386f0e7497b22c4790388128daa 100644
--- a/src/tests/sbus_tests.c
+++ b/src/tests/sbus_tests.c
@@ -98,6 +98,7 @@ const struct sbus_interface_meta pilot_meta = {
     pilot_methods,
     NULL, /* no signals */
     NULL, /* no properties */
+    NULL, /* no GetAll invoker */
 };
 
 static int blink_handler(struct sbus_request *req, void *data)
-- 
1.9.0

-------------- next part --------------
>From 3069c68d947c5e84c44148d9bdac0cd318d48286 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 21 May 2014 20:10:23 +0200
Subject: [PATCH 5/5] SBUS: Add org.freedesktop.DBus.Properties.GetAll to
 Introspection

---
 src/sbus/sssd_dbus_introspect.c | 4 ++++
 src/tests/sbus_tests.c          | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/src/sbus/sssd_dbus_introspect.c b/src/sbus/sssd_dbus_introspect.c
index 73434faf7d226ea1f58e10d319cc79852997136b..977383356c4df05215007253a5d1327c22a3507e 100644
--- a/src/sbus/sssd_dbus_introspect.c
+++ b/src/sbus/sssd_dbus_introspect.c
@@ -57,6 +57,10 @@ const struct sbus_method_meta introspect_method =
      "     <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"          \
      "     <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"            \
      "   </method>\n"                                                       \
+     "   <method name=\"GetAll\">\n"                                        \
+     "     <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"         \
+     "     <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n"   \
+     "   </method>\n"                                                       \
      " </interface>\n"
 
 struct introspect_ctx {
diff --git a/src/tests/sbus_tests.c b/src/tests/sbus_tests.c
index 8572f3263e7b7386f0e7497b22c4790388128daa..50c452e42ff0085b554be8991a7b34d1405c3b3c 100644
--- a/src/tests/sbus_tests.c
+++ b/src/tests/sbus_tests.c
@@ -65,6 +65,10 @@
         "     <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"                        \
         "     <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"                          \
         "   </method>\n"                                                                     \
+        "   <method name=\"GetAll\">\n"                                                      \
+        "     <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"                       \
+        "     <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n"                 \
+        "   </method>\n"                                                                     \
         " </interface>\n"                                                                    \
         "</node>\n"
 
-- 
1.9.0



More information about the sssd-devel mailing list