summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Szyndela <adrian.s@samsung.com>2020-05-20 15:09:21 +0200
committerAdrian Szyndela <adrian.s@samsung.com>2020-06-01 11:59:55 +0200
commit688c714673c9906122e77a7bbaf88544f3247f9a (patch)
treee2042dcb83bb3654edb9aeed6a4a1bd99c15df3d
parent22eb17b827ad3de1b2d53e5ca17675edabf44a75 (diff)
downloaddbus-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.c261
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, &params,
- toggles, log, &result, &privilege, &matched_rule);
+ result = check_policy (policy, check_send_rule, &params,
+ 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, &params,
- toggles, NULL, &result, &privilege, &matched_rule);
+ result = check_policy (policy, check_receive_rule, &params,
+ 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, &params,
- NULL, NULL, &result, &privilege, NULL);
+ result = check_policy (policy, check_own_rule, &params,
+ NULL, NULL, &privilege, NULL);
if (result == BUS_RESULT_LATER)
{