From: Havoc Pennington Date: Mon, 14 Apr 2003 02:29:21 +0000 (+0000) Subject: 2003-04-13 Havoc Pennington X-Git-Tag: dbus-0.10~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=777707ed8dff6958972a93894a87ec1945c65c14;p=platform%2Fupstream%2Fdbus.git 2003-04-13 Havoc Pennington * dbus/dbus-mainloop.c: fix some reentrancy issues by refcounting callbacks * test/data/valid-config-files/debug-allow-all.conf.in: allow all users * dbus/dbus-transport.c (_dbus_transport_get_dispatch_status): fix to only recover unused bytes if we're already authenticated (_dbus_transport_get_is_authenticated): fix to still mark us authenticated if there are unused bytes. * bus/dispatch.c: implement security policy checking * bus/connection.c (bus_transaction_send_from_driver): new * bus/bus.c (bus_context_check_security_policy): new * bus/dispatch.c (send_service_nonexistent_error): delete this, now we just set the DBusError and it gets converted to an error reply. * bus/connection.c (allow_user_function): enable code using actual data from the config file * bus/policy.c (list_allows_user): handle wildcard rules for user/group connection perms --- diff --git a/ChangeLog b/ChangeLog index 1cb38e2..0d03e46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,34 @@ 2003-04-13 Havoc Pennington + * dbus/dbus-mainloop.c: fix some reentrancy issues by refcounting + callbacks + + * test/data/valid-config-files/debug-allow-all.conf.in: allow all + users + + * dbus/dbus-transport.c (_dbus_transport_get_dispatch_status): + fix to only recover unused bytes if we're already authenticated + (_dbus_transport_get_is_authenticated): fix to still mark us + authenticated if there are unused bytes. + + * bus/dispatch.c: implement security policy checking + + * bus/connection.c (bus_transaction_send_from_driver): new + + * bus/bus.c (bus_context_check_security_policy): new + + * bus/dispatch.c (send_service_nonexistent_error): delete this, + now we just set the DBusError and it gets converted to an error + reply. + + * bus/connection.c (allow_user_function): enable code using actual + data from the config file + + * bus/policy.c (list_allows_user): handle wildcard rules for + user/group connection perms + +2003-04-13 Havoc Pennington + * bus/config-parser.c: Load up the BusPolicy and BusPolicyRules * dbus/dbus-sysdeps.c (_dbus_get_user_id): new function diff --git a/bus/activation.c b/bus/activation.c index 1a448a7..0a70d6b 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -582,8 +582,7 @@ bus_activation_service_created (BusActivation *activation, goto error; } - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) || - !dbus_message_append_args (message, + if (!dbus_message_append_args (message, DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED, 0)) { @@ -592,7 +591,7 @@ bus_activation_service_created (BusActivation *activation, goto error; } - if (!bus_transaction_send_message (transaction, entry->connection, message)) + if (!bus_transaction_send_from_driver (transaction, entry->connection, message)) { dbus_message_unref (message); BUS_SET_OOM (error); @@ -654,14 +653,8 @@ try_send_activation_failure (BusPendingActivation *pending_activation, how->message); if (!message) goto error; - - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) - { - dbus_message_unref (message); - goto error; - } - if (!bus_transaction_send_message (transaction, entry->connection, message)) + if (!bus_transaction_send_from_driver (transaction, entry->connection, message)) { dbus_message_unref (message); goto error; @@ -861,8 +854,7 @@ bus_activation_activate_service (BusActivation *activation, return FALSE; } - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) || - !dbus_message_append_args (message, + if (!dbus_message_append_args (message, DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE, 0)) { @@ -872,7 +864,7 @@ bus_activation_activate_service (BusActivation *activation, return FALSE; } - retval = bus_transaction_send_message (transaction, connection, message); + retval = bus_transaction_send_from_driver (transaction, connection, message); dbus_message_unref (message); if (!retval) { diff --git a/bus/bus.c b/bus/bus.c index 31b43f2..7b7ea6f 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -796,3 +796,66 @@ bus_context_get_activation_timeout (BusContext *context) return context->activation_timeout; } + +dbus_bool_t +bus_context_check_security_policy (BusContext *context, + DBusConnection *sender, + DBusConnection *recipient, + DBusMessage *message, + DBusError *error) +{ + BusClientPolicy *sender_policy; + BusClientPolicy *recipient_policy; + + /* NULL sender/receiver means the bus driver */ + + if (sender != NULL) + { + _dbus_assert (dbus_connection_get_is_authenticated (sender)); + sender_policy = bus_connection_get_policy (sender); + } + else + sender_policy = NULL; + + if (recipient != NULL) + { + _dbus_assert (dbus_connection_get_is_authenticated (recipient)); + recipient_policy = bus_connection_get_policy (recipient); + } + else + recipient_policy = NULL; + + if (sender_policy && + !bus_client_policy_check_can_send (sender_policy, + context->registry, recipient, + message)) + { + const char *dest = dbus_message_get_service (message); + dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, + "A security policy in place prevents this sender " + "from sending this message to this recipient, " + "see message bus configuration file (rejected message " + "had name \"%s\" destination \"%s\")", + dbus_message_get_name (message), + dest ? dest : DBUS_SERVICE_DBUS); + return FALSE; + } + + if (recipient_policy && + !bus_client_policy_check_can_receive (recipient_policy, + context->registry, sender, + message)) + { + const char *dest = dbus_message_get_service (message); + dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, + "A security policy in place prevents this recipient " + "from receiving this message from this sender, " + "see message bus configuration file (rejected message " + "had name \"%s\" destination \"%s\")", + dbus_message_get_name (message), + dest ? dest : DBUS_SERVICE_DBUS); + return FALSE; + } + + return TRUE; +} diff --git a/bus/bus.h b/bus/bus.h index 754fab0..885182c 100644 --- a/bus/bus.h +++ b/bus/bus.h @@ -57,6 +57,11 @@ dbus_bool_t bus_context_allow_user (BusContext *context, BusClientPolicy* bus_context_create_client_policy (BusContext *context, DBusConnection *connection); int bus_context_get_activation_timeout (BusContext *context); +dbus_bool_t bus_context_check_security_policy (BusContext *context, + DBusConnection *sender, + DBusConnection *recipient, + DBusMessage *message, + DBusError *error); #endif /* BUS_BUS_H */ diff --git a/bus/config-parser.c b/bus/config-parser.c index 85c367b..bf959ae 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -859,7 +859,7 @@ append_rule_from_element (BusConfigParser *parser, if (rule == NULL) goto nomem; - /* FIXME the wildcard needs storing in the rule somehow */ + rule->d.user.uid = DBUS_UID_UNSET; } else { @@ -873,10 +873,7 @@ append_rule_from_element (BusConfigParser *parser, rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); if (rule == NULL) goto nomem; - - rule->d.user.user = _dbus_strdup (user); - if (rule->d.user.user == NULL) - goto nomem; + rule->d.user.uid = uid; } else @@ -894,7 +891,7 @@ append_rule_from_element (BusConfigParser *parser, if (rule == NULL) goto nomem; - /* FIXME the wildcard needs storing in the rule somehow */ + rule->d.group.gid = DBUS_GID_UNSET; } else { @@ -908,10 +905,7 @@ append_rule_from_element (BusConfigParser *parser, rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); if (rule == NULL) goto nomem; - - rule->d.group.group = _dbus_strdup (group); - if (rule->d.group.group == NULL) - goto nomem; + rule->d.group.gid = gid; } else diff --git a/bus/connection.c b/bus/connection.c index 21c8f1a..4c48fbd 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -283,8 +283,6 @@ allow_user_function (DBusConnection *connection, d = BUS_CONNECTION_DATA (connection); _dbus_assert (d != NULL); - - return TRUE; /* FIXME - this is just until we can parse a config file */ return bus_context_allow_user (d->connections->context, uid); } @@ -504,7 +502,7 @@ bus_connection_get_groups (DBusConnection *connection, if (dbus_connection_get_unix_user (connection, &uid)) { - if (!_dbus_get_groups (uid, &d->group_ids, &d->n_group_ids)) + if (!_dbus_get_groups (uid, &d->group_ids, &d->n_group_ids, NULL)) { _dbus_verbose ("Did not get any groups for UID %lu\n", uid); @@ -924,9 +922,34 @@ bus_transaction_get_connections (BusTransaction *transaction) } dbus_bool_t -bus_transaction_send_message (BusTransaction *transaction, - DBusConnection *connection, - DBusMessage *message) +bus_transaction_send_from_driver (BusTransaction *transaction, + DBusConnection *connection, + DBusMessage *message) +{ + /* We have to set the sender to the driver, and have + * to check security policy since it was not done in + * dispatch.c + */ + _dbus_verbose ("Sending %s from driver\n", + dbus_message_get_name (message)); + + if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) + return FALSE; + + /* If security policy doesn't allow the message, we silently + * eat it; the driver doesn't care about getting a reply. + */ + if (!bus_context_check_security_policy (bus_transaction_get_context (transaction), + NULL, connection, message, NULL)) + return TRUE; + + return bus_transaction_send (transaction, connection, message); +} + +dbus_bool_t +bus_transaction_send (BusTransaction *transaction, + DBusConnection *connection, + DBusMessage *message) { MessageToSend *to_send; BusConnectionData *d; @@ -934,7 +957,7 @@ bus_transaction_send_message (BusTransaction *transaction, _dbus_verbose (" trying to add %s %s to transaction%s\n", dbus_message_get_is_error (message) ? "error" : - dbus_message_get_reply_serial (message) != 0 ? "reply" : + dbus_message_get_reply_serial (message) != -1 ? "reply" : "message", dbus_message_get_name (message), dbus_connection_get_is_connected (connection) ? @@ -1152,8 +1175,7 @@ bus_transaction_send_error_reply (BusTransaction *transaction, if (reply == NULL) return FALSE; - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS) || - !bus_transaction_send_message (transaction, connection, reply)) + if (!bus_transaction_send_from_driver (transaction, connection, reply)) { dbus_message_unref (reply); return FALSE; diff --git a/bus/connection.h b/bus/connection.h index 4962211..ead4767 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -84,7 +84,10 @@ typedef void (* BusTransactionCancelFunction) (void *data); BusTransaction* bus_transaction_new (BusContext *context); BusContext* bus_transaction_get_context (BusTransaction *transaction); BusConnections* bus_transaction_get_connections (BusTransaction *transaction); -dbus_bool_t bus_transaction_send_message (BusTransaction *transaction, +dbus_bool_t bus_transaction_send (BusTransaction *transaction, + DBusConnection *connection, + DBusMessage *message); +dbus_bool_t bus_transaction_send_from_driver (BusTransaction *transaction, DBusConnection *connection, DBusMessage *message); dbus_bool_t bus_transaction_send_error_reply (BusTransaction *transaction, diff --git a/bus/dispatch.c b/bus/dispatch.c index 4131754..3ce7731 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -37,6 +37,8 @@ static int message_handler_slot_refcount; typedef struct { + BusContext *context; + DBusConnection *sender; DBusMessage *message; BusTransaction *transaction; DBusError *error; @@ -50,9 +52,16 @@ send_one_message (DBusConnection *connection, void *data) if (!bus_connection_is_active (connection)) return TRUE; - if (!bus_transaction_send_message (d->transaction, - connection, - d->message)) + if (!bus_context_check_security_policy (d->context, + d->sender, + connection, + d->message, + NULL)) + return TRUE; /* silently don't send it */ + + if (!bus_transaction_send (d->transaction, + connection, + d->message)) { BUS_SET_OOM (d->error); return FALSE; @@ -63,6 +72,7 @@ send_one_message (DBusConnection *connection, void *data) dbus_bool_t bus_dispatch_broadcast_message (BusTransaction *transaction, + DBusConnection *sender, DBusMessage *message, DBusError *error) { @@ -77,6 +87,8 @@ bus_dispatch_broadcast_message (BusTransaction *transaction, connections = bus_transaction_get_connections (transaction); dbus_error_init (&tmp_error); + d.sender = sender; + d.context = bus_transaction_get_context (transaction); d.message = message; d.transaction = transaction; d.error = &tmp_error; @@ -92,70 +104,6 @@ bus_dispatch_broadcast_message (BusTransaction *transaction, return TRUE; } -static dbus_bool_t -send_service_nonexistent_error (BusTransaction *transaction, - DBusConnection *connection, - const char *service_name, - DBusMessage *in_reply_to, - DBusError *error) -{ - DBusMessage *error_reply; - DBusString error_message; - const char *error_str; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - /* Trying to send a message to a non-existant service, - * bounce back an error message. - */ - - if (!_dbus_string_init (&error_message)) - { - BUS_SET_OOM (error); - return FALSE; - } - - if (!_dbus_string_append (&error_message, "Service \"") || - !_dbus_string_append (&error_message, service_name) || - !_dbus_string_append (&error_message, "\" does not exist")) - { - _dbus_string_free (&error_message); - BUS_SET_OOM (error); - return FALSE; - } - - error_str = _dbus_string_get_const_data (&error_message); - error_reply = dbus_message_new_error_reply (in_reply_to, - DBUS_ERROR_SERVICE_DOES_NOT_EXIST, - error_str); - - _dbus_string_free (&error_message); - - if (error_reply == NULL) - { - BUS_SET_OOM (error); - return FALSE; - } - - if (!dbus_message_set_sender (error_reply, DBUS_SERVICE_DBUS)) - { - dbus_message_unref (error_reply); - BUS_SET_OOM (error); - return FALSE; - } - - if (!bus_transaction_send_message (transaction, connection, error_reply)) - { - dbus_message_unref (error_reply); - BUS_SET_OOM (error); - return FALSE; - } - - dbus_message_unref (error_reply); - - return TRUE; -} - static void bus_dispatch (DBusConnection *connection, DBusMessage *message) @@ -188,9 +136,10 @@ bus_dispatch (DBusConnection *connection, _dbus_verbose ("DISPATCH: %s to %s\n", message_name, service_name ? service_name : "peer"); - /* If service_name is NULL, this is a message to the bus daemon, not intended - * to actually go "on the bus"; e.g. a peer-to-peer ping. Handle these - * immediately, especially disconnection messages. + /* If service_name is NULL, this is a message to the bus daemon, not + * intended to actually go "on the bus"; e.g. a peer-to-peer + * ping. Handle these immediately, especially disconnection + * messages. There are no security policy checks on these. */ if (service_name == NULL) { @@ -235,6 +184,10 @@ bus_dispatch (DBusConnection *connection, if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */ { + if (!bus_context_check_security_policy (context, + connection, NULL, message, &error)) + goto out; + if (!bus_driver_handle_message (connection, transaction, message, &error)) goto out; } @@ -249,7 +202,7 @@ bus_dispatch (DBusConnection *connection, */ else if (strcmp (service_name, DBUS_SERVICE_BROADCAST) == 0) /* spam! */ { - if (!bus_dispatch_broadcast_message (transaction, message, &error)) + if (!bus_dispatch_broadcast_message (transaction, connection, message, &error)) goto out; } else /* route to named service */ @@ -265,19 +218,25 @@ bus_dispatch (DBusConnection *connection, if (service == NULL) { - if (!send_service_nonexistent_error (transaction, connection, - service_name, - message, &error)) - goto out; + dbus_set_error (&error, + DBUS_ERROR_SERVICE_DOES_NOT_EXIST, + "Service \"%s\" does not exist", + service_name); + goto out; } else { - _dbus_assert (bus_service_get_primary_owner (service) != NULL); - + DBusConnection *recipient; + + recipient = bus_service_get_primary_owner (service); + _dbus_assert (recipient != NULL); + + if (!bus_context_check_security_policy (context, + connection, recipient, message, &error)) + goto out; + /* Dispatch the message */ - if (!bus_transaction_send_message (transaction, - bus_service_get_primary_owner (service), - message)) + if (!bus_transaction_send (transaction, recipient, message)) { BUS_SET_OOM (&error); goto out; @@ -316,7 +275,7 @@ bus_dispatch (DBusConnection *connection, &error, message)) { bus_connection_send_oom_error (connection, message); - + /* cancel transaction due to OOM */ if (transaction != NULL) { @@ -608,8 +567,9 @@ kill_client_connection_unchecked (DBusConnection *connection) /* dispatching disconnect handler will unref once */ if (bus_connection_dispatch_one_message (connection)) _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register"); - dbus_connection_unref (connection); + _dbus_assert (!bus_test_client_listed (connection)); + dbus_connection_unref (connection); } typedef struct @@ -740,10 +700,12 @@ check_hello_message (BusContext *context, DBusError error; char *name; char *acquired; - + + retval = FALSE; dbus_error_init (&error); name = NULL; acquired = NULL; + message = NULL; message = dbus_message_new (DBUS_SERVICE_DBUS, DBUS_MESSAGE_HELLO); @@ -760,15 +722,22 @@ check_hello_message (BusContext *context, dbus_message_unref (message); message = NULL; - bus_test_run_everything (context); + /* send our message */ + bus_test_run_clients_loop (TRUE); + + dbus_connection_ref (connection); /* because we may get disconnected */ + block_connection_until_message_from_bus (context, connection); if (!dbus_connection_get_is_connected (connection)) { _dbus_verbose ("connection was disconnected\n"); + + dbus_connection_unref (connection); + return TRUE; } - - retval = FALSE; + + dbus_connection_unref (connection); message = pop_message_waiting_for_memory (connection); if (message == NULL) @@ -1390,7 +1359,10 @@ check_send_exit_to_service (BusContext *context, message = dbus_connection_borrow_message (connection); got_error = message != NULL && dbus_message_get_is_error (message); if (message) - dbus_connection_return_message (connection, message); + { + dbus_connection_return_message (connection, message); + message = NULL; + } if (!got_error) { @@ -1944,6 +1916,12 @@ bus_dispatch_test (const DBusString *test_data_dir) if (!check_hello_message (context, baz)) _dbus_assert_not_reached ("hello message failed"); + if (!check_no_leftovers (context)) + { + _dbus_warn ("Messages were left over after setting up initial connections"); + _dbus_assert_not_reached ("initial connection setup failed"); + } + check1_try_iterations (context, "create_and_hello", check_hello_connection); diff --git a/bus/dispatch.h b/bus/dispatch.h index c24170d..18f7452 100644 --- a/bus/dispatch.h +++ b/bus/dispatch.h @@ -30,6 +30,7 @@ dbus_bool_t bus_dispatch_add_connection (DBusConnection *connection); void bus_dispatch_remove_connection (DBusConnection *connection); dbus_bool_t bus_dispatch_broadcast_message (BusTransaction *transaction, + DBusConnection *sender, DBusMessage *message, DBusError *error); diff --git a/bus/driver.c b/bus/driver.c index f89b70a..c7d66d5 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -67,7 +67,7 @@ bus_driver_send_service_deleted (const char *service_name, return FALSE; } - retval = bus_dispatch_broadcast_message (transaction, message, error); + retval = bus_dispatch_broadcast_message (transaction, NULL, message, error); dbus_message_unref (message); return retval; @@ -107,7 +107,7 @@ bus_driver_send_service_created (const char *service_name, return FALSE; } - retval = bus_dispatch_broadcast_message (transaction, message, error); + retval = bus_dispatch_broadcast_message (transaction, NULL, message, error); dbus_message_unref (message); return retval; @@ -131,13 +131,6 @@ bus_driver_send_service_lost (DBusConnection *connection, return FALSE; } - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) - { - dbus_message_unref (message); - BUS_SET_OOM (error); - return FALSE; - } - if (!dbus_message_append_args (message, DBUS_TYPE_STRING, service_name, 0)) @@ -147,7 +140,7 @@ bus_driver_send_service_lost (DBusConnection *connection, return FALSE; } - if (!bus_transaction_send_message (transaction, connection, message)) + if (!bus_transaction_send_from_driver (transaction, connection, message)) { dbus_message_unref (message); BUS_SET_OOM (error); @@ -178,13 +171,6 @@ bus_driver_send_service_acquired (DBusConnection *connection, return FALSE; } - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) - { - dbus_message_unref (message); - BUS_SET_OOM (error); - return FALSE; - } - if (!dbus_message_append_args (message, DBUS_TYPE_STRING, service_name, 0)) @@ -194,7 +180,7 @@ bus_driver_send_service_acquired (DBusConnection *connection, return FALSE; } - if (!bus_transaction_send_message (transaction, connection, message)) + if (!bus_transaction_send_from_driver (transaction, connection, message)) { dbus_message_unref (message); BUS_SET_OOM (error); @@ -347,13 +333,6 @@ bus_driver_send_welcome_message (DBusConnection *connection, return FALSE; } - if (!dbus_message_set_sender (welcome, DBUS_SERVICE_DBUS)) - { - dbus_message_unref (welcome); - BUS_SET_OOM (error); - return FALSE; - } - if (!dbus_message_append_args (welcome, DBUS_TYPE_STRING, name, NULL)) @@ -363,7 +342,7 @@ bus_driver_send_welcome_message (DBusConnection *connection, return FALSE; } - if (!bus_transaction_send_message (transaction, connection, welcome)) + if (!bus_transaction_send_from_driver (transaction, connection, welcome)) { dbus_message_unref (welcome); BUS_SET_OOM (error); @@ -417,7 +396,7 @@ bus_driver_handle_list_services (DBusConnection *connection, dbus_free_string_array (services); - if (!bus_transaction_send_message (transaction, connection, reply)) + if (!bus_transaction_send_from_driver (transaction, connection, reply)) { dbus_message_unref (reply); BUS_SET_OOM (error); @@ -474,19 +453,13 @@ bus_driver_handle_acquire_service (DBusConnection *connection, goto out; } - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - { - BUS_SET_OOM (error); - goto out; - } - if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID)) { BUS_SET_OOM (error); goto out; } - if (!bus_transaction_send_message (transaction, connection, reply)) + if (!bus_transaction_send_from_driver (transaction, connection, reply)) { BUS_SET_OOM (error); goto out; @@ -534,12 +507,6 @@ bus_driver_handle_service_exists (DBusConnection *connection, BUS_SET_OOM (error); goto out; } - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - { - BUS_SET_OOM (error); - goto out; - } if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service != NULL, @@ -549,7 +516,7 @@ bus_driver_handle_service_exists (DBusConnection *connection, goto out; } - if (!bus_transaction_send_message (transaction, connection, reply)) + if (!bus_transaction_send_from_driver (transaction, connection, reply)) { BUS_SET_OOM (error); goto out; @@ -653,6 +620,12 @@ bus_driver_handle_message (DBusConnection *connection, return FALSE; } + if (dbus_message_get_reply_serial (message) != -1) + { + _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n"); + return TRUE; + } + i = 0; while (i < _DBUS_N_ELEMENTS (message_handlers)) { diff --git a/bus/policy.c b/bus/policy.c index 81894b8..ad0cfae 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -73,7 +73,7 @@ bus_policy_rule_unref (BusPolicyRule *rule) _dbus_assert (rule->refcount > 0); rule->refcount -= 1; - + if (rule->refcount == 0) { switch (rule->type) @@ -90,10 +90,8 @@ bus_policy_rule_unref (BusPolicyRule *rule) dbus_free (rule->d.own.service_name); break; case BUS_POLICY_RULE_USER: - dbus_free (rule->d.user.user); break; case BUS_POLICY_RULE_GROUP: - dbus_free (rule->d.group.group); break; } @@ -239,7 +237,6 @@ bus_policy_create_client_policy (BusPolicy *policy, { BusClientPolicy *client; unsigned long uid; - DBusList **list; _dbus_assert (dbus_connection_get_is_authenticated (connection)); @@ -266,6 +263,8 @@ bus_policy_create_client_policy (BusPolicy *policy, i = 0; while (i < n_groups) { + DBusList **list; + list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid, groups[i]); @@ -282,12 +281,20 @@ bus_policy_create_client_policy (BusPolicy *policy, if (!dbus_connection_get_unix_user (connection, &uid)) goto failed; - list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid, - uid); + if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0) + { + DBusList **list; + + list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid, + uid); + + if (list != NULL) + { + if (!add_list_to_client (list, client)) + goto failed; + } + } - if (!add_list_to_client (list, client)) - goto failed; - if (!add_list_to_client (&policy->mandatory_rules, client)) goto failed; @@ -310,9 +317,6 @@ list_allows_user (dbus_bool_t def, { DBusList *link; dbus_bool_t allowed; - - /* FIXME there's currently no handling of wildcard user/group rules. - */ allowed = def; @@ -324,23 +328,36 @@ list_allows_user (dbus_bool_t def, if (rule->type == BUS_POLICY_RULE_USER) { - if (rule->d.user.uid != uid) + _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n", + list, rule->d.user.uid); + + if (rule->d.user.uid == DBUS_UID_UNSET) + ; /* '*' wildcard */ + else if (rule->d.user.uid != uid) continue; } else if (rule->type == BUS_POLICY_RULE_GROUP) { - int i; - - i = 0; - while (i < n_group_ids) + _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n", + list, rule->d.user.uid); + + if (rule->d.group.gid == DBUS_GID_UNSET) + ; /* '*' wildcard */ + else { - if (rule->d.group.gid == group_ids[i]) - break; - ++i; + int i; + + i = 0; + while (i < n_group_ids) + { + if (rule->d.group.gid == group_ids[i]) + break; + ++i; + } + + if (i == n_group_ids) + continue; } - - if (i == n_group_ids) - continue; } else continue; @@ -360,7 +377,7 @@ bus_policy_allow_user (BusPolicy *policy, int n_group_ids; /* On OOM or error we always reject the user */ - if (!_dbus_get_groups (uid, &group_ids, &n_group_ids)) + if (!_dbus_get_groups (uid, &group_ids, &n_group_ids, NULL)) { _dbus_verbose ("Did not get any groups for UID %lu\n", uid); @@ -381,6 +398,8 @@ bus_policy_allow_user (BusPolicy *policy, dbus_free (group_ids); + _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed); + return allowed; } @@ -536,15 +555,18 @@ remove_rules_by_type_up_to (BusClientPolicy *policy, { DBusList *link; - link = _dbus_list_get_first (&policy->rules); + link = _dbus_list_get_first_link (&policy->rules); while (link != up_to) { BusPolicyRule *rule = link->data; DBusList *next = _dbus_list_get_next_link (&policy->rules, link); - bus_policy_rule_unref (rule); - _dbus_list_remove_link (&policy->rules, link); - + if (rule->type == type) + { + _dbus_list_remove_link (&policy->rules, link); + bus_policy_rule_unref (rule); + } + link = next; } } @@ -571,14 +593,19 @@ bus_client_policy_optimize (BusClientPolicy *policy) _dbus_verbose ("Optimizing policy with %d rules\n", _dbus_list_get_length (&policy->rules)); - link = _dbus_list_get_first (&policy->rules); + link = _dbus_list_get_first_link (&policy->rules); while (link != NULL) { - BusPolicyRule *rule = link->data; - DBusList *next = _dbus_list_get_next_link (&policy->rules, link); + BusPolicyRule *rule; + DBusList *next; dbus_bool_t remove_preceding; + next = _dbus_list_get_next_link (&policy->rules, link); + rule = link->data; + remove_preceding = FALSE; + + _dbus_assert (rule != NULL); switch (rule->type) { @@ -601,7 +628,7 @@ bus_client_policy_optimize (BusClientPolicy *policy) _dbus_assert_not_reached ("invalid rule"); break; } - + if (remove_preceding) remove_rules_by_type_up_to (policy, rule->type, link); @@ -617,6 +644,9 @@ dbus_bool_t bus_client_policy_append_rule (BusClientPolicy *policy, BusPolicyRule *rule) { + _dbus_verbose ("Appending rule %p with type %d to policy %p\n", + rule, rule->type, policy); + if (!_dbus_list_append (&policy->rules, rule)) return FALSE; @@ -639,7 +669,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, */ allowed = FALSE; - link = _dbus_list_get_first (&policy->rules); + link = _dbus_list_get_first_link (&policy->rules); while (link != NULL) { BusPolicyRule *rule = link->data; @@ -711,7 +741,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, */ allowed = FALSE; - link = _dbus_list_get_first (&policy->rules); + link = _dbus_list_get_first_link (&policy->rules); while (link != NULL) { BusPolicyRule *rule = link->data; @@ -783,7 +813,7 @@ bus_client_policy_check_can_own (BusClientPolicy *policy, */ allowed = FALSE; - link = _dbus_list_get_first (&policy->rules); + link = _dbus_list_get_first_link (&policy->rules); while (link != NULL) { BusPolicyRule *rule = link->data; diff --git a/bus/policy.h b/bus/policy.h index 986cfe0..53e30e7 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -74,13 +74,13 @@ struct BusPolicyRule struct { - char *user; + /* can be DBUS_UID_UNSET meaning "any" */ dbus_uid_t uid; } user; struct { - char *group; + /* can be DBUS_GID_UNSET meaning "any" */ dbus_gid_t gid; } group; diff --git a/bus/session.conf.in b/bus/session.conf.in index d430d99..4feca23 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -15,6 +15,7 @@ + +