diff options
author | Adrian Szyndela <adrian.s@samsung.com> | 2020-05-20 15:09:21 +0200 |
---|---|---|
committer | Adrian Szyndela <adrian.s@samsung.com> | 2020-06-01 11:59:55 +0200 |
commit | 688c714673c9906122e77a7bbaf88544f3247f9a (patch) | |
tree | e2042dcb83bb3654edb9aeed6a4a1bd99c15df3d | |
parent | 22eb17b827ad3de1b2d53e5ca17675edabf44a75 (diff) | |
download | dbus-688c714673c9906122e77a7bbaf88544f3247f9a.tar.gz dbus-688c714673c9906122e77a7bbaf88544f3247f9a.tar.bz2 dbus-688c714673c9906122e77a7bbaf88544f3247f9a.zip |
bus/policy: direct checking of policy, without copies
Change-Id: I42926c107aae0be1a1247a61f3558122b07f9914
-rw-r--r-- | bus/policy.c | 261 |
1 files changed, 95 insertions, 166 deletions
diff --git a/bus/policy.c b/bus/policy.c index 272adcfb..45477b95 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -32,8 +32,17 @@ #include <dbus/dbus-internals.h> #include <dbus/dbus-message-internal.h> -static dbus_bool_t bus_client_policy_append_rule (BusClientPolicy *policy, - BusPolicyRule *rule); +struct BusClientPolicy +{ + int refcount; + + BusPolicy *policy; + unsigned long *groups; + int n_groups; + dbus_uid_t uid; + dbus_bool_t uid_set; + dbus_bool_t at_console; +}; BusPolicyRule* bus_policy_rule_new (BusPolicyRuleType type, @@ -246,49 +255,12 @@ bus_policy_unref (BusPolicy *policy) } } -static dbus_bool_t -add_list_to_client (DBusList **list, - BusClientPolicy *client) -{ - DBusList *link; - - link = _dbus_list_get_first_link (list); - while (link != NULL) - { - BusPolicyRule *rule = link->data; - link = _dbus_list_get_next_link (list, link); - - switch (rule->type) - { - case BUS_POLICY_RULE_USER: - case BUS_POLICY_RULE_GROUP: - /* These aren't per-connection policies */ - break; - - case BUS_POLICY_RULE_OWN: - case BUS_POLICY_RULE_SEND: - case BUS_POLICY_RULE_RECEIVE: - /* These are per-connection */ - if (!bus_client_policy_append_rule (client, rule)) - return FALSE; - break; - - default: - _dbus_assert_not_reached ("invalid rule"); - } - } - - return TRUE; -} - BusClientPolicy* bus_policy_create_client_policy (BusPolicy *policy, DBusConnection *connection, DBusError *error) { BusClientPolicy *client; - dbus_uid_t uid; - dbus_bool_t at_console; _dbus_assert (dbus_connection_get_is_authenticated (connection)); _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -297,82 +269,22 @@ bus_policy_create_client_policy (BusPolicy *policy, if (client == NULL) goto nomem; - if (!add_list_to_client (&policy->default_rules, - client)) - goto nomem; - - /* we avoid the overhead of looking up user's groups - * if we don't have any group rules anyway - */ if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0) { - unsigned long *groups; - int n_groups; - int i; - - if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error)) + if (!bus_connection_get_unix_groups (connection, &client->groups, &client->n_groups, error)) goto failed; - - i = 0; - while (i < n_groups) - { - DBusList **list; - - list = _dbus_hash_table_lookup_uintptr (policy->rules_by_gid, - groups[i]); - - if (list != NULL) - { - if (!add_list_to_client (list, client)) - { - dbus_free (groups); - goto nomem; - } - } - - ++i; - } - - dbus_free (groups); } - if (dbus_connection_get_unix_user (connection, &uid)) + if (dbus_connection_get_unix_user (connection, &client->uid)) { - if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0) - { - DBusList **list; - - list = _dbus_hash_table_lookup_uintptr (policy->rules_by_uid, - uid); - - if (list != NULL) - { - if (!add_list_to_client (list, client)) - goto nomem; - } - } - - /* Add console rules */ - at_console = _dbus_unix_user_is_at_console (uid, error); + client->uid_set = TRUE; + client->at_console = _dbus_unix_user_is_at_console (client->uid, error); - if (at_console) - { - if (!add_list_to_client (&policy->at_console_true_rules, client)) - goto nomem; - } - else if (dbus_error_is_set (error) == TRUE) - { + if (dbus_error_is_set (error) == TRUE) goto failed; - } - else if (!add_list_to_client (&policy->at_console_false_rules, client)) - { - goto nomem; - } } - if (!add_list_to_client (&policy->mandatory_rules, - client)) - goto nomem; + client->policy = bus_policy_ref (policy); return client; @@ -703,13 +615,6 @@ bus_policy_merge (BusPolicy *policy, return TRUE; } -struct BusClientPolicy -{ - int refcount; - - DBusList *rules; -}; - BusClientPolicy* bus_client_policy_new (void) { @@ -734,15 +639,6 @@ bus_client_policy_ref (BusClientPolicy *policy) return policy; } -static void -rule_unref_foreach (void *data, - void *user_data) -{ - BusPolicyRule *rule = data; - - bus_policy_rule_unref (rule); -} - void bus_client_policy_unref (BusClientPolicy *policy) { @@ -752,31 +648,15 @@ bus_client_policy_unref (BusClientPolicy *policy) if (policy->refcount == 0) { - _dbus_list_foreach (&policy->rules, - rule_unref_foreach, - NULL); + if (policy->policy) + bus_policy_unref (policy->policy); - _dbus_list_clear (&policy->rules); + dbus_free (policy->groups); dbus_free (policy); } } -static 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; - - bus_policy_rule_ref (rule); - - return TRUE; -} - #define _dbus_string_append_printf_err_check(str, fmt, args...) \ if (!_dbus_string_append_printf(str, fmt, ##args)) \ { \ @@ -1166,6 +1046,75 @@ check_rules_list (const DBusList *rules, } } +static BusResult +check_policy (BusClientPolicy *policy, + CheckRuleFunc check_func, + const void *params, + dbus_int32_t *toggles, + dbus_bool_t *log, + const char **privilege, + BusPolicyRule **matched_rule) +{ + BusResult result = BUS_RESULT_FALSE; + + if (toggles) + *toggles = 0; + + /* checking is in the order the rules appeared + * in the config file, i.e. last rule that applies wins + */ + + check_rules_list (policy->policy->default_rules, check_func, params, + toggles, log, &result, privilege, matched_rule); + + /* we avoid the overhead of looking up user's groups + * if we don't have any group rules anyway + */ + if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_gid) > 0) + { + int i; + + for (i = 0; i < policy->n_groups; ++i) + { + const DBusList **list; + + list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_gid, + policy->groups[i]); + + if (list != NULL) + check_rules_list (*list, check_func, params, + toggles, log, &result, privilege, matched_rule); + } + } + + if (policy->uid_set) + { + if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_uid) > 0) + { + const DBusList **list; + + list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_uid, + policy->uid); + + if (list != NULL) + check_rules_list (*list, check_func, params, + toggles, log, &result, privilege, matched_rule); + + if (policy->at_console) + check_rules_list (policy->policy->at_console_true_rules, check_func, + params, toggles, log, &result, privilege, matched_rule); + else + check_rules_list (policy->policy->at_console_false_rules, check_func, + params, toggles, log, &result, privilege, matched_rule); + } + } + + check_rules_list (policy->policy->mandatory_rules, check_func, params, + toggles, log, &result, privilege, matched_rule); + + return result; +} + BusResult bus_client_policy_check_can_send (DBusConnection *sender, BusClientPolicy *policy, @@ -1191,17 +1140,10 @@ bus_client_policy_check_can_send (DBusConnection *sender, params.u.sr.peer = receiver; params.u.sr.message = message; - /* policy->rules is in the order the rules appeared - * in the config file, i.e. last rule that applies wins - */ - _dbus_verbose (" (policy) checking send rules\n"); - *toggles = 0; - - result = BUS_RESULT_FALSE; - check_rules_list (policy->rules, check_send_rule, ¶ms, - toggles, log, &result, &privilege, &matched_rule); + result = check_policy (policy, check_send_rule, ¶ms, + toggles, log, &privilege, &matched_rule); if (result == BUS_RESULT_LATER) { @@ -1456,17 +1398,10 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, addressed_recipient != proposed_recipient && dbus_message_get_destination (message) != NULL; - /* policy->rules is in the order the rules appeared - * in the config file, i.e. last rule that applies wins - */ - _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping); - *toggles = 0; - - result = BUS_RESULT_FALSE; - check_rules_list (policy->rules, check_receive_rule, ¶ms, - toggles, NULL, &result, &privilege, &matched_rule); + result = check_policy (policy, check_receive_rule, ¶ms, + toggles, NULL, &privilege, &matched_rule); if (result == BUS_RESULT_LATER) { @@ -1556,14 +1491,8 @@ bus_client_policy_check_can_own (BusClientPolicy *policy, params.type = PARAM_OWN; params.u.name = service_name; - /* policy->rules is in the order the rules appeared - * in the config file, i.e. last rule that applies wins - */ - - result = BUS_RESULT_FALSE; - - check_rules_list (policy->rules, check_own_rule, ¶ms, - NULL, NULL, &result, &privilege, NULL); + result = check_policy (policy, check_own_rule, ¶ms, + NULL, NULL, &privilege, NULL); if (result == BUS_RESULT_LATER) { |