1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* driver.c Bus client (driver)
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
7 * Licensed under the Academic Free License version 2.1
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "activation.h"
28 #include "connection.h"
37 #include <dbus/dbus-asv-util.h>
38 #include <dbus/dbus-connection-internal.h>
39 #include <dbus/dbus-string.h>
40 #include <dbus/dbus-internals.h>
41 #include <dbus/dbus-message.h>
42 #include <dbus/dbus-marshal-recursive.h>
43 #include <dbus/dbus-marshal-validate.h>
46 static inline const char *
47 nonnull (const char *maybe_null,
50 return (maybe_null ? maybe_null : if_null);
53 static DBusConnection *
54 bus_driver_get_owner_of_name (DBusConnection *connection,
57 BusRegistry *registry;
61 registry = bus_connection_get_registry (connection);
62 _dbus_string_init_const (&str, name);
63 serv = bus_registry_lookup (registry, &str);
68 return bus_service_get_primary_owners_connection (serv);
72 bus_driver_get_conn_helper (DBusConnection *connection,
74 const char *what_we_want,
76 DBusConnection **peer_conn_p,
82 if (!dbus_message_get_args (message, error,
83 DBUS_TYPE_STRING, &name,
85 return BUS_DRIVER_FOUND_ERROR;
87 _dbus_assert (name != NULL);
88 _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
93 if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
94 return BUS_DRIVER_FOUND_SELF;
96 conn = bus_driver_get_owner_of_name (connection, name);
100 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
101 "Could not get %s of name '%s': no such name",
103 return BUS_DRIVER_FOUND_ERROR;
106 if (peer_conn_p != NULL)
109 return BUS_DRIVER_FOUND_PEER;
113 * Log a security warning and set error unless the uid of the connection
114 * is either the uid of this process, or on Unix, uid 0 (root).
116 * This is intended to be a second line of defence after <deny> rules,
117 * to mitigate incorrect system bus security policy configuration files
118 * like the ones in CVE-2014-8148 and CVE-2014-8156, and (if present)
119 * LSM rules; so it doesn't need to be perfect, but as long as we have
120 * potentially dangerous functionality in the system bus, it does need
124 bus_driver_check_caller_is_privileged (DBusConnection *connection,
125 BusTransaction *transaction,
126 DBusMessage *message,
132 if (!dbus_connection_get_unix_user (connection, &uid))
134 const char *method = dbus_message_get_member (message);
136 bus_context_log_and_set_error (bus_transaction_get_context (transaction),
137 DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
138 "rejected attempt to call %s by connection %s (%s) with "
139 "unknown uid", method,
140 nonnull (bus_connection_get_name (connection), "(inactive)"),
141 bus_connection_get_loginfo (connection));
145 /* I'm writing it in this slightly strange form so that it's more
146 * obvious that this security-sensitive code is correct.
148 if (_dbus_unix_user_is_process_owner (uid))
158 const char *method = dbus_message_get_member (message);
160 bus_context_log_and_set_error (bus_transaction_get_context (transaction),
161 DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
162 "rejected attempt to call %s by connection %s (%s) with "
164 nonnull (bus_connection_get_name (connection), "(inactive)"),
165 bus_connection_get_loginfo (connection), uid);
170 #elif defined(DBUS_WIN)
171 char *windows_sid = NULL;
172 dbus_bool_t ret = FALSE;
174 if (!dbus_connection_get_windows_user (connection, &windows_sid))
176 const char *method = dbus_message_get_member (message);
178 bus_context_log_and_set_error (bus_transaction_get_context (transaction),
179 DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
180 "rejected attempt to call %s by unknown uid", method);
184 if (!_dbus_windows_user_is_process_owner (windows_sid))
186 const char *method = dbus_message_get_member (message);
188 bus_context_log_and_set_error (bus_transaction_get_context (transaction),
189 DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
190 "rejected attempt to call %s by uid %s", method, windows_sid);
196 dbus_free (windows_sid);
199 /* make sure we fail closed in the hypothetical case that we are neither
200 * Unix nor Windows */
201 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
202 "please teach bus/driver.c how uids work on this platform");
207 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
208 DBusMessage *hello_message,
209 BusTransaction *transaction,
213 bus_driver_send_connection_overflow (DBusConnection *connection,
214 BusTransaction *transaction,
217 DBusMessage *message;
221 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
223 message = dbus_message_new_signal (DBUS_PATH_DBUS,
224 DBUS_INTERFACE_TIZEN,
225 DBUS_TIZEN_CONNECTION_OVERFLOW_SIGNAL);
233 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
236 name = bus_connection_get_name (connection);
238 if (!dbus_message_append_args (message,
239 DBUS_TYPE_STRING, &name,
243 _dbus_assert (dbus_message_has_signature (message, "s"));
245 if (!bus_transaction_capture (transaction, NULL, NULL, message))
248 switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
250 case BUS_RESULT_TRUE:
253 case BUS_RESULT_FALSE:
256 case BUS_RESULT_LATER:
258 /* should never happen */
259 _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
263 dbus_message_unref (message);
268 dbus_message_unref (message);
274 bus_driver_send_service_owner_changed (const char *service_name,
275 const char *old_owner,
276 const char *new_owner,
277 BusTransaction *transaction,
280 DBusMessage *message;
282 const char *null_service;
284 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
287 _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
289 old_owner ? old_owner : null_service,
290 new_owner ? new_owner : null_service);
292 message = dbus_message_new_signal (DBUS_PATH_DBUS,
302 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
305 if (!dbus_message_append_args (message,
306 DBUS_TYPE_STRING, &service_name,
307 DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
308 DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
312 _dbus_assert (dbus_message_has_signature (message, "sss"));
314 if (!bus_transaction_capture (transaction, NULL, NULL, message))
317 switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
319 case BUS_RESULT_TRUE:
322 case BUS_RESULT_FALSE:
326 /* should never happen */
327 _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
331 dbus_message_unref (message);
336 dbus_message_unref (message);
342 bus_driver_send_service_lost (DBusConnection *connection,
343 const char *service_name,
344 BusTransaction *transaction,
347 DBusMessage *message;
349 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
351 message = dbus_message_new_signal (DBUS_PATH_DBUS,
361 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
362 !dbus_message_append_args (message,
363 DBUS_TYPE_STRING, &service_name,
366 dbus_message_unref (message);
371 if (!bus_transaction_send_from_driver (transaction, connection, message))
373 dbus_message_unref (message);
379 dbus_message_unref (message);
385 bus_driver_send_service_acquired (DBusConnection *connection,
386 const char *service_name,
387 BusTransaction *transaction,
390 DBusMessage *message;
392 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
394 message = dbus_message_new_signal (DBUS_PATH_DBUS,
404 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
405 !dbus_message_append_args (message,
406 DBUS_TYPE_STRING, &service_name,
409 dbus_message_unref (message);
414 if (!bus_transaction_send_from_driver (transaction, connection, message))
416 dbus_message_unref (message);
422 dbus_message_unref (message);
428 create_unique_client_name (BusRegistry *registry,
431 /* We never want to use the same unique client name twice, because
432 * we want to guarantee that if you send a message to a given unique
433 * name, you always get the same application. So we use two numbers
434 * for INT_MAX * INT_MAX combinations, should be pretty safe against
437 /* FIXME these should be in BusRegistry rather than static vars */
438 static int next_major_number = 0;
439 static int next_minor_number = 0;
442 len = _dbus_string_get_length (str);
446 /* start out with 1-0, go to 1-1, 1-2, 1-3,
447 * up to 1-MAXINT, then 2-0, 2-1, etc.
449 if (next_minor_number <= 0)
451 next_major_number += 1;
452 next_minor_number = 0;
453 if (next_major_number <= 0)
454 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
457 _dbus_assert (next_major_number > 0);
458 _dbus_assert (next_minor_number >= 0);
460 /* appname:MAJOR-MINOR */
462 if (!_dbus_string_append (str, ":"))
465 if (!_dbus_string_append_int (str, next_major_number))
468 if (!_dbus_string_append (str, "."))
471 if (!_dbus_string_append_int (str, next_minor_number))
474 next_minor_number += 1;
476 /* Check if a client with the name exists */
477 if (bus_registry_lookup (registry, str) == NULL)
480 /* drop the number again, try the next one. */
481 _dbus_string_set_length (str, len);
488 bus_driver_handle_hello (DBusConnection *connection,
489 BusTransaction *transaction,
490 DBusMessage *message,
493 DBusString unique_name;
496 BusRegistry *registry;
497 BusConnections *connections;
500 const char *limit_name;
502 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
504 if (bus_connection_is_active (connection))
506 /* We already handled an Hello message for this connection. */
507 dbus_set_error (error, DBUS_ERROR_FAILED,
508 "Already handled an Hello message");
509 return BUS_RESULT_FALSE;
512 /* Note that when these limits are exceeded we don't disconnect the
513 * connection; we just sort of leave it hanging there until it times
514 * out or disconnects itself or is dropped due to the max number of
515 * incomplete connections. It's even OK if the connection wants to
516 * retry the hello message, we support that.
518 dbus_error_init (&tmp_error);
519 connections = bus_connection_get_connections (connection);
520 if (!bus_connections_check_limits (connections, connection,
526 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
527 context = bus_connection_get_context (connection);
528 bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s (%s=%d)",
529 tmp_error.message, limit_name, limit);
530 dbus_move_error (&tmp_error, error);
531 return BUS_RESULT_FALSE;
534 if (!_dbus_string_init (&unique_name))
537 return BUS_RESULT_FALSE;
540 retval = BUS_RESULT_FALSE;
542 registry = bus_connection_get_registry (connection);
544 if (!create_unique_client_name (registry, &unique_name))
550 if (!bus_connection_complete (connection, &unique_name, error))
552 _DBUS_ASSERT_ERROR_IS_SET (error);
556 if (!dbus_message_set_sender (message,
557 bus_connection_get_name (connection)))
563 if (!bus_driver_send_welcome_message (connection, message, transaction, error))
566 /* Create the service */
567 service = bus_registry_ensure (registry,
568 &unique_name, connection, 0, transaction, error);
572 _dbus_assert (bus_connection_is_active (connection));
573 retval = BUS_RESULT_TRUE;
576 _dbus_string_free (&unique_name);
581 bus_driver_send_welcome_message (DBusConnection *connection,
582 DBusMessage *hello_message,
583 BusTransaction *transaction,
586 DBusMessage *welcome;
589 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
591 name = bus_connection_get_name (connection);
592 _dbus_assert (name != NULL);
594 welcome = dbus_message_new_method_return (hello_message);
601 if (!dbus_message_append_args (welcome,
602 DBUS_TYPE_STRING, &name,
605 dbus_message_unref (welcome);
610 _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
612 if (!bus_transaction_send_from_driver (transaction, connection, welcome))
614 dbus_message_unref (welcome);
620 dbus_message_unref (welcome);
626 bus_driver_handle_list_services (DBusConnection *connection,
627 BusTransaction *transaction,
628 DBusMessage *message,
634 BusRegistry *registry;
636 DBusMessageIter iter;
639 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
641 registry = bus_connection_get_registry (connection);
643 reply = dbus_message_new_method_return (message);
647 return BUS_RESULT_FALSE;
650 if (!bus_registry_list_services (registry, &services, &len))
652 dbus_message_unref (reply);
654 return BUS_RESULT_FALSE;
657 dbus_message_iter_init_append (reply, &iter);
659 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
660 DBUS_TYPE_STRING_AS_STRING,
663 dbus_free_string_array (services);
664 dbus_message_unref (reply);
666 return BUS_RESULT_FALSE;
670 /* Include the bus driver in the list */
671 const char *v_STRING = DBUS_SERVICE_DBUS;
672 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
675 dbus_free_string_array (services);
676 dbus_message_unref (reply);
678 return BUS_RESULT_FALSE;
685 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
688 dbus_free_string_array (services);
689 dbus_message_unref (reply);
691 return BUS_RESULT_FALSE;
696 dbus_free_string_array (services);
698 if (!dbus_message_iter_close_container (&iter, &sub))
700 dbus_message_unref (reply);
702 return BUS_RESULT_FALSE;
705 if (!bus_transaction_send_from_driver (transaction, connection, reply))
707 dbus_message_unref (reply);
709 return BUS_RESULT_FALSE;
713 dbus_message_unref (reply);
714 return BUS_RESULT_TRUE;
719 bus_driver_handle_list_activatable_services (DBusConnection *connection,
720 BusTransaction *transaction,
721 DBusMessage *message,
727 BusActivation *activation;
729 DBusMessageIter iter;
732 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
734 activation = bus_connection_get_activation (connection);
736 reply = dbus_message_new_method_return (message);
740 return BUS_RESULT_FALSE;
743 if (!bus_activation_list_services (activation, &services, &len))
745 dbus_message_unref (reply);
747 return BUS_RESULT_FALSE;
750 dbus_message_iter_init_append (reply, &iter);
752 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
753 DBUS_TYPE_STRING_AS_STRING,
756 dbus_free_string_array (services);
757 dbus_message_unref (reply);
759 return BUS_RESULT_FALSE;
763 /* Include the bus driver in the list */
764 const char *v_STRING = DBUS_SERVICE_DBUS;
765 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
768 dbus_free_string_array (services);
769 dbus_message_unref (reply);
771 return BUS_RESULT_FALSE;
778 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
781 dbus_free_string_array (services);
782 dbus_message_unref (reply);
784 return BUS_RESULT_FALSE;
789 dbus_free_string_array (services);
791 if (!dbus_message_iter_close_container (&iter, &sub))
793 dbus_message_unref (reply);
795 return BUS_RESULT_FALSE;
798 if (!bus_transaction_send_from_driver (transaction, connection, reply))
800 dbus_message_unref (reply);
802 return BUS_RESULT_FALSE;
806 dbus_message_unref (reply);
807 return BUS_RESULT_TRUE;
812 bus_driver_handle_acquire_service (DBusConnection *connection,
813 BusTransaction *transaction,
814 DBusMessage *message,
818 DBusString service_name;
820 dbus_uint32_t service_reply;
823 BusRegistry *registry;
825 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
827 registry = bus_connection_get_registry (connection);
829 if (!dbus_message_get_args (message, error,
830 DBUS_TYPE_STRING, &name,
831 DBUS_TYPE_UINT32, &flags,
833 return BUS_RESULT_FALSE;
835 _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
837 retval = BUS_RESULT_FALSE;
840 _dbus_string_init_const (&service_name, name);
842 switch (bus_registry_acquire_service (registry, connection, message,
843 &service_name, flags,
844 &service_reply, transaction,
847 case BUS_RESULT_TRUE:
849 case BUS_RESULT_FALSE:
851 case BUS_RESULT_LATER:
852 retval = BUS_RESULT_LATER;
856 reply = dbus_message_new_method_return (message);
863 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
869 if (!bus_transaction_send_from_driver (transaction, connection, reply))
875 retval = BUS_RESULT_TRUE;
879 dbus_message_unref (reply);
884 bus_driver_handle_release_service (DBusConnection *connection,
885 BusTransaction *transaction,
886 DBusMessage *message,
890 DBusString service_name;
892 dbus_uint32_t service_reply;
894 BusRegistry *registry;
896 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
898 registry = bus_connection_get_registry (connection);
900 if (!dbus_message_get_args (message, error,
901 DBUS_TYPE_STRING, &name,
903 return BUS_RESULT_FALSE;
905 _dbus_verbose ("Trying to release name %s\n", name);
907 retval = BUS_RESULT_FALSE;
910 _dbus_string_init_const (&service_name, name);
912 if (!bus_registry_release_service (registry, connection,
913 &service_name, &service_reply,
917 reply = dbus_message_new_method_return (message);
924 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
930 if (!bus_transaction_send_from_driver (transaction, connection, reply))
936 retval = BUS_RESULT_TRUE;
940 dbus_message_unref (reply);
945 bus_driver_handle_service_exists (DBusConnection *connection,
946 BusTransaction *transaction,
947 DBusMessage *message,
951 DBusString service_name;
953 dbus_bool_t service_exists;
956 BusRegistry *registry;
958 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
960 registry = bus_connection_get_registry (connection);
962 if (!dbus_message_get_args (message, error,
963 DBUS_TYPE_STRING, &name,
965 return BUS_RESULT_FALSE;
967 retval = BUS_RESULT_FALSE;
969 if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
971 service_exists = TRUE;
975 _dbus_string_init_const (&service_name, name);
976 service = bus_registry_lookup (registry, &service_name);
977 service_exists = service != NULL;
980 reply = dbus_message_new_method_return (message);
987 if (!dbus_message_append_args (reply,
988 DBUS_TYPE_BOOLEAN, &service_exists,
995 if (!bus_transaction_send_from_driver (transaction, connection, reply))
1001 retval = BUS_RESULT_TRUE;
1005 dbus_message_unref (reply);
1011 bus_driver_handle_activate_service (DBusConnection *connection,
1012 BusTransaction *transaction,
1013 DBusMessage *message,
1016 dbus_uint32_t flags;
1019 BusActivation *activation;
1021 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1023 activation = bus_connection_get_activation (connection);
1025 if (!dbus_message_get_args (message, error,
1026 DBUS_TYPE_STRING, &name,
1027 DBUS_TYPE_UINT32, &flags,
1030 _DBUS_ASSERT_ERROR_IS_SET (error);
1031 _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
1032 return BUS_RESULT_FALSE;
1035 retval = BUS_RESULT_FALSE;
1037 if (bus_activation_activate_service (activation, connection, transaction, FALSE,
1038 message, name, error, NULL) == BUS_RESULT_FALSE)
1040 _DBUS_ASSERT_ERROR_IS_SET (error);
1041 _dbus_verbose ("bus_activation_activate_service() failed\n");
1045 retval = BUS_RESULT_TRUE;
1052 bus_driver_send_ack_reply (DBusConnection *connection,
1053 BusTransaction *transaction,
1054 DBusMessage *message,
1059 if (dbus_message_get_no_reply (message))
1062 reply = dbus_message_new_method_return (message);
1065 BUS_SET_OOM (error);
1069 if (!bus_transaction_send_from_driver (transaction, connection, reply))
1071 BUS_SET_OOM (error);
1072 dbus_message_unref (reply);
1076 dbus_message_unref (reply);
1082 * Send a message from the driver, activating the destination if necessary.
1083 * The message must already have a destination set.
1086 bus_driver_send_or_activate (BusTransaction *transaction,
1087 DBusMessage *message,
1090 BusContext *context;
1091 BusService *service;
1092 const char *service_name;
1093 DBusString service_string;
1095 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1097 service_name = dbus_message_get_destination (message);
1099 _dbus_assert (service_name != NULL);
1101 _dbus_string_init_const (&service_string, service_name);
1103 context = bus_transaction_get_context (transaction);
1105 service = bus_registry_lookup (bus_context_get_registry (context),
1108 if (service == NULL)
1110 /* destination isn't connected yet; pass the message to activation */
1111 BusActivation *activation;
1113 activation = bus_context_get_activation (context);
1115 if (!bus_transaction_capture (transaction, NULL, NULL, message))
1117 BUS_SET_OOM (error);
1118 _dbus_verbose ("No memory for bus_transaction_capture()");
1122 if (bus_activation_activate_service (activation, NULL, transaction, TRUE,
1123 message, service_name, error, NULL) == BUS_RESULT_FALSE)
1125 _DBUS_ASSERT_ERROR_IS_SET (error);
1126 _dbus_verbose ("bus_activation_activate_service() failed");
1132 DBusConnection *service_conn;
1134 service_conn = bus_service_get_primary_owners_connection (service);
1136 if (!bus_transaction_send_from_driver (transaction, service_conn, message))
1138 BUS_SET_OOM (error);
1139 _dbus_verbose ("No memory for bus_transaction_send_from_driver()");
1148 bus_driver_handle_update_activation_environment (DBusConnection *connection,
1149 BusTransaction *transaction,
1150 DBusMessage *message,
1154 BusActivation *activation;
1155 BusContext *context;
1156 DBusMessageIter iter;
1157 DBusMessageIter dict_iter;
1158 DBusMessageIter dict_entry_iter;
1161 DBusList *keys, *key_link;
1162 DBusList *values, *value_link;
1163 DBusMessage *systemd_message;
1164 DBusMessageIter systemd_iter;
1166 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1168 context = bus_connection_get_context (connection);
1170 if (bus_context_get_servicehelper (context) != NULL)
1172 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1173 "Cannot change activation environment "
1174 "on a system bus.");
1175 return BUS_RESULT_FALSE;
1178 activation = bus_connection_get_activation (connection);
1180 dbus_message_iter_init (message, &iter);
1182 /* The message signature has already been checked for us,
1183 * so let's just assert it's right.
1185 _dbus_assert (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY);
1187 dbus_message_iter_recurse (&iter, &dict_iter);
1189 retval = BUS_RESULT_FALSE;
1190 systemd_message = NULL;
1192 /* Then loop through the sent dictionary, add the location of
1193 * the environment keys and values to lists. The result will
1194 * be in reverse order, so we don't have to constantly search
1195 * for the end of the list in a loop.
1199 while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY)
1201 dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
1203 while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING)
1209 dbus_message_iter_get_basic (&dict_entry_iter, &key);
1210 dbus_message_iter_next (&dict_entry_iter);
1212 value_type = dbus_message_iter_get_arg_type (&dict_entry_iter);
1214 if (value_type != DBUS_TYPE_STRING)
1217 dbus_message_iter_get_basic (&dict_entry_iter, &value);
1219 if (!_dbus_list_append (&keys, key))
1221 BUS_SET_OOM (error);
1225 if (!_dbus_list_append (&values, value))
1227 BUS_SET_OOM (error);
1231 dbus_message_iter_next (&dict_entry_iter);
1234 if (key_type != DBUS_TYPE_INVALID)
1237 dbus_message_iter_next (&dict_iter);
1240 if (array_type != DBUS_TYPE_INVALID)
1243 _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values));
1245 if (bus_context_get_systemd_activation (bus_connection_get_context (connection)))
1247 /* Prepare a call to forward environment updates to systemd */
1248 systemd_message = dbus_message_new_method_call ("org.freedesktop.systemd1",
1249 "/org/freedesktop/systemd1",
1250 "org.freedesktop.systemd1.Manager",
1252 if (systemd_message == NULL ||
1253 !dbus_message_set_sender (systemd_message, DBUS_SERVICE_DBUS))
1255 BUS_SET_OOM (error);
1256 _dbus_verbose ("No memory to create systemd message\n");
1260 dbus_message_set_no_reply (systemd_message, TRUE);
1261 dbus_message_iter_init_append (systemd_message, &iter);
1263 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
1266 BUS_SET_OOM (error);
1267 _dbus_verbose ("No memory to open systemd message container\n");
1273 value_link = values;
1274 while (key_link != NULL)
1279 key = key_link->data;
1280 value = value_link->data;
1282 if (!bus_activation_set_environment_variable (activation,
1285 _DBUS_ASSERT_ERROR_IS_SET (error);
1286 _dbus_verbose ("bus_activation_set_environment_variable() failed\n");
1290 if (systemd_message != NULL)
1295 /* SetEnvironment wants an array of KEY=VALUE strings */
1296 if (!_dbus_string_init (&envline) ||
1297 !_dbus_string_append_printf (&envline, "%s=%s", key, value))
1299 BUS_SET_OOM (error);
1300 _dbus_verbose ("No memory to format systemd environment line\n");
1301 _dbus_string_free (&envline);
1305 s = _dbus_string_get_data (&envline);
1307 if (!dbus_message_iter_append_basic (&systemd_iter,
1308 DBUS_TYPE_STRING, &s))
1310 BUS_SET_OOM (error);
1311 _dbus_verbose ("No memory to append systemd environment line\n");
1312 _dbus_string_free (&envline);
1316 _dbus_string_free (&envline);
1319 key_link = _dbus_list_get_next_link (&keys, key_link);
1320 value_link = _dbus_list_get_next_link (&values, value_link);
1323 /* FIXME: We can fail early having set only some of the environment variables,
1324 * (because of OOM failure). It's sort of hard to fix and it doesn't really
1325 * matter, so we're punting for now.
1327 if (key_link != NULL)
1329 if (systemd_message != NULL)
1330 dbus_message_iter_abandon_container (&iter, &systemd_iter);
1334 if (systemd_message != NULL)
1336 if (!dbus_message_iter_close_container (&iter, &systemd_iter))
1338 BUS_SET_OOM (error);
1339 _dbus_verbose ("No memory to close systemd message container\n");
1343 if (!bus_driver_send_or_activate (transaction, systemd_message, error))
1345 _DBUS_ASSERT_ERROR_IS_SET (error);
1346 _dbus_verbose ("bus_driver_send_or_activate() failed\n");
1351 if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1354 retval = BUS_RESULT_TRUE;
1357 if (systemd_message != NULL)
1358 dbus_message_unref (systemd_message);
1359 _dbus_list_clear (&keys);
1360 _dbus_list_clear (&values);
1365 bus_driver_handle_add_match (DBusConnection *connection,
1366 BusTransaction *transaction,
1367 DBusMessage *message,
1371 const char *text, *bustype;
1373 BusMatchmaker *matchmaker;
1375 BusContext *context;
1377 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1382 context = bus_transaction_get_context (transaction);
1383 limit = bus_context_get_max_match_rules_per_connection (context);
1385 if (bus_connection_get_n_match_rules (connection) >= limit)
1387 DBusError tmp_error;
1389 dbus_error_init (&tmp_error);
1390 dbus_set_error (&tmp_error, DBUS_ERROR_LIMITS_EXCEEDED,
1391 "Connection \"%s\" is not allowed to add more match rules "
1392 "(increase limits in configuration file if required; "
1393 "max_match_rules_per_connection=%d)",
1394 bus_connection_is_active (connection) ?
1395 bus_connection_get_name (connection) :
1398 bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s",
1400 dbus_move_error (&tmp_error, error);
1404 if (!dbus_message_get_args (message, error,
1405 DBUS_TYPE_STRING, &text,
1408 _dbus_verbose ("No memory to get arguments to AddMatch\n");
1412 _dbus_string_init_const (&str, text);
1414 rule = bus_match_rule_parse (connection, &str, error);
1418 bustype = bus_context_get_type (context);
1420 if (bus_match_rule_get_client_is_eavesdropping (rule))
1422 if (!bus_driver_check_caller_is_privileged (connection,
1426 !bus_apparmor_allows_eavesdropping (connection, bustype, error))
1430 matchmaker = bus_connection_get_matchmaker (connection);
1432 if (!bus_matchmaker_add_rule (matchmaker, rule))
1434 BUS_SET_OOM (error);
1438 if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1440 bus_matchmaker_remove_rule (matchmaker, rule);
1444 bus_match_rule_unref (rule);
1446 return BUS_RESULT_TRUE;
1449 _DBUS_ASSERT_ERROR_IS_SET (error);
1451 bus_match_rule_unref (rule);
1452 return BUS_RESULT_FALSE;
1456 bus_driver_handle_remove_match (DBusConnection *connection,
1457 BusTransaction *transaction,
1458 DBusMessage *message,
1464 BusMatchmaker *matchmaker;
1466 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1471 if (!dbus_message_get_args (message, error,
1472 DBUS_TYPE_STRING, &text,
1475 _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
1479 _dbus_string_init_const (&str, text);
1481 rule = bus_match_rule_parse (connection, &str, error);
1485 /* Send the ack before we remove the rule, since the ack is undone
1486 * on transaction cancel, but rule removal isn't.
1488 if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1491 matchmaker = bus_connection_get_matchmaker (connection);
1493 if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
1496 bus_match_rule_unref (rule);
1498 return BUS_RESULT_TRUE;
1501 _DBUS_ASSERT_ERROR_IS_SET (error);
1503 bus_match_rule_unref (rule);
1504 return BUS_RESULT_FALSE;
1508 bus_driver_handle_get_service_owner (DBusConnection *connection,
1509 BusTransaction *transaction,
1510 DBusMessage *message,
1514 const char *base_name;
1516 BusRegistry *registry;
1517 BusService *service;
1520 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1522 registry = bus_connection_get_registry (connection);
1527 if (! dbus_message_get_args (message, error,
1528 DBUS_TYPE_STRING, &text,
1532 _dbus_string_init_const (&str, text);
1533 service = bus_registry_lookup (registry, &str);
1534 if (service == NULL &&
1535 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1537 /* ORG_FREEDESKTOP_DBUS owns itself */
1538 base_name = DBUS_SERVICE_DBUS;
1540 else if (service == NULL)
1542 dbus_set_error (error,
1543 DBUS_ERROR_NAME_HAS_NO_OWNER,
1544 "Could not get owner of name '%s': no such name", text);
1549 base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1550 if (base_name == NULL)
1552 /* FIXME - how is this error possible? */
1553 dbus_set_error (error,
1555 "Could not determine unique name for '%s'", text);
1558 _dbus_assert (*base_name == ':');
1561 _dbus_assert (base_name != NULL);
1563 reply = dbus_message_new_method_return (message);
1567 if (! dbus_message_append_args (reply,
1568 DBUS_TYPE_STRING, &base_name,
1572 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1575 dbus_message_unref (reply);
1577 return BUS_RESULT_TRUE;
1580 BUS_SET_OOM (error);
1583 _DBUS_ASSERT_ERROR_IS_SET (error);
1585 dbus_message_unref (reply);
1586 return BUS_RESULT_FALSE;
1590 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1591 BusTransaction *transaction,
1592 DBusMessage *message,
1595 static const char dbus_service_name[] = DBUS_SERVICE_DBUS;
1598 DBusList *base_names;
1601 BusRegistry *registry;
1602 BusService *service;
1604 DBusMessageIter iter, array_iter;
1606 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1608 registry = bus_connection_get_registry (connection);
1614 if (! dbus_message_get_args (message, error,
1615 DBUS_TYPE_STRING, &text,
1619 _dbus_string_init_const (&str, text);
1620 service = bus_registry_lookup (registry, &str);
1621 if (service == NULL &&
1622 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1624 /* ORG_FREEDESKTOP_DBUS owns itself */
1625 if (! _dbus_list_append (&base_names, (char *) dbus_service_name))
1628 else if (service == NULL)
1630 dbus_set_error (error,
1631 DBUS_ERROR_NAME_HAS_NO_OWNER,
1632 "Could not get owners of name '%s': no such name", text);
1637 if (!bus_service_list_queued_owners (service,
1643 _dbus_assert (base_names != NULL);
1645 reply = dbus_message_new_method_return (message);
1649 dbus_message_iter_init_append (reply, &iter);
1650 if (!dbus_message_iter_open_container (&iter,
1652 DBUS_TYPE_STRING_AS_STRING,
1656 link = _dbus_list_get_first_link (&base_names);
1657 while (link != NULL)
1661 _dbus_assert (link->data != NULL);
1662 uname = (char *)link->data;
1664 if (!dbus_message_iter_append_basic (&array_iter,
1669 link = _dbus_list_get_next_link (&base_names, link);
1672 if (! dbus_message_iter_close_container (&iter, &array_iter))
1676 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1679 dbus_message_unref (reply);
1681 return BUS_RESULT_TRUE;
1684 BUS_SET_OOM (error);
1687 _DBUS_ASSERT_ERROR_IS_SET (error);
1689 dbus_message_unref (reply);
1692 _dbus_list_clear (&base_names);
1694 return BUS_RESULT_FALSE;
1698 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1699 BusTransaction *transaction,
1700 DBusMessage *message,
1703 DBusConnection *conn;
1706 dbus_uint32_t uid32;
1707 const char *service;
1708 BusDriverFound found;
1710 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1714 found = bus_driver_get_conn_helper (connection, message, "UID", &service,
1718 case BUS_DRIVER_FOUND_SELF:
1719 uid = _dbus_getuid ();
1721 case BUS_DRIVER_FOUND_PEER:
1722 if (!dbus_connection_get_unix_user (conn, &uid))
1723 uid = DBUS_UID_UNSET;
1725 case BUS_DRIVER_FOUND_ERROR:
1731 if (uid == DBUS_UID_UNSET)
1733 dbus_set_error (error,
1735 "Could not determine UID for '%s'", service);
1739 reply = dbus_message_new_method_return (message);
1744 if (! dbus_message_append_args (reply,
1745 DBUS_TYPE_UINT32, &uid32,
1749 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1752 dbus_message_unref (reply);
1754 return BUS_RESULT_TRUE;
1757 BUS_SET_OOM (error);
1760 _DBUS_ASSERT_ERROR_IS_SET (error);
1762 dbus_message_unref (reply);
1763 return BUS_RESULT_FALSE;
1767 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1768 BusTransaction *transaction,
1769 DBusMessage *message,
1772 DBusConnection *conn;
1775 dbus_uint32_t pid32;
1776 const char *service;
1777 BusDriverFound found;
1779 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1783 found = bus_driver_get_conn_helper (connection, message, "PID", &service,
1787 case BUS_DRIVER_FOUND_SELF:
1788 pid = _dbus_getpid ();
1790 case BUS_DRIVER_FOUND_PEER:
1791 if (!dbus_connection_get_unix_process_id (conn, &pid))
1792 pid = DBUS_PID_UNSET;
1794 case BUS_DRIVER_FOUND_ERROR:
1800 if (pid == DBUS_PID_UNSET)
1802 dbus_set_error (error,
1803 DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1804 "Could not determine PID for '%s'", service);
1808 reply = dbus_message_new_method_return (message);
1813 if (! dbus_message_append_args (reply,
1814 DBUS_TYPE_UINT32, &pid32,
1818 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1821 dbus_message_unref (reply);
1823 return BUS_RESULT_TRUE;
1826 BUS_SET_OOM (error);
1829 _DBUS_ASSERT_ERROR_IS_SET (error);
1831 dbus_message_unref (reply);
1832 return BUS_RESULT_FALSE;
1836 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1837 BusTransaction *transaction,
1838 DBusMessage *message,
1841 DBusConnection *conn;
1844 dbus_int32_t data_size;
1845 const char *service;
1846 BusDriverFound found;
1848 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1852 found = bus_driver_get_conn_helper (connection, message, "audit session data",
1853 &service, &conn, error);
1855 if (found == BUS_DRIVER_FOUND_ERROR)
1858 reply = dbus_message_new_method_return (message);
1862 /* We don't know how to find "ADT audit session data" for the bus daemon
1863 * itself. Is that even meaningful?
1864 * FIXME: Implement this or briefly note it makes no sense.
1866 if (found != BUS_DRIVER_FOUND_PEER ||
1867 !dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) ||
1870 dbus_set_error (error,
1871 DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1872 "Could not determine audit session data for '%s'", service);
1876 if (! dbus_message_append_args (reply,
1877 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1881 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1884 dbus_message_unref (reply);
1886 return BUS_RESULT_TRUE;
1889 BUS_SET_OOM (error);
1892 _DBUS_ASSERT_ERROR_IS_SET (error);
1894 dbus_message_unref (reply);
1895 return BUS_RESULT_FALSE;
1899 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1900 BusTransaction *transaction,
1901 DBusMessage *message,
1904 DBusConnection *conn;
1906 BusSELinuxID *context;
1907 const char *service;
1908 BusDriverFound found;
1910 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1914 found = bus_driver_get_conn_helper (connection, message, "security context",
1915 &service, &conn, error);
1917 if (found == BUS_DRIVER_FOUND_ERROR)
1920 reply = dbus_message_new_method_return (message);
1924 if (found == BUS_DRIVER_FOUND_SELF)
1925 context = bus_selinux_get_self ();
1926 else if (found == BUS_DRIVER_FOUND_PEER)
1927 context = bus_connection_get_selinux_id (conn);
1933 dbus_set_error (error,
1934 DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1935 "Could not determine security context for '%s'", service);
1939 if (! bus_selinux_append_context (reply, context, error))
1942 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1945 dbus_message_unref (reply);
1947 return BUS_RESULT_TRUE;
1950 BUS_SET_OOM (error);
1953 _DBUS_ASSERT_ERROR_IS_SET (error);
1955 dbus_message_unref (reply);
1956 return BUS_RESULT_FALSE;
1960 bus_driver_handle_get_connection_credentials (DBusConnection *connection,
1961 BusTransaction *transaction,
1962 DBusMessage *message,
1965 DBusConnection *conn;
1967 DBusMessageIter reply_iter;
1968 DBusMessageIter array_iter;
1969 unsigned long ulong_uid, ulong_pid;
1971 const char *service;
1972 BusDriverFound found;
1974 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1978 found = bus_driver_get_conn_helper (connection, message, "credentials",
1979 &service, &conn, error);
1983 case BUS_DRIVER_FOUND_SELF:
1984 ulong_pid = _dbus_getpid ();
1985 ulong_uid = _dbus_getuid ();
1988 case BUS_DRIVER_FOUND_PEER:
1989 if (!dbus_connection_get_unix_process_id (conn, &ulong_pid))
1990 ulong_pid = DBUS_PID_UNSET;
1991 if (!dbus_connection_get_unix_user (conn, &ulong_uid))
1992 ulong_uid = DBUS_UID_UNSET;
1994 case BUS_DRIVER_FOUND_ERROR:
2000 reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
2004 /* we can't represent > 32-bit pids; if your system needs them, please
2005 * add ProcessID64 to the spec or something */
2006 if (ulong_pid <= _DBUS_UINT32_MAX && ulong_pid != DBUS_PID_UNSET &&
2007 !_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_pid))
2010 /* we can't represent > 32-bit uids; if your system needs them, please
2011 * add UnixUserID64 to the spec or something */
2012 if (ulong_uid <= _DBUS_UINT32_MAX && ulong_uid != DBUS_UID_UNSET &&
2013 !_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_uid))
2016 /* FIXME: Obtain the Windows user of the bus daemon itself */
2017 if (found == BUS_DRIVER_FOUND_PEER &&
2018 dbus_connection_get_windows_user (conn, &s))
2026 _dbus_string_init_const (&str, s);
2027 result = _dbus_validate_utf8 (&str, 0, _dbus_string_get_length (&str));
2028 _dbus_string_free (&str);
2031 if (!_dbus_asv_add_string (&array_iter, "WindowsSID", s))
2040 /* FIXME: Obtain the security label for the bus daemon itself */
2041 if (found == BUS_DRIVER_FOUND_PEER &&
2042 _dbus_connection_get_linux_security_label (conn, &s))
2047 /* use the GVariant bytestring convention for strings of unknown
2048 * encoding: include the \0 in the payload, for zero-copy reading */
2049 if (!_dbus_asv_add_byte_array (&array_iter, "LinuxSecurityLabel",
2059 if (!_dbus_asv_close (&reply_iter, &array_iter))
2062 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2064 /* this time we don't want to close the iterator again, so just
2065 * get rid of the message */
2066 dbus_message_unref (reply);
2071 dbus_message_unref (reply);
2073 return BUS_RESULT_TRUE;
2076 BUS_SET_OOM (error);
2079 _DBUS_ASSERT_ERROR_IS_SET (error);
2083 _dbus_asv_abandon (&reply_iter, &array_iter);
2084 dbus_message_unref (reply);
2087 return BUS_RESULT_FALSE;
2091 bus_driver_handle_reload_config (DBusConnection *connection,
2092 BusTransaction *transaction,
2093 DBusMessage *message,
2096 BusContext *context;
2099 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2103 context = bus_connection_get_context (connection);
2104 if (!bus_context_reload_config (context, error))
2107 reply = dbus_message_new_method_return (message);
2111 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2114 dbus_message_unref (reply);
2115 return BUS_RESULT_TRUE;
2118 BUS_SET_OOM (error);
2121 _DBUS_ASSERT_ERROR_IS_SET (error);
2123 dbus_message_unref (reply);
2124 return BUS_RESULT_FALSE;
2127 #ifdef DBUS_ENABLE_VERBOSE_MODE
2129 bus_driver_handle_enable_verbose (DBusConnection *connection,
2130 BusTransaction *transaction,
2131 DBusMessage *message,
2134 DBusMessage *reply = NULL;
2136 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2138 reply = dbus_message_new_method_return (message);
2142 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2145 _dbus_set_verbose(TRUE);
2147 dbus_message_unref (reply);
2151 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2153 BUS_SET_OOM (error);
2156 dbus_message_unref (reply);
2161 bus_driver_handle_disable_verbose (DBusConnection *connection,
2162 BusTransaction *transaction,
2163 DBusMessage *message,
2166 DBusMessage *reply = NULL;
2168 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2170 reply = dbus_message_new_method_return (message);
2174 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2177 _dbus_set_verbose(FALSE);
2179 dbus_message_unref (reply);
2183 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2185 BUS_SET_OOM (error);
2188 dbus_message_unref (reply);
2194 bus_driver_handle_get_id (DBusConnection *connection,
2195 BusTransaction *transaction,
2196 DBusMessage *message,
2199 BusContext *context;
2202 const char *v_STRING;
2204 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2206 if (!_dbus_string_init (&uuid))
2208 BUS_SET_OOM (error);
2209 return BUS_RESULT_FALSE;
2214 context = bus_connection_get_context (connection);
2215 if (!bus_context_get_id (context, &uuid))
2218 reply = dbus_message_new_method_return (message);
2222 v_STRING = _dbus_string_get_const_data (&uuid);
2223 if (!dbus_message_append_args (reply,
2224 DBUS_TYPE_STRING, &v_STRING,
2228 _dbus_assert (dbus_message_has_signature (reply, "s"));
2230 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2233 _dbus_string_free (&uuid);
2234 dbus_message_unref (reply);
2235 return BUS_RESULT_TRUE;
2238 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2240 BUS_SET_OOM (error);
2243 dbus_message_unref (reply);
2244 _dbus_string_free (&uuid);
2245 return BUS_RESULT_FALSE;
2249 bus_driver_handle_become_monitor (DBusConnection *connection,
2250 BusTransaction *transaction,
2251 DBusMessage *message,
2254 char **match_rules = NULL;
2255 const char *bustype;
2256 BusContext *context;
2258 DBusList *rules = NULL;
2263 dbus_uint32_t flags;
2264 dbus_bool_t ret = FALSE;
2266 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2268 context = bus_transaction_get_context (transaction);
2269 bustype = context ? bus_context_get_type (context) : NULL;
2270 if (!bus_apparmor_allows_eavesdropping (connection, bustype, error))
2273 if (!dbus_message_get_args (message, error,
2274 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &match_rules, &n_match_rules,
2275 DBUS_TYPE_UINT32, &flags,
2281 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2282 "BecomeMonitor does not support any flags yet");
2286 /* Special case: a zero-length array becomes [""] */
2287 if (n_match_rules == 0)
2289 match_rules = dbus_malloc (2 * sizeof (char *));
2291 if (match_rules == NULL)
2293 BUS_SET_OOM (error);
2297 match_rules[0] = _dbus_strdup ("");
2299 if (match_rules[0] == NULL)
2301 BUS_SET_OOM (error);
2305 match_rules[1] = NULL;
2309 for (i = 0; i < n_match_rules; i++)
2311 _dbus_string_init_const (&str, match_rules[i]);
2312 rule = bus_match_rule_parse (connection, &str, error);
2317 /* monitors always eavesdrop */
2318 bus_match_rule_set_client_is_eavesdropping (rule, TRUE);
2320 if (!_dbus_list_append (&rules, rule))
2322 BUS_SET_OOM (error);
2323 bus_match_rule_unref (rule);
2328 /* Send the ack before we remove the rule, since the ack is undone
2329 * on transaction cancel, but becoming a monitor isn't.
2331 if (!bus_driver_send_ack_reply (connection, transaction, message, error))
2334 if (!bus_connection_be_monitor (connection, transaction, &rules, error))
2341 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2343 _DBUS_ASSERT_ERROR_IS_SET (error);
2345 for (iter = _dbus_list_get_first_link (&rules);
2347 iter = _dbus_list_get_next_link (&rules, iter))
2348 bus_match_rule_unref (iter->data);
2350 _dbus_list_clear (&rules);
2352 dbus_free_string_array (match_rules);
2357 bus_driver_handle_get_machine_id (DBusConnection *connection,
2358 BusTransaction *transaction,
2359 DBusMessage *message,
2362 DBusMessage *reply = NULL;
2366 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2368 if (!_dbus_string_init (&uuid))
2370 BUS_SET_OOM (error);
2374 if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
2377 reply = dbus_message_new_method_return (message);
2382 str = _dbus_string_get_const_data (&uuid);
2384 if (!dbus_message_append_args (reply,
2385 DBUS_TYPE_STRING, &str,
2389 _dbus_assert (dbus_message_has_signature (reply, "s"));
2391 if (!bus_transaction_send_from_driver (transaction, connection, reply))
2394 _dbus_string_free (&uuid);
2395 dbus_message_unref (reply);
2399 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2401 BUS_SET_OOM (error);
2404 _DBUS_ASSERT_ERROR_IS_SET (error);
2407 dbus_message_unref (reply);
2409 _dbus_string_free (&uuid);
2414 bus_driver_handle_ping (DBusConnection *connection,
2415 BusTransaction *transaction,
2416 DBusMessage *message,
2419 return bus_driver_send_ack_reply (connection, transaction, message, error);
2422 static dbus_bool_t bus_driver_handle_get (DBusConnection *connection,
2423 BusTransaction *transaction,
2424 DBusMessage *message,
2427 static dbus_bool_t bus_driver_handle_get_all (DBusConnection *connection,
2428 BusTransaction *transaction,
2429 DBusMessage *message,
2432 static dbus_bool_t bus_driver_handle_set (DBusConnection *connection,
2433 BusTransaction *transaction,
2434 DBusMessage *message,
2437 static dbus_bool_t features_getter (BusContext *context,
2438 DBusMessageIter *variant_iter);
2439 static dbus_bool_t interfaces_getter (BusContext *context,
2440 DBusMessageIter *variant_iter);
2444 /* Various older methods were available at every object path. We have to
2445 * preserve that behaviour for backwards compatibility, but we can at least
2446 * stop doing that for newly added methods.
2447 * The special Peer interface should also work at any object path.
2448 * <https://bugs.freedesktop.org/show_bug.cgi?id=101256> */
2449 METHOD_FLAG_ANY_PATH = (1 << 0),
2451 /* If set, callers must be privileged. On Unix, the uid of the connection
2452 * must either be the uid of this process, or 0 (root). On Windows,
2453 * the SID of the connection must be the SID of this process. */
2454 METHOD_FLAG_PRIVILEGED = (1 << 1),
2456 METHOD_FLAG_NONE = 0
2462 const char *in_args;
2463 const char *out_args;
2464 BusResult (* handler) (DBusConnection *connection,
2465 BusTransaction *transaction,
2466 DBusMessage *message,
2475 dbus_bool_t (* getter) (BusContext *context,
2476 DBusMessageIter *variant_iter);
2479 /* For speed it might be useful to sort this in order of
2480 * frequency of use (but doesn't matter with only a few items
2483 static const MessageHandler dbus_message_handlers[] = {
2486 DBUS_TYPE_STRING_AS_STRING,
2487 bus_driver_handle_hello,
2488 METHOD_FLAG_ANY_PATH },
2490 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2491 DBUS_TYPE_UINT32_AS_STRING,
2492 bus_driver_handle_acquire_service,
2493 METHOD_FLAG_ANY_PATH },
2495 DBUS_TYPE_STRING_AS_STRING,
2496 DBUS_TYPE_UINT32_AS_STRING,
2497 bus_driver_handle_release_service,
2498 METHOD_FLAG_ANY_PATH },
2499 { "StartServiceByName",
2500 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2501 DBUS_TYPE_UINT32_AS_STRING,
2502 bus_driver_handle_activate_service,
2503 METHOD_FLAG_ANY_PATH },
2504 { "UpdateActivationEnvironment",
2505 DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
2507 bus_driver_handle_update_activation_environment,
2508 METHOD_FLAG_PRIVILEGED },
2510 DBUS_TYPE_STRING_AS_STRING,
2511 DBUS_TYPE_BOOLEAN_AS_STRING,
2512 bus_driver_handle_service_exists,
2513 METHOD_FLAG_ANY_PATH },
2516 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2517 bus_driver_handle_list_services,
2518 METHOD_FLAG_ANY_PATH },
2519 { "ListActivatableNames",
2521 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2522 bus_driver_handle_list_activatable_services,
2523 METHOD_FLAG_ANY_PATH },
2525 DBUS_TYPE_STRING_AS_STRING,
2527 bus_driver_handle_add_match,
2528 METHOD_FLAG_ANY_PATH },
2530 DBUS_TYPE_STRING_AS_STRING,
2532 bus_driver_handle_remove_match,
2533 METHOD_FLAG_ANY_PATH },
2535 DBUS_TYPE_STRING_AS_STRING,
2536 DBUS_TYPE_STRING_AS_STRING,
2537 bus_driver_handle_get_service_owner,
2538 METHOD_FLAG_ANY_PATH },
2539 { "ListQueuedOwners",
2540 DBUS_TYPE_STRING_AS_STRING,
2541 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2542 bus_driver_handle_list_queued_owners,
2543 METHOD_FLAG_ANY_PATH },
2544 { "GetConnectionUnixUser",
2545 DBUS_TYPE_STRING_AS_STRING,
2546 DBUS_TYPE_UINT32_AS_STRING,
2547 bus_driver_handle_get_connection_unix_user,
2548 METHOD_FLAG_ANY_PATH },
2549 { "GetConnectionUnixProcessID",
2550 DBUS_TYPE_STRING_AS_STRING,
2551 DBUS_TYPE_UINT32_AS_STRING,
2552 bus_driver_handle_get_connection_unix_process_id,
2553 METHOD_FLAG_ANY_PATH },
2554 { "GetAdtAuditSessionData",
2555 DBUS_TYPE_STRING_AS_STRING,
2556 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2557 bus_driver_handle_get_adt_audit_session_data,
2558 METHOD_FLAG_ANY_PATH },
2559 { "GetConnectionSELinuxSecurityContext",
2560 DBUS_TYPE_STRING_AS_STRING,
2561 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2562 bus_driver_handle_get_connection_selinux_security_context,
2563 METHOD_FLAG_ANY_PATH },
2567 bus_driver_handle_reload_config,
2568 METHOD_FLAG_ANY_PATH },
2571 DBUS_TYPE_STRING_AS_STRING,
2572 bus_driver_handle_get_id,
2573 METHOD_FLAG_ANY_PATH },
2574 { "GetConnectionCredentials", "s", "a{sv}",
2575 bus_driver_handle_get_connection_credentials,
2576 METHOD_FLAG_ANY_PATH },
2577 { NULL, NULL, NULL, NULL }
2580 static const PropertyHandler dbus_property_handlers[] = {
2581 { "Features", "as", features_getter },
2582 { "Interfaces", "as", interfaces_getter },
2583 { NULL, NULL, NULL }
2586 static BusResult bus_driver_handle_introspect (DBusConnection *,
2587 BusTransaction *, DBusMessage *, DBusError *);
2589 static const MessageHandler properties_message_handlers[] = {
2590 { "Get", "ss", "v", bus_driver_handle_get, METHOD_FLAG_NONE },
2591 { "GetAll", "s", "a{sv}", bus_driver_handle_get_all, METHOD_FLAG_NONE },
2592 { "Set", "ssv", "", bus_driver_handle_set, METHOD_FLAG_NONE },
2593 { NULL, NULL, NULL, NULL }
2596 static const MessageHandler introspectable_message_handlers[] = {
2597 { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect,
2598 METHOD_FLAG_ANY_PATH },
2599 { NULL, NULL, NULL, NULL }
2602 static const MessageHandler monitoring_message_handlers[] = {
2603 { "BecomeMonitor", "asu", "", bus_driver_handle_become_monitor,
2604 METHOD_FLAG_PRIVILEGED },
2605 { NULL, NULL, NULL, NULL }
2608 #ifdef DBUS_ENABLE_VERBOSE_MODE
2609 static const MessageHandler verbose_message_handlers[] = {
2610 { "EnableVerbose", "", "", bus_driver_handle_enable_verbose,
2612 { "DisableVerbose", "", "", bus_driver_handle_disable_verbose,
2614 { NULL, NULL, NULL, NULL }
2618 #ifdef DBUS_ENABLE_STATS
2619 static const MessageHandler stats_message_handlers[] = {
2620 { "GetStats", "", "a{sv}", bus_stats_handle_get_stats,
2622 { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats,
2624 { "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules,
2626 { NULL, NULL, NULL, NULL }
2630 static const MessageHandler peer_message_handlers[] = {
2631 { "GetMachineId", "", "s", bus_driver_handle_get_machine_id,
2632 METHOD_FLAG_ANY_PATH },
2633 { "Ping", "", "", bus_driver_handle_ping, METHOD_FLAG_ANY_PATH },
2634 { NULL, NULL, NULL, NULL }
2639 /* Various older interfaces were available at every object path. We have to
2640 * preserve that behaviour for backwards compatibility, but we can at least
2641 * stop doing that for newly added interfaces:
2642 * <https://bugs.freedesktop.org/show_bug.cgi?id=101256>
2643 * Introspectable and Peer are also useful at all object paths. */
2644 INTERFACE_FLAG_ANY_PATH = (1 << 0),
2646 /* Set this flag for interfaces that should not show up in the
2647 * Interfaces property. */
2648 INTERFACE_FLAG_UNINTERESTING = (1 << 1),
2650 INTERFACE_FLAG_NONE = 0
2655 const MessageHandler *message_handlers;
2656 const char *extra_introspection;
2657 InterfaceFlags flags;
2658 const PropertyHandler *property_handlers;
2661 /* These should ideally be sorted by frequency of use, although it
2662 * probably doesn't matter with this few items */
2663 static InterfaceHandler interface_handlers[] = {
2664 { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2665 " <signal name=\"NameOwnerChanged\">\n"
2666 " <arg type=\"s\"/>\n"
2667 " <arg type=\"s\"/>\n"
2668 " <arg type=\"s\"/>\n"
2670 " <signal name=\"NameLost\">\n"
2671 " <arg type=\"s\"/>\n"
2673 " <signal name=\"NameAcquired\">\n"
2674 " <arg type=\"s\"/>\n"
2676 /* Not in the Interfaces property because if you can get the properties
2677 * of the o.fd.DBus interface, then you certainly have the o.fd.DBus
2678 * interface, so there is little point in listing it explicitly.
2679 * Partially available at all paths for backwards compatibility. */
2680 INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING,
2681 dbus_property_handlers },
2682 { DBUS_INTERFACE_PROPERTIES, properties_message_handlers,
2683 " <signal name=\"PropertiesChanged\">\n"
2684 " <arg type=\"s\" name=\"interface_name\"/>\n"
2685 " <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
2686 " <arg type=\"as\" name=\"invalidated_properties\"/>\n"
2688 /* Not in the Interfaces property because if you can get the properties
2689 * of the o.fd.DBus interface, then you certainly have Properties. */
2690 INTERFACE_FLAG_UNINTERESTING },
2691 { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL,
2692 /* Not in the Interfaces property because introspection isn't really a
2693 * feature in the same way as e.g. Monitoring.
2694 * Available at all paths so tools like d-feet can start from "/". */
2695 INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
2696 { DBUS_INTERFACE_MONITORING, monitoring_message_handlers, NULL,
2697 INTERFACE_FLAG_NONE },
2698 #ifdef DBUS_ENABLE_VERBOSE_MODE
2699 { DBUS_INTERFACE_VERBOSE, verbose_message_handlers, NULL,
2700 INTERFACE_FLAG_NONE },
2702 #ifdef DBUS_ENABLE_STATS
2703 { BUS_INTERFACE_STATS, stats_message_handlers, NULL,
2704 INTERFACE_FLAG_NONE },
2706 { DBUS_INTERFACE_PEER, peer_message_handlers, NULL,
2707 /* Not in the Interfaces property because it's a pseudo-interface
2708 * on all object paths of all connections, rather than a feature of the
2709 * bus driver object. */
2710 INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
2711 { NULL, NULL, NULL }
2715 write_args_for_direction (DBusString *xml,
2716 const char *signature,
2719 DBusTypeReader typereader;
2723 _dbus_string_init_const (&sigstr, signature);
2724 _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2726 while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2728 const DBusString *subsig;
2731 _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2732 if (!_dbus_string_append_printf (xml, " <arg direction=\"%s\" type=\"",
2735 if (!_dbus_string_append_len (xml,
2736 _dbus_string_get_const_data (subsig) + start,
2739 if (!_dbus_string_append (xml, "\"/>\n"))
2742 _dbus_type_reader_next (&typereader);
2750 bus_driver_generate_introspect_string (DBusString *xml,
2751 dbus_bool_t is_canonical_path,
2752 DBusMessage *message)
2754 const InterfaceHandler *ih;
2755 const MessageHandler *mh;
2756 const PropertyHandler *ph;
2758 if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2760 if (!_dbus_string_append (xml, "<node>\n"))
2763 for (ih = interface_handlers; ih->name != NULL; ih++)
2765 if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
2768 if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n",
2772 for (mh = ih->message_handlers; mh->name != NULL; mh++)
2774 if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n",
2778 if (!write_args_for_direction (xml, mh->in_args, TRUE))
2781 if (!write_args_for_direction (xml, mh->out_args, FALSE))
2784 if (!_dbus_string_append (xml, " </method>\n"))
2788 for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
2790 /* We only have constant properties so far, so hard-code that bit */
2791 if (!_dbus_string_append_printf (xml,
2792 " <property name=\"%s\" type=\"%s\" access=\"read\">\n",
2793 ph->name, ph->type))
2796 if (!_dbus_string_append (xml,
2797 " <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
2802 if (ih->extra_introspection != NULL &&
2803 !_dbus_string_append (xml, ih->extra_introspection))
2806 if (!_dbus_string_append (xml, " </interface>\n"))
2810 if (message != NULL)
2812 /* Make the bus driver object path discoverable */
2813 if (dbus_message_has_path (message, "/"))
2815 if (!_dbus_string_append (xml,
2816 " <node name=\"org/freedesktop/DBus\"/>\n"))
2819 else if (dbus_message_has_path (message, "/org"))
2821 if (!_dbus_string_append (xml,
2822 " <node name=\"freedesktop/DBus\"/>\n"))
2825 else if (dbus_message_has_path (message, "/org/freedesktop"))
2827 if (!_dbus_string_append (xml, " <node name=\"DBus\"/>\n"))
2832 if (!_dbus_string_append (xml, "</node>\n"))
2839 bus_driver_handle_introspect (DBusConnection *connection,
2840 BusTransaction *transaction,
2841 DBusMessage *message,
2846 const char *v_STRING;
2847 dbus_bool_t is_canonical_path;
2849 _dbus_verbose ("Introspect() on bus driver\n");
2851 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2855 if (! dbus_message_get_args (message, error,
2858 _DBUS_ASSERT_ERROR_IS_SET (error);
2859 return BUS_RESULT_FALSE;
2862 if (!_dbus_string_init (&xml))
2864 BUS_SET_OOM (error);
2865 return BUS_RESULT_FALSE;
2868 is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
2870 if (!bus_driver_generate_introspect_string (&xml, is_canonical_path, message))
2873 v_STRING = _dbus_string_get_const_data (&xml);
2875 reply = dbus_message_new_method_return (message);
2879 if (! dbus_message_append_args (reply,
2880 DBUS_TYPE_STRING, &v_STRING,
2884 if (! bus_transaction_send_from_driver (transaction, connection, reply))
2887 dbus_message_unref (reply);
2888 _dbus_string_free (&xml);
2890 return BUS_RESULT_TRUE;
2893 BUS_SET_OOM (error);
2896 dbus_message_unref (reply);
2898 _dbus_string_free (&xml);
2900 return BUS_RESULT_FALSE;
2904 bus_driver_handle_message (DBusConnection *connection,
2905 BusTransaction *transaction,
2906 DBusMessage *message,
2909 const char *name, *interface;
2910 const InterfaceHandler *ih;
2911 const MessageHandler *mh;
2912 dbus_bool_t found_interface = FALSE;
2913 dbus_bool_t is_canonical_path;
2915 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2917 if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2919 BusContext *context;
2920 DBusConnection *systemd;
2922 /* This is a directed signal, not a method call, so the log message
2923 * is a little weird (it talks about "calling" ActivationFailure),
2924 * but it's close enough */
2925 if (!bus_driver_check_caller_is_privileged (connection,
2929 return BUS_RESULT_FALSE;
2931 context = bus_connection_get_context (connection);
2932 systemd = bus_driver_get_owner_of_name (connection,
2933 "org.freedesktop.systemd1");
2935 if (systemd != connection)
2937 const char *attacker;
2939 attacker = bus_connection_get_name (connection);
2940 bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY,
2941 "Ignoring forged ActivationFailure message from "
2942 "connection %s (%s)",
2943 attacker ? attacker : "(unauthenticated)",
2944 bus_connection_get_loginfo (connection));
2946 return BUS_RESULT_TRUE;
2949 if (!bus_context_get_systemd_activation (context))
2951 bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
2952 "Ignoring unexpected ActivationFailure message "
2953 "while not using systemd activation");
2954 return BUS_RESULT_FALSE;
2957 return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
2960 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2962 _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2963 return BUS_RESULT_TRUE; /* we just ignore this */
2966 /* may be NULL, which means "any interface will do" */
2967 interface = dbus_message_get_interface (message);
2969 _dbus_assert (dbus_message_get_member (message) != NULL);
2971 name = dbus_message_get_member (message);
2973 _dbus_verbose ("Driver got a method call: %s\n", name);
2975 /* security checks should have kept this from getting here */
2976 _dbus_assert (dbus_message_get_sender (message) != NULL ||
2977 strcmp (name, "Hello") == 0);
2979 is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
2981 for (ih = interface_handlers; ih->name != NULL; ih++)
2983 if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
2986 if (interface != NULL && strcmp (interface, ih->name) != 0)
2989 found_interface = TRUE;
2991 for (mh = ih->message_handlers; mh->name != NULL; mh++)
2993 if (strcmp (mh->name, name) != 0)
2996 _dbus_verbose ("Found driver handler for %s\n", name);
2998 if ((mh->flags & METHOD_FLAG_PRIVILEGED) &&
2999 !bus_driver_check_caller_is_privileged (connection, transaction,
3002 _DBUS_ASSERT_ERROR_IS_SET (error);
3003 return BUS_RESULT_FALSE;
3006 if (!(is_canonical_path || (mh->flags & METHOD_FLAG_ANY_PATH)))
3008 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3009 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
3010 "Method '%s' is only available at the canonical object path '%s'",
3011 dbus_message_get_member (message), DBUS_PATH_DBUS);
3012 _DBUS_ASSERT_ERROR_IS_SET (error);
3013 return BUS_RESULT_FALSE;
3016 if (!dbus_message_has_signature (message, mh->in_args))
3018 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3019 _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
3020 name, dbus_message_get_signature (message),
3023 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
3024 "Call to %s has wrong args (%s, expected %s)\n",
3025 name, dbus_message_get_signature (message),
3027 _DBUS_ASSERT_ERROR_IS_SET (error);
3028 return BUS_RESULT_FALSE;
3031 switch ((* mh->handler) (connection, transaction, message, error))
3033 case BUS_RESULT_TRUE:
3034 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3035 _dbus_verbose ("Driver handler succeeded\n");
3036 return BUS_RESULT_TRUE;
3037 case BUS_RESULT_FALSE:
3038 _DBUS_ASSERT_ERROR_IS_SET (error);
3039 _dbus_verbose ("Driver handler returned failure\n");
3040 return BUS_RESULT_FALSE;
3041 case BUS_RESULT_LATER:
3042 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3043 _dbus_verbose ("Driver handler delayed message processing due to policy check\n");
3044 return BUS_RESULT_LATER;
3049 _dbus_verbose ("No driver handler for message \"%s\"\n",
3052 dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
3053 "%s does not understand message %s",
3054 DBUS_SERVICE_DBUS, name);
3056 return BUS_RESULT_FALSE;
3060 bus_driver_remove_connection (DBusConnection *connection)
3062 /* FIXME 1.0 Does nothing for now, should unregister the connection
3063 * with the bus driver.
3068 features_getter (BusContext *context,
3069 DBusMessageIter *variant_iter)
3071 DBusMessageIter arr_iter;
3073 if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
3074 DBUS_TYPE_STRING_AS_STRING,
3078 if (bus_apparmor_enabled ())
3080 const char *s = "AppArmor";
3082 if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3086 if (bus_selinux_enabled ())
3088 const char *s = "SELinux";
3090 if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3094 if (bus_context_get_systemd_activation (context))
3096 const char *s = "SystemdActivation";
3098 if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3102 return dbus_message_iter_close_container (variant_iter, &arr_iter);
3105 dbus_message_iter_abandon_container (variant_iter, &arr_iter);
3110 interfaces_getter (BusContext *context,
3111 DBusMessageIter *variant_iter)
3113 DBusMessageIter arr_iter;
3114 const InterfaceHandler *ih;
3116 if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
3117 DBUS_TYPE_STRING_AS_STRING,
3121 for (ih = interface_handlers; ih->name != NULL; ih++)
3123 if (ih->flags & INTERFACE_FLAG_UNINTERESTING)
3126 if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING,
3131 return dbus_message_iter_close_container (variant_iter, &arr_iter);
3134 dbus_message_iter_abandon_container (variant_iter, &arr_iter);
3138 static const InterfaceHandler *
3139 bus_driver_find_interface (const char *name,
3140 dbus_bool_t canonical_path,
3143 const InterfaceHandler *ih;
3145 for (ih = interface_handlers; ih->name != NULL; ih++)
3147 if (!(canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
3150 if (strcmp (name, ih->name) == 0)
3154 dbus_set_error (error, DBUS_ERROR_UNKNOWN_INTERFACE,
3155 "Interface \"%s\" not found", name);
3159 static const PropertyHandler *
3160 interface_handler_find_property (const InterfaceHandler *ih,
3164 const PropertyHandler *ph;
3166 for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
3168 if (strcmp (name, ph->name) == 0)
3172 dbus_set_error (error, DBUS_ERROR_UNKNOWN_PROPERTY,
3173 "Property \"%s.%s\" not found", ih->name, name);
3178 bus_driver_handle_get (DBusConnection *connection,
3179 BusTransaction *transaction,
3180 DBusMessage *message,
3183 const InterfaceHandler *ih;
3184 const PropertyHandler *handler;
3187 BusContext *context;
3188 DBusMessage *reply = NULL;
3189 DBusMessageIter iter;
3190 DBusMessageIter var_iter;
3192 /* The message signature has already been checked for us,
3193 * so this should always succeed. */
3194 if (!dbus_message_get_args (message, error,
3195 DBUS_TYPE_STRING, &iface,
3196 DBUS_TYPE_STRING, &prop,
3200 /* We only implement Properties on /org/freedesktop/DBus so far. */
3201 ih = bus_driver_find_interface (iface, TRUE, error);
3206 handler = interface_handler_find_property (ih, prop, error);
3208 if (handler == NULL)
3211 context = bus_transaction_get_context (transaction);
3213 reply = dbus_message_new_method_return (message);
3218 dbus_message_iter_init_append (reply, &iter);
3220 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT,
3221 handler->type, &var_iter))
3224 if (!handler->getter (context, &var_iter))
3226 dbus_message_iter_abandon_container (&iter, &var_iter);
3230 if (!dbus_message_iter_close_container (&iter, &var_iter))
3233 if (!bus_transaction_send_from_driver (transaction, connection, reply))
3236 dbus_message_unref (reply);
3241 dbus_message_unref (reply);
3243 BUS_SET_OOM (error);
3248 bus_driver_handle_get_all (DBusConnection *connection,
3249 BusTransaction *transaction,
3250 DBusMessage *message,
3253 const InterfaceHandler *ih;
3255 const PropertyHandler *ph;
3256 DBusMessageIter reply_iter;
3257 DBusMessageIter array_iter;
3258 BusContext *context;
3259 DBusMessage *reply = NULL;
3261 /* The message signature has already been checked for us,
3262 * so this should always succeed. */
3263 if (!dbus_message_get_args (message, error,
3264 DBUS_TYPE_STRING, &iface,
3268 /* We only implement Properties on /org/freedesktop/DBus so far. */
3269 ih = bus_driver_find_interface (iface, TRUE, error);
3274 context = bus_transaction_get_context (transaction);
3276 reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
3281 for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
3283 DBusMessageIter entry_iter;
3284 DBusMessageIter var_iter;
3286 if (!_dbus_asv_open_entry (&array_iter, &entry_iter, ph->name,
3287 ph->type, &var_iter))
3288 goto oom_abandon_message;
3290 if (!ph->getter (context, &var_iter))
3292 _dbus_asv_abandon_entry (&array_iter, &entry_iter, &var_iter);
3293 goto oom_abandon_message;
3296 if (!_dbus_asv_close_entry (&array_iter, &entry_iter, &var_iter))
3297 goto oom_abandon_message;
3300 if (!_dbus_asv_close (&reply_iter, &array_iter))
3303 if (!bus_transaction_send_from_driver (transaction, connection, reply))
3306 dbus_message_unref (reply);
3309 oom_abandon_message:
3310 _dbus_asv_abandon (&reply_iter, &array_iter);
3314 dbus_message_unref (reply);
3316 BUS_SET_OOM (error);
3321 bus_driver_handle_set (DBusConnection *connection,
3322 BusTransaction *transaction,
3323 DBusMessage *message,
3326 const InterfaceHandler *ih;
3329 const PropertyHandler *handler;
3330 DBusMessageIter iter;
3332 /* We already checked this in bus_driver_handle_message() */
3333 _dbus_assert (dbus_message_has_signature (message, "ssv"));
3335 if (!dbus_message_iter_init (message, &iter))
3336 _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
3338 dbus_message_iter_get_basic (&iter, &iface);
3340 if (!dbus_message_iter_next (&iter))
3341 _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
3343 dbus_message_iter_get_basic (&iter, &prop);
3345 /* We only implement Properties on /org/freedesktop/DBus so far. */
3346 ih = bus_driver_find_interface (iface, TRUE, error);
3351 handler = interface_handler_find_property (ih, prop, error);
3353 if (handler == NULL)
3356 /* We don't implement any properties that can be set yet. */
3357 dbus_set_error (error, DBUS_ERROR_PROPERTY_READ_ONLY,
3358 "Property '%s.%s' cannot be set", iface, prop);