summaryrefslogtreecommitdiffstats
path: root/src/sbus/sssd_dbus_properties.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbus/sssd_dbus_properties.c')
-rw-r--r--src/sbus/sssd_dbus_properties.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c
new file mode 100644
index 000000000..835b3078b
--- /dev/null
+++ b/src/sbus/sssd_dbus_properties.c
@@ -0,0 +1,122 @@
+/*
+ Authors:
+ Stef Walter <stefw@redhat.com>
+
+ Copyright (C) 2014 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus/sssd_dbus_meta.h"
+#include "sbus/sssd_dbus_private.h"
+
+static int
+dispatch_properties_set(struct sbus_connection *conn,
+ struct sbus_interface *intf,
+ DBusMessage *message)
+{
+ const char *signature;
+ const struct sbus_interface_meta *meta;
+ const struct sbus_property_meta *property;
+ const char *interface_name;
+ const char *property_name;
+ const char *type;
+ struct sbus_request *req;
+ sbus_msg_handler_fn handler_fn;
+ DBusMessageIter iter;
+ DBusMessageIter variant;
+
+ req = sbus_new_request(conn, intf, message);
+ if (!req)
+ return ENOMEM;
+
+ meta = intf->vtable->meta;
+
+ signature = dbus_message_get_signature(message);
+ if (strcmp (signature, "ssv") != 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);
+ dbus_message_iter_next (&iter);
+ dbus_message_iter_get_basic (&iter, &property_name);
+ dbus_message_iter_next (&iter);
+
+ 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"));
+ }
+
+ property = sbus_meta_find_property (intf->vtable->meta, property_name);
+ if (property == NULL) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_UNKNOWN_PROPERTY,
+ "No such property"));
+ }
+
+ if (!(property->flags & SBUS_PROPERTY_WRITABLE)) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_PROPERTY_READ_ONLY,
+ "Property is not writable"));
+ }
+
+ dbus_message_iter_recurse(&iter, &variant);
+ type = dbus_message_iter_get_signature (&variant);
+ if (strcmp (property->type, type) != 0) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_INVALID_ARGS,
+ "Invalid data type for property"));
+ }
+
+ handler_fn = VTABLE_FUNC(intf->vtable, property->vtable_offset_set);
+ if (!handler_fn) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_NOT_SUPPORTED,
+ "Not implemented"));
+ }
+
+ sbus_request_invoke_or_finish(req, handler_fn,
+ intf->instance_data,
+ property->invoker_set);
+ return EOK;
+}
+
+int sbus_properties_dispatch(struct sbus_request *dbus_req)
+{
+ const char *member;
+
+ member = dbus_message_get_member(dbus_req->message);
+
+ /* Set is handled a lot like a method invocation */
+ if (strcmp(member, "Set") == 0) {
+ return dispatch_properties_set(dbus_req->conn,
+ dbus_req->intf,
+ dbus_req->message);
+ }
+
+ return ERR_SBUS_NOSUP;
+}