sssd_dbus_properties.c revision 66277b21179d95f6e96abed01a20ccbccf27ce99
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Stef Walter <stefw@redhat.com>
b742179ac0790068380618ab72a06af18544f09cPavel Březina Pavel Březina <pbrezina@redhat.com>
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Copyright (C) 2014 Red Hat
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 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 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/>.
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 error = sbus_error_new(req, DBUS_ERROR_INVALID_ARGS, \
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid arguments: expected \"%s\", got \"%s\"", exp, __sig); \
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_vtable vtable; /* derive from sbus_vtable */
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 /* Properties.Get */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.Set */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta set_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.GetAll */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_method_meta iface_methods[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_interface_meta iface_meta = {
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_invoke(struct sbus_request *sbus_req,
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 sbus_request_invoke_or_finish(sbus_subreq, handler_fn, handler_data,
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ss");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
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 handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_get);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Getter is not implemented");
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_properties_invoke(sbus_req, iface, handler_fn,
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
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řezinastatic int sbus_properties_set(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ssv");
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_get_basic(&iter, &property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
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 handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_set);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Setter is not implemented");
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 error = sbus_error_new(sbus_req, DBUS_ERROR_INVALID_ARGS,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid data type for property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_properties_invoke(sbus_req, iface, handler_fn,
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "s");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_properties_invoke(sbus_req, iface, NULL, NULL,
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozekstatic char *
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek if (l != 1) {
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozekint sbus_add_variant_to_dict(DBusMessageIter *iter_dict,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek const char *key,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_open_container(iter_dict,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek /* Start by appending the key */
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_append_basic(&iter_dict_entry,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_open_container(&iter_dict_entry,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek /* Now add the value */
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_append_basic(&iter_dict_val, type, value);
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_close_container(&iter_dict_entry,
c43ed56bc5d29e189e529235a3ba4bc17cd1a95fJakub Hrozek dbret = dbus_message_iter_close_container(iter_dict,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březinaint sbus_add_array_as_variant_to_dict(DBusMessageIter *iter_dict,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina const char *key,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina const unsigned int item_size)
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina char variant_type[] = {DBUS_TYPE_ARRAY, type, '\0'};
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_open_container(iter_dict,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina /* Start by appending the key */
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_append_basic(&iter_dict_entry,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_open_container(&iter_dict_entry,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_open_container(&iter_variant,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina /* Now add the value */
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina for (i = 0; i < len; i++) {
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_append_basic(&iter_array, type, addr);
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_close_container(&iter_variant,
2965f42fed62b77a5b0e7f6cd01c4be1072484f5Pavel Březina dbret = dbus_message_iter_close_container(&iter_dict_entry,