1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter/*
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Authors:
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Stef Walter <stefw@redhat.com>
b742179ac0790068380618ab72a06af18544f09cPavel Březina Pavel Březina <pbrezina@redhat.com>
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Copyright (C) 2014 Red Hat
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter This program is free software; you can redistribute it and/or modify
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter it under the terms of the GNU General Public License as published by
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter the Free Software Foundation; either version 3 of the License, or
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter (at your option) any later version.
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter This program is distributed in the hope that it will be useful,
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter but WITHOUT ANY WARRANTY; without even the implied warranty of
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter GNU General Public License for more details.
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter You should have received a copy of the GNU General Public License
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter along with this program. If not, see <http://www.gnu.org/licenses/>.
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter*/
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
b742179ac0790068380618ab72a06af18544f09cPavel Březina#include "config.h"
b742179ac0790068380618ab72a06af18544f09cPavel Březina
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter#include "util/util.h"
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter#include "sbus/sssd_dbus.h"
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter#include "sbus/sssd_dbus_meta.h"
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter#include "sbus/sssd_dbus_private.h"
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina#include "sbus/sssd_dbus_invokers.h"
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter
b742179ac0790068380618ab72a06af18544f09cPavel Březina#define CHECK_SIGNATURE_OR_FAIL(req, error, label, exp) do { \
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *__sig; \
b742179ac0790068380618ab72a06af18544f09cPavel Březina __sig = dbus_message_get_signature(req->message); \
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (strcmp(__sig, exp) != 0) { \
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(req, DBUS_ERROR_INVALID_ARGS, \
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid arguments: expected \"%s\", got \"%s\"", exp, __sig); \
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto label; \
b742179ac0790068380618ab72a06af18544f09cPavel Březina } \
b742179ac0790068380618ab72a06af18544f09cPavel Březina} while (0)
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinastruct iface_properties {
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_vtable vtable; /* derive from sbus_vtable */
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_msg_handler_fn Get;
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_msg_handler_fn Set;
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_msg_handler_fn GetAll;
b742179ac0790068380618ab72a06af18544f09cPavel Březina};
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_set(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinastruct sbus_vtable *
b742179ac0790068380618ab72a06af18544f09cPavel Březinasbus_properties_vtable(void)
b742179ac0790068380618ab72a06af18544f09cPavel Březina{
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.Get */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "interface_name", "s" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "property_name", "s" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "value", "v" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.Set */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta set_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "interface_name", "s" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "property_name", "s" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "value", "v" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.GetAll */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "interface_name", "s" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { "props", "a{sv}" },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_method_meta iface_methods[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina {
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Get", /* name */
b742179ac0790068380618ab72a06af18544f09cPavel Březina get_args_in,
b742179ac0790068380618ab72a06af18544f09cPavel Březina get_args_out,
b742179ac0790068380618ab72a06af18544f09cPavel Březina offsetof(struct iface_properties, Get),
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no invoker */
b742179ac0790068380618ab72a06af18544f09cPavel Březina },
b742179ac0790068380618ab72a06af18544f09cPavel Březina {
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Set", /* name */
b742179ac0790068380618ab72a06af18544f09cPavel Březina set_args_in,
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no out_args */
b742179ac0790068380618ab72a06af18544f09cPavel Březina offsetof(struct iface_properties, Set),
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no invoker */
b742179ac0790068380618ab72a06af18544f09cPavel Březina },
b742179ac0790068380618ab72a06af18544f09cPavel Březina {
b742179ac0790068380618ab72a06af18544f09cPavel Březina "GetAll", /* name */
b742179ac0790068380618ab72a06af18544f09cPavel Březina getall_args_in,
b742179ac0790068380618ab72a06af18544f09cPavel Březina getall_args_out,
b742179ac0790068380618ab72a06af18544f09cPavel Březina offsetof(struct iface_properties, GetAll),
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no invoker */
b742179ac0790068380618ab72a06af18544f09cPavel Březina },
b742179ac0790068380618ab72a06af18544f09cPavel Březina { NULL, }
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_interface_meta iface_meta = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina "org.freedesktop.DBus.Properties", /* name */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface_methods,
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no signals */
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no properties */
b742179ac0790068380618ab72a06af18544f09cPavel Březina NULL, /* no GetAll invoker */
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina static struct iface_properties iface = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina { &iface_meta, 0 },
b742179ac0790068380618ab72a06af18544f09cPavel Březina .Get = sbus_properties_get,
b742179ac0790068380618ab72a06af18544f09cPavel Březina .Set = sbus_properties_set,
b742179ac0790068380618ab72a06af18544f09cPavel Březina .GetAll = sbus_properties_get_all,
b742179ac0790068380618ab72a06af18544f09cPavel Březina };
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina return &iface.vtable;
b742179ac0790068380618ab72a06af18544f09cPavel Březina}
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březinastatic struct sbus_request *
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březinasbus_properties_subreq(struct sbus_request *sbus_req,
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina struct sbus_interface *iface)
b742179ac0790068380618ab72a06af18544f09cPavel Březina{
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_request *sbus_subreq;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Create new sbus_request to so it contain given interface. The
b742179ac0790068380618ab72a06af18544f09cPavel Březina * old sbus_request talloc context will be attached to this new one
b742179ac0790068380618ab72a06af18544f09cPavel Březina * so it is freed together. */
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_subreq = sbus_new_request(sbus_req->conn, iface, sbus_req->message);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (sbus_subreq == NULL) {
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina return NULL;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina talloc_steal(sbus_subreq, sbus_req);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina return sbus_subreq;
b742179ac0790068380618ab72a06af18544f09cPavel Březina}
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina{
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBusError *error;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina struct sbus_request *sbus_subreq;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_connection *conn;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_interface *iface;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const struct sbus_property_meta *prop;
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_msg_handler_fn handler_fn;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *interface_name;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *property_name;
b742179ac0790068380618ab72a06af18544f09cPavel Březina bool bret;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ss");
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina bret = sbus_request_parse_or_finish(sbus_req,
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBUS_TYPE_STRING, &interface_name,
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBUS_TYPE_STRING, &property_name,
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBUS_TYPE_INVALID);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!bret) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina return EOK;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina interface_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (iface == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (prop == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!(prop->flags & SBUS_PROPERTY_READABLE)) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Property is not readable");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_get);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (handler_fn == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Getter is not implemented");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina if (sbus_subreq == NULL) {
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina error = NULL;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina goto fail;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina }
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_invoke_get(sbus_subreq, prop->type,
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina prop->invoker_get, handler_fn);
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina return EOK;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinafail:
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březina}
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina/*
b742179ac0790068380618ab72a06af18544f09cPavel Březina * We don't implement any handlers for setters yet. This code is for future
b742179ac0790068380618ab72a06af18544f09cPavel Březina * use and it is likely it will need some changes.
b742179ac0790068380618ab72a06af18544f09cPavel Březina */
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_set(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina{
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBusError *error;
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBusMessageIter iter;
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBusMessageIter iter_variant;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina struct sbus_request *sbus_subreq;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_connection *conn;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_interface *iface;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const struct sbus_property_meta *prop;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *interface_name;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *property_name;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *variant_sig;
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_msg_handler_fn handler_fn;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ssv");
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* get interface and property */
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_init(sbus_req->message, &iter);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_get_basic(&iter, &interface_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_next(&iter);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_get_basic(&iter, &property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_next(&iter);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina interface_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (iface == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (prop == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!(prop->flags & SBUS_PROPERTY_WRITABLE)) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Property is not writable");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_set);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (handler_fn == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Setter is not implemented");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* check variant type */
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_recurse(&iter, &iter_variant);
b742179ac0790068380618ab72a06af18544f09cPavel Březina variant_sig = dbus_message_iter_get_signature(&iter_variant);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (strcmp(prop->type, variant_sig) != 0) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_INVALID_ARGS,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid data type for property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina if (sbus_subreq == NULL) {
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina error = NULL;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina goto fail;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina }
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_request_invoke_or_finish(sbus_subreq, handler_fn,
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina iface->handler_data, prop->invoker_set);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina return EOK;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinafail:
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březina}
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina{
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBusError *error;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina struct sbus_request *sbus_subreq;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_connection *conn;
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_interface *iface;
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *interface_name;
b742179ac0790068380618ab72a06af18544f09cPavel Březina bool bret;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "s");
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina bret = sbus_request_parse_or_finish(sbus_req,
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBUS_TYPE_STRING, &interface_name,
b742179ac0790068380618ab72a06af18544f09cPavel Březina DBUS_TYPE_INVALID);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!bret) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina return EOK;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina interface_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (iface == NULL) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina goto fail;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina if (sbus_subreq == NULL) {
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina error = NULL;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina goto fail;
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina }
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina if (iface->vtable->meta->invoker_get_all == NULL) {
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "No get all invoker set,"
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina "using the default one\n");
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina sbus_invoke_get_all(sbus_req);
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina } else {
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina iface->vtable->meta->invoker_get_all(sbus_subreq);
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina }
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina return EOK;
b742179ac0790068380618ab72a06af18544f09cPavel Březina
b742179ac0790068380618ab72a06af18544f09cPavel Březinafail:
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březina}