From 35ef89cd6777ea2430077fc621d21bd01df92349 Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Thu, 27 Nov 2014 11:26:21 +0100 Subject: [PATCH 7/8] Add own rule result unavailability handling Own rule result unavailability is handled like send rules - dispatching messages from the sender is blocked and resumed when result becomes available. Handler of "RequestName" method needs to return BUS_RESULT_LATER when policy result is not known therefore its return type is modified. Since bus message handlers are put into function pointer array other message handler function singatures are also affected. Change-Id: I4c2cbd4585e41fccd8a30f825a8f0d342ab56755 --- bus/dispatch.c | 11 ++- bus/driver.c | 227 ++++++++++++++++++++++++++++++--------------------------- bus/driver.h | 2 +- bus/policy.c | 51 ++++++++++--- bus/policy.h | 6 +- bus/services.c | 26 +++++-- bus/services.h | 3 +- bus/stats.c | 16 ++-- 8 files changed, 204 insertions(+), 138 deletions(-) diff --git a/bus/dispatch.c b/bus/dispatch.c index 9972e76..d3b970f 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -404,8 +404,17 @@ bus_dispatch (DBusConnection *connection, } _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS); - if (!bus_driver_handle_message (connection, transaction, message, &error)) + res = bus_driver_handle_message (connection, transaction, message, &error); + if (res == BUS_RESULT_FALSE) goto out; + else if (res == BUS_RESULT_LATER) + { + /* connection has been disabled in message handler */ + bus_transaction_cancel_and_free (transaction); + transaction = NULL; + result = DBUS_HANDLER_RESULT_LATER; + goto out; + } } else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */ { diff --git a/bus/driver.c b/bus/driver.c index 2fb1385..9708f49 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -297,7 +297,7 @@ create_unique_client_name (BusRegistry *registry, return TRUE; } -static dbus_bool_t +static BusResult bus_driver_handle_hello (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -305,7 +305,7 @@ bus_driver_handle_hello (DBusConnection *connection, { DBusString unique_name; BusService *service; - dbus_bool_t retval; + BusResult retval; BusRegistry *registry; BusConnections *connections; @@ -316,7 +316,7 @@ bus_driver_handle_hello (DBusConnection *connection, /* We already handled an Hello message for this connection. */ dbus_set_error (error, DBUS_ERROR_FAILED, "Already handled an Hello message"); - return FALSE; + return BUS_RESULT_FALSE; } /* Note that when these limits are exceeded we don't disconnect the @@ -330,16 +330,16 @@ bus_driver_handle_hello (DBusConnection *connection, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!_dbus_string_init (&unique_name)) { BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } - retval = FALSE; + retval = BUS_RESULT_FALSE; registry = bus_connection_get_registry (connection); @@ -372,7 +372,7 @@ bus_driver_handle_hello (DBusConnection *connection, goto out_0; _dbus_assert (bus_connection_is_active (connection)); - retval = TRUE; + retval = BUS_RESULT_TRUE; out_0: _dbus_string_free (&unique_name); @@ -424,7 +424,7 @@ bus_driver_send_welcome_message (DBusConnection *connection, } } -static dbus_bool_t +static BusResult bus_driver_handle_list_services (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -446,14 +446,14 @@ bus_driver_handle_list_services (DBusConnection *connection, if (reply == NULL) { BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!bus_registry_list_services (registry, &services, &len)) { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } dbus_message_iter_init_append (reply, &iter); @@ -465,7 +465,7 @@ bus_driver_handle_list_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } { @@ -477,7 +477,7 @@ bus_driver_handle_list_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } } @@ -490,7 +490,7 @@ bus_driver_handle_list_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } ++i; } @@ -501,23 +501,23 @@ bus_driver_handle_list_services (DBusConnection *connection, { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!bus_transaction_send_from_driver (transaction, connection, reply)) { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } else { dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; } } -static dbus_bool_t +static BusResult bus_driver_handle_list_activatable_services (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -539,14 +539,14 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection, if (reply == NULL) { BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!bus_activation_list_services (activation, &services, &len)) { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } dbus_message_iter_init_append (reply, &iter); @@ -558,7 +558,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } { @@ -570,7 +570,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } } @@ -583,7 +583,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection, dbus_free_string_array (services); dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } ++i; } @@ -594,23 +594,23 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection, { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!bus_transaction_send_from_driver (transaction, connection, reply)) { dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } else { dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; } } -static dbus_bool_t +static BusResult bus_driver_handle_acquire_service (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -621,7 +621,8 @@ bus_driver_handle_acquire_service (DBusConnection *connection, const char *name; dbus_uint32_t service_reply; dbus_uint32_t flags; - dbus_bool_t retval; + BusResult retval; + BusResult res; BusRegistry *registry; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -632,20 +633,24 @@ bus_driver_handle_acquire_service (DBusConnection *connection, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID)) - return FALSE; + return BUS_RESULT_FALSE; _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags); - retval = FALSE; + retval = BUS_RESULT_FALSE; reply = NULL; _dbus_string_init_const (&service_name, name); - if (!bus_registry_acquire_service (registry, connection, - &service_name, flags, - &service_reply, transaction, - error)) - goto out; + res = bus_registry_acquire_service (registry, connection, message, + &service_name, flags, + &service_reply, transaction, + error); + if (res != BUS_RESULT_TRUE) + { + retval = res; + goto out; + } reply = dbus_message_new_method_return (message); if (reply == NULL) @@ -666,7 +671,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection, goto out; } - retval = TRUE; + retval = BUS_RESULT_TRUE; out: if (reply) @@ -674,7 +679,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection, return retval; } -static dbus_bool_t +static BusResult bus_driver_handle_release_service (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -684,7 +689,7 @@ bus_driver_handle_release_service (DBusConnection *connection, DBusString service_name; const char *name; dbus_uint32_t service_reply; - dbus_bool_t retval; + BusResult retval; BusRegistry *registry; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -694,11 +699,11 @@ bus_driver_handle_release_service (DBusConnection *connection, if (!dbus_message_get_args (message, error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) - return FALSE; + return BUS_RESULT_FALSE; _dbus_verbose ("Trying to release name %s\n", name); - retval = FALSE; + retval = BUS_RESULT_FALSE; reply = NULL; _dbus_string_init_const (&service_name, name); @@ -727,7 +732,7 @@ bus_driver_handle_release_service (DBusConnection *connection, goto out; } - retval = TRUE; + retval = BUS_RESULT_TRUE; out: if (reply) @@ -735,7 +740,7 @@ bus_driver_handle_release_service (DBusConnection *connection, return retval; } -static dbus_bool_t +static BusResult bus_driver_handle_service_exists (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -746,7 +751,7 @@ bus_driver_handle_service_exists (DBusConnection *connection, BusService *service; dbus_bool_t service_exists; const char *name; - dbus_bool_t retval; + BusResult retval; BusRegistry *registry; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -756,9 +761,9 @@ bus_driver_handle_service_exists (DBusConnection *connection, if (!dbus_message_get_args (message, error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) - return FALSE; + return BUS_RESULT_FALSE; - retval = FALSE; + retval = BUS_RESULT_FALSE; if (strcmp (name, DBUS_SERVICE_DBUS) == 0) { @@ -792,7 +797,7 @@ bus_driver_handle_service_exists (DBusConnection *connection, goto out; } - retval = TRUE; + retval = BUS_RESULT_TRUE; out: if (reply) @@ -801,7 +806,7 @@ bus_driver_handle_service_exists (DBusConnection *connection, return retval; } -static dbus_bool_t +static BusResult bus_driver_handle_activate_service (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -809,7 +814,7 @@ bus_driver_handle_activate_service (DBusConnection *connection, { dbus_uint32_t flags; const char *name; - dbus_bool_t retval; + BusResult retval; BusActivation *activation; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -823,10 +828,10 @@ bus_driver_handle_activate_service (DBusConnection *connection, { _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_verbose ("No memory to get arguments to StartServiceByName\n"); - return FALSE; + return BUS_RESULT_FALSE; } - retval = FALSE; + retval = BUS_RESULT_FALSE; if (!bus_activation_activate_service (activation, connection, transaction, FALSE, message, name, error)) @@ -836,7 +841,7 @@ bus_driver_handle_activate_service (DBusConnection *connection, goto out; } - retval = TRUE; + retval = BUS_RESULT_TRUE; out: return retval; @@ -872,13 +877,13 @@ send_ack_reply (DBusConnection *connection, return TRUE; } -static dbus_bool_t +static BusResult bus_driver_handle_update_activation_environment (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, DBusError *error) { - dbus_bool_t retval; + BusResult retval; BusActivation *activation; DBusMessageIter iter; DBusMessageIter dict_iter; @@ -939,7 +944,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection, dbus_message_iter_recurse (&iter, &dict_iter); - retval = FALSE; + retval = BUS_RESULT_FALSE; /* Then loop through the sent dictionary, add the location of * the environment keys and values to lists. The result will @@ -1026,7 +1031,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection, message, error)) goto out; - retval = TRUE; + retval = BUS_RESULT_TRUE; out: _dbus_list_clear (&keys); @@ -1034,7 +1039,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection, return retval; } -static dbus_bool_t +static BusResult bus_driver_handle_add_match (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1093,16 +1098,16 @@ bus_driver_handle_add_match (DBusConnection *connection, bus_match_rule_unref (rule); - return TRUE; + return BUS_RESULT_TRUE; failed: _DBUS_ASSERT_ERROR_IS_SET (error); if (rule) bus_match_rule_unref (rule); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_remove_match (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1146,16 +1151,16 @@ bus_driver_handle_remove_match (DBusConnection *connection, bus_match_rule_unref (rule); - return TRUE; + return BUS_RESULT_TRUE; failed: _DBUS_ASSERT_ERROR_IS_SET (error); if (rule) bus_match_rule_unref (rule); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_service_owner (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1225,7 +1230,7 @@ bus_driver_handle_get_service_owner (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1234,10 +1239,10 @@ bus_driver_handle_get_service_owner (DBusConnection *connection, _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_list_queued_owners (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1328,7 +1333,7 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1341,10 +1346,10 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection, if (base_names) _dbus_list_clear (&base_names); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_connection_unix_user (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1389,7 +1394,7 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1398,10 +1403,10 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection, _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1446,7 +1451,7 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1455,10 +1460,10 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1502,7 +1507,7 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1511,10 +1516,10 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1556,7 +1561,7 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1565,10 +1570,10 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_connection_credentials (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1645,7 +1650,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1659,10 +1664,10 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, dbus_message_unref (reply); } - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_reload_config (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1687,7 +1692,7 @@ bus_driver_handle_reload_config (DBusConnection *connection, goto oom; dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -1696,10 +1701,10 @@ bus_driver_handle_reload_config (DBusConnection *connection, _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); - return FALSE; + return BUS_RESULT_FALSE; } -static dbus_bool_t +static BusResult bus_driver_handle_get_id (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1715,7 +1720,7 @@ bus_driver_handle_get_id (DBusConnection *connection, if (!_dbus_string_init (&uuid)) { BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } reply = NULL; @@ -1741,7 +1746,7 @@ bus_driver_handle_get_id (DBusConnection *connection, _dbus_string_free (&uuid); dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1751,7 +1756,7 @@ bus_driver_handle_get_id (DBusConnection *connection, if (reply) dbus_message_unref (reply); _dbus_string_free (&uuid); - return FALSE; + return BUS_RESULT_FALSE; } typedef struct @@ -1759,10 +1764,10 @@ typedef struct const char *name; const char *in_args; const char *out_args; - dbus_bool_t (* handler) (DBusConnection *connection, - BusTransaction *transaction, - DBusMessage *message, - DBusError *error); + BusResult (* handler) (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error); } MessageHandler; /* For speed it might be useful to sort this in order of @@ -1847,7 +1852,7 @@ static const MessageHandler dbus_message_handlers[] = { { NULL, NULL, NULL, NULL } }; -static dbus_bool_t bus_driver_handle_introspect (DBusConnection *, +static BusResult bus_driver_handle_introspect (DBusConnection *, BusTransaction *, DBusMessage *, DBusError *); static const MessageHandler introspectable_message_handlers[] = { @@ -1973,7 +1978,7 @@ bus_driver_generate_introspect_string (DBusString *xml) return TRUE; } -static dbus_bool_t +static BusResult bus_driver_handle_introspect (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -1993,13 +1998,13 @@ bus_driver_handle_introspect (DBusConnection *connection, DBUS_TYPE_INVALID)) { _DBUS_ASSERT_ERROR_IS_SET (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!_dbus_string_init (&xml)) { BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } if (!bus_driver_generate_introspect_string (&xml)) @@ -2022,7 +2027,7 @@ bus_driver_handle_introspect (DBusConnection *connection, dbus_message_unref (reply); _dbus_string_free (&xml); - return TRUE; + return BUS_RESULT_TRUE; oom: BUS_SET_OOM (error); @@ -2032,7 +2037,7 @@ bus_driver_handle_introspect (DBusConnection *connection, _dbus_string_free (&xml); - return FALSE; + return BUS_RESULT_FALSE; } /* @@ -2067,7 +2072,7 @@ bus_driver_check_message_is_for_us (DBusMessage *message, return TRUE; } -dbus_bool_t +BusResult bus_driver_handle_message (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -2077,6 +2082,7 @@ bus_driver_handle_message (DBusConnection *connection, const InterfaceHandler *ih; const MessageHandler *mh; dbus_bool_t found_interface = FALSE; + BusResult res; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -2085,13 +2091,13 @@ bus_driver_handle_message (DBusConnection *connection, BusContext *context; context = bus_connection_get_context (connection); - return dbus_activation_systemd_failure(bus_context_get_activation(context), message); + return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE; } if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL) { _dbus_verbose ("Driver got a non-method-call message, ignoring\n"); - return TRUE; /* we just ignore this */ + return BUS_RESULT_TRUE; /* we just ignore this */ } /* may be NULL, which means "any interface will do" */ @@ -2133,20 +2139,27 @@ bus_driver_handle_message (DBusConnection *connection, name, dbus_message_get_signature (message), mh->in_args); _DBUS_ASSERT_ERROR_IS_SET (error); - return FALSE; + return BUS_RESULT_FALSE; } - if ((* mh->handler) (connection, transaction, message, error)) + res = (* mh->handler) (connection, transaction, message, error); + if (res == BUS_RESULT_TRUE) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("Driver handler succeeded\n"); - return TRUE; + return BUS_RESULT_TRUE; } - else + else if (res == BUS_RESULT_FALSE) { _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_verbose ("Driver handler returned failure\n"); - return FALSE; + return BUS_RESULT_FALSE; + } + else if (res == BUS_RESULT_LATER) + { + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + _dbus_verbose ("Driver handler delayed message processing due to policy check\n"); + return BUS_RESULT_LATER; } } } @@ -2158,7 +2171,7 @@ bus_driver_handle_message (DBusConnection *connection, "%s does not understand message %s", DBUS_SERVICE_DBUS, name); - return FALSE; + return BUS_RESULT_FALSE; } void diff --git a/bus/driver.h b/bus/driver.h index 201709c..3ff4ff1 100644 --- a/bus/driver.h +++ b/bus/driver.h @@ -28,7 +28,7 @@ #include "connection.h" void bus_driver_remove_connection (DBusConnection *connection); -dbus_bool_t bus_driver_handle_message (DBusConnection *connection, +BusResult bus_driver_handle_message (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, DBusError *error); diff --git a/bus/policy.c b/bus/policy.c index 448147f..3672ff9 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -1323,18 +1323,21 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, -static dbus_bool_t +static BusResult bus_rules_check_can_own (DBusList *rules, - const DBusString *service_name) + const DBusString *service_name, + DBusConnection *connection, + DBusMessage *message) { DBusList *link; - dbus_bool_t allowed; + BusResult result; + const char *privilege; /* rules is in the order the rules appeared * in the config file, i.e. last rule that applies wins */ - allowed = FALSE; + result = BUS_RESULT_FALSE; link = _dbus_list_get_first_link (&rules); while (link != NULL) { @@ -1370,17 +1373,45 @@ bus_rules_check_can_own (DBusList *rules, } /* Use this rule */ - allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW; + switch (rule->access) + { + case BUS_POLICY_RULE_ACCESS_ALLOW: + result = BUS_RESULT_TRUE; + break; + case BUS_POLICY_RULE_ACCESS_DENY: + result = BUS_RESULT_FALSE; + break; + case BUS_POLICY_RULE_ACCESS_CHECK: + result = BUS_RESULT_LATER; + privilege = rule->privilege; + break; + } } - return allowed; + if (result == BUS_RESULT_LATER) + { + BusContext *context = bus_connection_get_context(connection); + BusCheck *check = bus_context_get_check(context); + BusDeferredMessage *deferred_message; + + result = bus_check_privilege(check, message, connection, NULL, NULL, + privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message); + if (result == BUS_RESULT_LATER) + { + bus_deferred_message_disable_sender(deferred_message); + } + } + + return result; } -dbus_bool_t +BusResult bus_client_policy_check_can_own (BusClientPolicy *policy, - const DBusString *service_name) + const DBusString *service_name, + DBusConnection *connection, + DBusMessage *message) { - return bus_rules_check_can_own (policy->rules, service_name); + return bus_rules_check_can_own (policy->rules, service_name, connection, message); } #ifdef DBUS_ENABLE_EMBEDDED_TESTS @@ -1388,7 +1419,7 @@ dbus_bool_t bus_policy_check_can_own (BusPolicy *policy, const DBusString *service_name) { - return bus_rules_check_can_own (policy->default_rules, service_name); + return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL); } #endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/bus/policy.h b/bus/policy.h index e9f193a..1f23431 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -170,8 +170,10 @@ BusResult bus_client_policy_check_can_receive (BusClientPolicy *polic dbus_int32_t *toggles, const char **privilege_param, BusDeferredMessage **deferred_message); -dbus_bool_t bus_client_policy_check_can_own (BusClientPolicy *policy, - const DBusString *service_name); +BusResult bus_client_policy_check_can_own (BusClientPolicy *policy, + const DBusString *service_name, + DBusConnection *connection, + DBusMessage *message); dbus_bool_t bus_client_policy_append_rule (BusClientPolicy *policy, BusPolicyRule *rule); void bus_client_policy_optimize (BusClientPolicy *policy); diff --git a/bus/services.c b/bus/services.c index 584485b..f25fdf3 100644 --- a/bus/services.c +++ b/bus/services.c @@ -374,24 +374,26 @@ bus_registry_list_services (BusRegistry *registry, return FALSE; } -dbus_bool_t +BusResult bus_registry_acquire_service (BusRegistry *registry, DBusConnection *connection, + DBusMessage *message, const DBusString *service_name, dbus_uint32_t flags, dbus_uint32_t *result, BusTransaction *transaction, DBusError *error) { - dbus_bool_t retval; + BusResult retval; DBusConnection *old_owner_conn; BusClientPolicy *policy; BusService *service; BusActivation *activation; BusSELinuxID *sid; BusOwner *primary_owner; + BusResult res; - retval = FALSE; + retval = BUS_RESULT_FALSE; if (!_dbus_validate_bus_name (service_name, 0, _dbus_string_get_length (service_name))) @@ -459,7 +461,8 @@ bus_registry_acquire_service (BusRegistry *registry, goto out; } - if (!bus_client_policy_check_can_own (policy, service_name)) + res = bus_client_policy_check_can_own (policy, service_name, connection, message); + if (res == BUS_RESULT_FALSE) { dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Connection \"%s\" is not allowed to own the service \"%s\" due " @@ -470,6 +473,11 @@ bus_registry_acquire_service (BusRegistry *registry, _dbus_string_get_const_data (service_name)); goto out; } + else if (res == BUS_RESULT_LATER) + { + retval = BUS_RESULT_LATER; + goto out; + } if (bus_connection_get_n_services_owned (connection) >= bus_context_get_max_services_per_connection (registry->context)) @@ -586,11 +594,13 @@ bus_registry_acquire_service (BusRegistry *registry, } activation = bus_context_get_activation (registry->context); - retval = bus_activation_send_pending_auto_activation_messages (activation, + + if (bus_activation_send_pending_auto_activation_messages (activation, service, - transaction); - if (!retval) - BUS_SET_OOM (error); + transaction)) + retval = BUS_RESULT_TRUE; + else + BUS_SET_OOM (error); out: return retval; diff --git a/bus/services.h b/bus/services.h index 056dd9f..3df3dd7 100644 --- a/bus/services.h +++ b/bus/services.h @@ -50,8 +50,9 @@ void bus_registry_foreach (BusRegistry *registry dbus_bool_t bus_registry_list_services (BusRegistry *registry, char ***listp, int *array_len); -dbus_bool_t bus_registry_acquire_service (BusRegistry *registry, +BusResult bus_registry_acquire_service (BusRegistry *registry, DBusConnection *connection, + DBusMessage *message, const DBusString *service_name, dbus_uint32_t flags, dbus_uint32_t *result, diff --git a/bus/stats.c b/bus/stats.c index 20321e5..61dc428 100644 --- a/bus/stats.c +++ b/bus/stats.c @@ -35,7 +35,7 @@ #ifdef DBUS_ENABLE_STATS -dbus_bool_t +BusResult bus_stats_handle_get_stats (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, @@ -106,17 +106,17 @@ bus_stats_handle_get_stats (DBusConnection *connection, goto oom; dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: if (reply != NULL) dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } -dbus_bool_t +BusResult bus_stats_handle_get_connection_stats (DBusConnection *caller_connection, BusTransaction *transaction, DBusMessage *message, @@ -143,7 +143,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection, if (! dbus_message_get_args (message, error, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID)) - return FALSE; + return BUS_RESULT_FALSE; _dbus_string_init_const (&bus_name_str, bus_name); service = bus_registry_lookup (registry, &bus_name_str); @@ -152,7 +152,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection, { dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, "Bus name '%s' has no owner", bus_name); - return FALSE; + return BUS_RESULT_FALSE; } stats_connection = bus_service_get_primary_owners_connection (service); @@ -214,14 +214,14 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection, goto oom; dbus_message_unref (reply); - return TRUE; + return BUS_RESULT_TRUE; oom: if (reply != NULL) dbus_message_unref (reply); BUS_SET_OOM (error); - return FALSE; + return BUS_RESULT_FALSE; } #endif -- 2.1.4