diff options
Diffstat (limited to 'src/sbus/sssd_dbus_properties.c')
-rw-r--r-- | src/sbus/sssd_dbus_properties.c | 122 |
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; +} |