From ec4f7a8072cf8d7369e73938bde4c1d9e746790f Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Tue, 11 Feb 2014 17:13:49 +0100 Subject: ListDomains via libdbus --- .gitignore | 1 + src/main.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore index 6222d9d..69c3bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ build/* Debug/* Release/* +/Debug diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2daf927 --- /dev/null +++ b/src/main.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include + +typedef int errno_t; +#define EOK 0 + +#define INFOPIPE_DBUS_NAME "org.freedesktop.sssd.infopipe" +#define INFOPIPE_INTERFACE "org.freedesktop.sssd.infopipe" +#define INFOPIPE_PATH "/org/freedesktop/sssd/infopipe" + +#define SSS_METHOD_DOMAIN_LIST "ListDomains" + +#define DBUS_PROP_IFACE "org.freedesktop.DBus.Properties" + +static DBusMessage* sss_dbus_infopipe_call(DBusConnection *conn, + const char *method) +{ + return dbus_message_new_method_call(INFOPIPE_DBUS_NAME, + INFOPIPE_PATH, + INFOPIPE_INTERFACE, + method); +} + +static DBusMessage* sss_dbus_property_call(DBusConnection *conn, + const char *object_path, + const char *method) +{ + return dbus_message_new_method_call(INFOPIPE_DBUS_NAME, + object_path, + DBUS_PROP_IFACE, + method); +} + +errno_t sss_dbus_get_string_property(TALLOC_CTX *mem_ctx, + DBusConnection *conn, + DBusError *error, + const char *object_path, + const char *property, + char **_out) +{ + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusMessageIter iter; + DBusMessageIter subiter; + char *prop = NULL; + dbus_bool_t dbret; + errno_t ret; + + msg = sss_dbus_property_call(conn, object_path, "Get"); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + + dbret = dbus_message_append_args(msg, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (!dbret) { + ret = ENOMEM; + goto done; + } + + reply = dbus_connection_send_with_reply_and_block(conn, msg, 5000, error); + if (dbus_error_is_set(error)) { + ret = EIO; + goto done; + } + + dbus_message_iter_init(reply, &iter); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + ret = EINVAL; + goto done; + } + + dbus_message_iter_recurse(&iter, &subiter); + + if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING) { + ret = EINVAL; + goto done; + } + + dbus_message_iter_get_basic(&subiter, &prop); + + *_out = talloc_strdup(mem_ctx, prop); + if (*_out == NULL) { + ret = ENOMEM; + goto done; + } + + ret = EOK; + +done: + if (msg != NULL) { + dbus_message_unref(msg); + } + + if (reply != NULL) { + dbus_message_unref(reply); + } + + return ret; +} + +errno_t sss_dbus_list_domains(TALLOC_CTX *mem_ctx, + DBusConnection *conn, + DBusError *error, + char ***_domains) +{ + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + char **domains = NULL; + char **objects = NULL; + int num_objects; + dbus_bool_t dbret; + errno_t ret; + int i; + + if (conn == NULL || error == NULL) { + ret = EINVAL; + goto done; + } + + msg = sss_dbus_infopipe_call(conn, SSS_METHOD_DOMAIN_LIST); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + + reply = dbus_connection_send_with_reply_and_block(conn, msg, 5000, error); + if (dbus_error_is_set(error)) { + ret = EIO; + goto done; + } + + dbret = dbus_message_get_args(reply, error, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, + &objects, &num_objects, + DBUS_TYPE_INVALID); + if (!dbret) { + ret = EIO; + goto done; + } + + if (objects == NULL || num_objects == 0) { + ret = ENOENT; + goto done; + } + + domains = talloc_zero_array(mem_ctx, char*, num_objects + 1); + if (domains == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_objects; i++) { + ret = sss_dbus_get_string_property(domains, conn, error, objects[i], + "name", &domains[i]); + if (ret != EOK) { + goto done; + } + } + + *_domains = domains; + + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(domains); + } + + if (msg != NULL) { + dbus_message_unref(msg); + } + + if (reply != NULL) { + dbus_message_unref(reply); + } + + return ret; +} + +int main(int argc, const char **argv) +{ + DBusConnection *conn = NULL; + DBusError error; + char **domains = NULL; + errno_t ret; + int i; + + dbus_error_init(&error); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (dbus_error_is_set(&error)) { + fprintf(stderr, "Failed to open connection to bus: %s\n", + error.message); + return 1; + } + + ret = sss_dbus_list_domains(NULL, conn, &error, &domains); + if (ret != EOK) { + fprintf(stderr, "Error [%d]: %s\n", ret, strerror(ret)); + return 1; + } + + for (i = 0; domains[i] != NULL; i++) { + printf("%s\n", domains[i]); + } + + dbus_connection_unref(conn); + + return 0; +} -- cgit