1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* policy.c Bus security policy
4 * Copyright (C) 2003, 2004 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <dbus/dbus-list.h>
31 #include <dbus/dbus-hash.h>
32 #include <dbus/dbus-internals.h>
33 #include <dbus/dbus-message-internal.h>
34 #include <dbus/dbus-connection-internal.h>
36 struct BusClientPolicy
41 unsigned long *groups;
45 dbus_bool_t at_console;
49 bus_policy_rule_new (BusPolicyRuleType type,
50 BusPolicyRuleAccess access)
54 rule = dbus_new0 (BusPolicyRule, 1);
60 rule->access = access;
64 case BUS_POLICY_RULE_USER:
65 rule->d.user.uid = DBUS_UID_UNSET;
67 case BUS_POLICY_RULE_GROUP:
68 rule->d.group.gid = DBUS_GID_UNSET;
70 case BUS_POLICY_RULE_SEND:
71 rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
72 /* allow rules default to TRUE (only requested replies allowed)
73 * check rules default to TRUE (only requested replies are checked)
74 * deny rules default to FALSE (only unrequested replies denied)
76 rule->d.send.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
78 case BUS_POLICY_RULE_RECEIVE:
79 rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
80 /* allow rules default to TRUE (only requested replies allowed)
81 * check rules default to TRUE (only requested replies are checked)
82 * deny rules default to FALSE (only unrequested replies denied)
84 rule->d.receive.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
86 case BUS_POLICY_RULE_OWN:
89 _dbus_assert_not_reached ("invalid rule");
96 bus_policy_rule_ref (BusPolicyRule *rule)
98 _dbus_assert (rule->refcount > 0);
106 bus_policy_rule_unref (BusPolicyRule *rule)
108 _dbus_assert (rule->refcount > 0);
112 if (rule->refcount == 0)
116 case BUS_POLICY_RULE_SEND:
117 dbus_free (rule->d.send.path);
118 dbus_free (rule->d.send.interface);
119 dbus_free (rule->d.send.member);
120 dbus_free (rule->d.send.error);
121 dbus_free (rule->d.send.destination);
123 case BUS_POLICY_RULE_RECEIVE:
124 dbus_free (rule->d.receive.path);
125 dbus_free (rule->d.receive.interface);
126 dbus_free (rule->d.receive.member);
127 dbus_free (rule->d.receive.error);
128 dbus_free (rule->d.receive.origin);
130 case BUS_POLICY_RULE_OWN:
131 dbus_free (rule->d.own.service_name);
133 case BUS_POLICY_RULE_USER:
135 case BUS_POLICY_RULE_GROUP:
138 _dbus_assert_not_reached ("invalid rule");
141 dbus_free (rule->privilege);
150 DBusList *default_rules; /**< Default policy rules */
151 DBusList *mandatory_rules; /**< Mandatory policy rules */
152 DBusHashTable *rules_by_uid; /**< per-UID policy rules */
153 DBusHashTable *rules_by_gid; /**< per-GID policy rules */
154 DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
155 DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
157 DBusHashTable *default_rules_by_name;
158 DBusList *default_prefix_rules;
159 unsigned int n_default_rules;
162 typedef struct BusPolicyRulesWithScore
166 } BusPolicyRulesWithScore;
169 free_rule_func (void *data,
172 BusPolicyRule *rule = data;
174 bus_policy_rule_unref (rule);
178 free_rule_list_func (void *data)
180 DBusList **list = data;
182 if (list == NULL) /* DBusHashTable is on crack */
185 _dbus_list_foreach (list, free_rule_func, NULL);
187 _dbus_list_clear (list);
193 free_rule_list_with_score_func (void *data)
195 BusPolicyRulesWithScore *rules = data;
200 _dbus_list_foreach (&rules->rules, free_rule_func, NULL);
202 _dbus_list_clear (&rules->rules);
208 bus_policy_new (void)
212 policy = dbus_new0 (BusPolicy, 1);
216 policy->refcount = 1;
218 policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
220 free_rule_list_func);
221 if (policy->rules_by_uid == NULL)
224 policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
226 free_rule_list_func);
227 if (policy->rules_by_gid == NULL)
230 policy->default_rules_by_name = _dbus_hash_table_new (DBUS_HASH_STRING,
232 free_rule_list_with_score_func);
233 if (policy->default_rules_by_name == NULL)
239 bus_policy_unref (policy);
244 bus_policy_ref (BusPolicy *policy)
246 _dbus_assert (policy->refcount > 0);
248 policy->refcount += 1;
254 bus_policy_unref (BusPolicy *policy)
256 _dbus_assert (policy->refcount > 0);
258 policy->refcount -= 1;
260 if (policy->refcount == 0)
262 _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
263 _dbus_list_clear (&policy->default_rules);
265 _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
266 _dbus_list_clear (&policy->mandatory_rules);
268 _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
269 _dbus_list_clear (&policy->at_console_true_rules);
271 _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
272 _dbus_list_clear (&policy->at_console_false_rules);
274 if (policy->rules_by_uid)
276 _dbus_hash_table_unref (policy->rules_by_uid);
277 policy->rules_by_uid = NULL;
280 if (policy->rules_by_gid)
282 _dbus_hash_table_unref (policy->rules_by_gid);
283 policy->rules_by_gid = NULL;
286 if (policy->default_rules_by_name)
288 _dbus_hash_table_unref (policy->default_rules_by_name);
289 policy->default_rules_by_name = NULL;
292 _dbus_list_foreach (&policy->default_prefix_rules, free_rule_func, NULL);
293 _dbus_list_clear (&policy->default_prefix_rules);
300 bus_policy_create_client_policy (BusPolicy *policy,
301 DBusConnection *connection,
304 BusClientPolicy *client;
306 _dbus_assert (dbus_connection_get_is_authenticated (connection));
307 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
309 client = bus_client_policy_new ();
313 if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
315 if (!bus_connection_get_unix_groups (connection, &client->groups, &client->n_groups, error))
319 if (dbus_connection_get_unix_user (connection, &client->uid))
321 client->uid_set = TRUE;
322 client->at_console = _dbus_unix_user_is_at_console (client->uid, error);
324 if (dbus_error_is_set (error) == TRUE)
328 client->policy = bus_policy_ref (policy);
335 _DBUS_ASSERT_ERROR_IS_SET (error);
337 bus_client_policy_unref (client);
342 list_allows_user (dbus_bool_t def,
345 const unsigned long *group_ids,
353 link = _dbus_list_get_first_link (list);
356 BusPolicyRule *rule = link->data;
357 link = _dbus_list_get_next_link (list, link);
359 if (rule->type == BUS_POLICY_RULE_USER)
361 _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
362 list, rule->d.user.uid);
364 if (rule->d.user.uid == DBUS_UID_UNSET)
366 else if (rule->d.user.uid != uid)
369 else if (rule->type == BUS_POLICY_RULE_GROUP)
371 _dbus_verbose ("List %p group rule gid="DBUS_GID_FORMAT"\n",
372 list, rule->d.group.gid);
374 if (rule->d.group.gid == DBUS_GID_UNSET)
381 while (i < n_group_ids)
383 if (rule->d.group.gid == group_ids[i])
388 if (i == n_group_ids)
395 /* We don't intend to support <check user="..." /> and <check group="..." />
396 rules. They are treated like deny.
398 allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
405 bus_policy_allow_unix_user (BusPolicy *policy,
409 unsigned long *group_ids;
412 /* On OOM or error we always reject the user */
413 if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
415 _dbus_verbose ("Did not get any groups for UID %lu\n",
420 /* Default to "user owning bus" can connect */
421 allowed = _dbus_unix_user_is_process_owner (uid);
423 allowed = list_allows_user (allowed,
424 &policy->default_rules,
426 group_ids, n_group_ids);
428 allowed = list_allows_user (allowed,
429 &policy->mandatory_rules,
431 group_ids, n_group_ids);
433 dbus_free (group_ids);
435 _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
440 /* For now this is never actually called because the default
441 * DBusConnection behavior of 'same user that owns the bus can
442 * connect' is all it would do. Set the windows user function in
443 * connection.c if the config file ever supports doing something
447 bus_policy_allow_windows_user (BusPolicy *policy,
448 const char *windows_sid)
450 /* Windows has no policies here since only the session bus
451 * is really used for now, so just checking that the
452 * connecting person is the same as the bus owner is fine.
454 return _dbus_windows_user_is_process_owner (windows_sid);
457 static BusPolicyRulesWithScore *
458 get_rules_by_string (DBusHashTable *hash,
461 BusPolicyRulesWithScore *rules;
463 rules = _dbus_hash_table_lookup_string (hash, key);
466 rules = dbus_new0 (BusPolicyRulesWithScore, 1);
470 if (!_dbus_hash_table_insert_string (hash, (char *)key, rules))
481 get_name_from_rule (BusPolicyRule *rule)
483 const char *name = NULL;
484 if (rule->type == BUS_POLICY_RULE_SEND)
485 name = rule->d.send.destination;
486 else if (rule->type == BUS_POLICY_RULE_RECEIVE)
487 name = rule->d.receive.origin;
488 else if (rule->type == BUS_POLICY_RULE_OWN)
489 name = rule->d.own.service_name;
498 is_prefix_rule (BusPolicyRule *rule)
500 if (rule->type == BUS_POLICY_RULE_SEND && rule->d.send.destination_prefix)
502 if (rule->type == BUS_POLICY_RULE_OWN && rule->d.own.prefix)
509 bus_policy_append_default_rule (BusPolicy *policy,
512 if (rule->type == BUS_POLICY_RULE_USER || rule->type == BUS_POLICY_RULE_GROUP)
514 if (!_dbus_list_append (&policy->default_rules, rule))
519 rule->score = ++policy->n_default_rules;
521 if (is_prefix_rule (rule))
523 if (!_dbus_list_append (&policy->default_prefix_rules, rule))
529 BusPolicyRulesWithScore *rules;
531 rules = get_rules_by_string (policy->default_rules_by_name,
532 get_name_from_rule (rule));
537 list = &rules->rules;
539 if (!_dbus_list_prepend (list, rule))
542 rules->score = rule->score;
546 bus_policy_rule_ref (rule);
552 bus_policy_append_mandatory_rule (BusPolicy *policy,
555 if (!_dbus_list_append (&policy->mandatory_rules, rule))
558 bus_policy_rule_ref (rule);
566 get_list (DBusHashTable *hash,
571 list = _dbus_hash_table_lookup_uintptr (hash, key);
575 list = dbus_new0 (DBusList*, 1);
579 if (!_dbus_hash_table_insert_uintptr (hash, key, list))
590 bus_policy_append_user_rule (BusPolicy *policy,
596 list = get_list (policy->rules_by_uid, uid);
601 if (!_dbus_list_append (list, rule))
604 bus_policy_rule_ref (rule);
610 bus_policy_append_group_rule (BusPolicy *policy,
616 list = get_list (policy->rules_by_gid, gid);
621 if (!_dbus_list_append (list, rule))
624 bus_policy_rule_ref (rule);
630 bus_policy_append_console_rule (BusPolicy *policy,
631 dbus_bool_t at_console,
636 if (!_dbus_list_append (&policy->at_console_true_rules, rule))
641 if (!_dbus_list_append (&policy->at_console_false_rules, rule))
645 bus_policy_rule_ref (rule);
652 append_copy_of_policy_list (DBusList **list,
653 DBusList **to_append)
660 /* Preallocate all our links */
661 link = _dbus_list_get_first_link (to_append);
664 if (!_dbus_list_append (&tmp_list, link->data))
666 _dbus_list_clear (&tmp_list);
670 link = _dbus_list_get_next_link (to_append, link);
673 /* Now append them */
674 while ((link = _dbus_list_pop_first_link (&tmp_list)))
676 bus_policy_rule_ref (link->data);
677 _dbus_list_append_link (list, link);
684 merge_id_hash (DBusHashTable *dest,
685 DBusHashTable *to_absorb)
689 _dbus_hash_iter_init (to_absorb, &iter);
690 while (_dbus_hash_iter_next (&iter))
692 unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter);
693 DBusList **list = _dbus_hash_iter_get_value (&iter);
694 DBusList **target = get_list (dest, id);
699 if (!append_copy_of_policy_list (target, list))
707 merge_string_hash (unsigned int *n_rules,
708 unsigned int n_rules_to_absorb,
710 DBusHashTable *to_absorb)
713 #ifndef DBUS_DISABLE_ASSERT
717 _dbus_hash_iter_init (to_absorb, &iter);
718 while (_dbus_hash_iter_next (&iter))
720 const char *id = _dbus_hash_iter_get_string_key (&iter);
721 BusPolicyRulesWithScore *to_absorb_rules =_dbus_hash_iter_get_value (&iter);
722 DBusList **list = &to_absorb_rules->rules;
723 BusPolicyRulesWithScore *target_rules = get_rules_by_string (dest, id);
726 DBusList *target_first_link;
728 if (target_rules == NULL)
731 target = &target_rules->rules;
732 target_first_link = _dbus_list_get_first_link (target);
734 list_iter = _dbus_list_get_first_link (list);
735 while (list_iter != NULL)
738 BusPolicyRule *rule = list_iter->data;
740 rule->score += *n_rules;
741 list_iter = _dbus_list_get_next_link (list, list_iter);
742 #ifndef DBUS_DISABLE_ASSERT
745 new_link = _dbus_list_alloc_link (rule);
746 if (new_link == NULL)
749 bus_policy_rule_ref (rule);
751 _dbus_list_insert_before_link (target, target_first_link, new_link);
754 target_rules->score = to_absorb_rules->score + *n_rules;
757 _dbus_assert (n_rules_to_absorb == cnt_rules);
759 *n_rules += n_rules_to_absorb;
765 bus_policy_merge (BusPolicy *policy,
766 BusPolicy *to_absorb)
768 /* FIXME Not properly atomic, but as used for configuration files we
769 * don't rely on it quite so much.
772 if (!append_copy_of_policy_list (&policy->default_rules,
773 &to_absorb->default_rules))
776 if (!append_copy_of_policy_list (&policy->mandatory_rules,
777 &to_absorb->mandatory_rules))
780 if (!append_copy_of_policy_list (&policy->at_console_true_rules,
781 &to_absorb->at_console_true_rules))
784 if (!append_copy_of_policy_list (&policy->at_console_false_rules,
785 &to_absorb->at_console_false_rules))
788 if (!merge_id_hash (policy->rules_by_uid,
789 to_absorb->rules_by_uid))
792 if (!merge_id_hash (policy->rules_by_gid,
793 to_absorb->rules_by_gid))
796 if (!merge_string_hash (&policy->n_default_rules,
797 to_absorb->n_default_rules,
798 policy->default_rules_by_name,
799 to_absorb->default_rules_by_name))
802 if (!append_copy_of_policy_list (&policy->default_prefix_rules,
803 &to_absorb->default_prefix_rules))
810 bus_client_policy_new (void)
812 BusClientPolicy *policy;
814 policy = dbus_new0 (BusClientPolicy, 1);
818 policy->refcount = 1;
824 bus_client_policy_ref (BusClientPolicy *policy)
826 _dbus_assert (policy->refcount > 0);
828 policy->refcount += 1;
834 bus_client_policy_unref (BusClientPolicy *policy)
836 _dbus_assert (policy->refcount > 0);
838 policy->refcount -= 1;
840 if (policy->refcount == 0)
843 bus_policy_unref (policy->policy);
845 dbus_free (policy->groups);
851 #define _dbus_string_append_printf_err_check(str, fmt, args...) \
852 if (!_dbus_string_append_printf(str, fmt, ##args)) \
854 _dbus_string_free (str); \
859 bus_policy_rule_to_string (BusPolicyRule *rule,
865 const char *msg_type[] = {"Invalid", "method_call", "method_return", "signal", "error"};
870 switch (rule->access)
872 case BUS_POLICY_RULE_ACCESS_ALLOW:
875 case BUS_POLICY_RULE_ACCESS_DENY:
878 case BUS_POLICY_RULE_ACCESS_CHECK:
882 _dbus_assert_not_reached ("invalid rule access value");
885 if (rule->type == BUS_POLICY_RULE_SEND)
888 dest = "destination";
890 else if (rule->type == BUS_POLICY_RULE_RECEIVE)
898 /* generate xml format */
899 if (!_dbus_string_init (&str))
902 _dbus_string_append_printf_err_check (&str, "<%s ", access);
904 if (rule->d.send.destination_prefix)
906 _dbus_string_append_printf_err_check (&str, "%s_destination_prefix=\"%s\" ", sr, rule->d.send.destination);
908 else if (rule->d.send.destination)
910 _dbus_string_append_printf_err_check (&str, "%s_%s=\"%s\" ", sr, dest, rule->d.send.destination);
913 if (rule->d.send.path)
914 _dbus_string_append_printf_err_check (&str, "%s_path=\"%s\" ", sr, rule->d.send.path);
915 if (rule->d.send.interface)
916 _dbus_string_append_printf_err_check (&str, "%s_interface=\"%s\" ", sr, rule->d.send.interface);
917 if (rule->d.send.member)
918 _dbus_string_append_printf_err_check (&str, "%s_member=\"%s\" ", sr, rule->d.send.member);
919 if (rule->d.send.message_type)
920 _dbus_string_append_printf_err_check (&str, "%s_type=\"%s\" ", sr, msg_type[rule->d.send.message_type]);
922 _dbus_string_append_printf_err_check (&str, "privilege=\"%s\" ", rule->privilege);
924 if (!_dbus_string_append (&str, "/>"))
926 _dbus_string_free (&str);
930 if (!_dbus_string_steal_data (&str, out_rule))
933 _dbus_string_free (&str);
937 _dbus_string_free (&str);
942 typedef struct RuleParams {
943 enum {PARAM_SR, PARAM_OWN} type;
946 BusRegistry *registry;
947 dbus_bool_t requested_reply;
948 DBusConnection *peer;
950 DBusMessage *message;
951 dbus_bool_t eavesdropping;
953 const DBusString *name;
957 typedef dbus_bool_t (*CheckRuleFunc) (const BusPolicyRule *,
963 check_send_rule (const BusPolicyRule *rule,
964 const RuleParams *match_params,
966 const char **privilege)
968 /* Rule is skipped if it specifies a different
969 * message name from the message, or a different
970 * destination from the message
972 if (rule->type != BUS_POLICY_RULE_SEND)
974 _dbus_verbose (" (policy) skipping non-send rule\n");
978 if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
980 if (dbus_message_get_type (match_params->u.sr.message) != rule->d.send.message_type)
982 _dbus_verbose (" (policy) skipping rule for different message type\n");
987 /* If it's a reply, the requested_reply flag kicks in */
988 if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
990 /* for allow or check requested_reply=true means the rule applies
991 * only when reply was requested. requested_reply=false means the
992 * rule always applies
994 if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
996 _dbus_verbose (" (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
997 rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
1001 /* for deny, requested_reply=false means the rule applies only
1002 * when the reply was not requested. requested_reply=true means the
1003 * rule always applies.
1005 if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.send.requested_reply)
1007 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
1012 if (rule->d.send.path != NULL)
1014 if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
1015 strcmp (dbus_message_get_path (match_params->u.sr.message),
1016 rule->d.send.path) != 0)
1018 _dbus_verbose (" (policy) skipping rule for different path\n");
1023 if (rule->d.send.interface != NULL)
1025 /* The interface is optional in messages. For allow rules, if the message
1026 * has no interface we want to skip the rule (and thus not allow);
1027 * for deny rules, if the message has no interface we want to use the
1028 * rule (and thus deny). Check rules are meant to be used like allow
1029 * rules (they can grant access, but not remove it), so we treat it like
1032 dbus_bool_t no_interface;
1034 no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1036 if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1038 strcmp (dbus_message_get_interface (match_params->u.sr.message),
1039 rule->d.send.interface) != 0))
1041 _dbus_verbose (" (policy) skipping rule for different interface\n");
1046 if (rule->d.send.member != NULL)
1048 if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1049 strcmp (dbus_message_get_member (match_params->u.sr.message),
1050 rule->d.send.member) != 0)
1052 _dbus_verbose (" (policy) skipping rule for different member\n");
1057 if (rule->d.send.error != NULL)
1059 if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1060 strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1061 rule->d.send.error) != 0)
1063 _dbus_verbose (" (policy) skipping rule for different error name\n");
1068 if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
1070 if (dbus_message_get_destination (match_params->u.sr.message) == NULL &&
1071 dbus_message_get_type (match_params->u.sr.message) == DBUS_MESSAGE_TYPE_SIGNAL)
1073 /* it's a broadcast */
1074 if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
1076 _dbus_verbose (" (policy) skipping rule because message is a broadcast\n");
1080 /* else it isn't a broadcast: there is some destination */
1081 else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
1083 _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n");
1088 if (rule->d.send.destination != NULL)
1090 if (!rule->d.send.destination_prefix)
1092 /* receiver can be NULL for messages that are sent to the
1093 * message bus itself, we check the strings in that case as
1094 * built-in services don't have a DBusConnection but messages
1095 * to them have a destination service name.
1097 * Similarly, receiver can be NULL when we're deciding whether
1098 * activation should be allowed; we make the authorization decision
1099 * on the assumption that the activated service will have the
1100 * requested name and no others.
1102 if (match_params->u.sr.peer == NULL)
1104 if (!dbus_message_has_destination (match_params->u.sr.message,
1105 rule->d.send.destination))
1107 _dbus_verbose (" (policy) skipping rule because message dest is not %s\n",
1108 rule->d.send.destination);
1115 BusService *service;
1117 _dbus_string_init_const (&str, rule->d.send.destination);
1119 service = bus_registry_lookup (match_params->u.sr.registry, &str);
1120 if (service == NULL)
1122 _dbus_verbose (" (policy) skipping rule because dest %s doesn't exist\n",
1123 rule->d.send.destination);
1127 if (!bus_service_has_owner (service, match_params->u.sr.peer))
1129 _dbus_verbose (" (policy) skipping rule because dest %s isn't owned by receiver\n",
1130 rule->d.send.destination);
1135 else if (rule->d.send.destination_prefix)
1137 /* receiver can be NULL - the same as in !send.destination_prefix */
1138 if (match_params->u.sr.peer == NULL)
1140 const char *destination = dbus_message_get_destination (match_params->u.sr.message);
1141 DBusString dest_name;
1143 if (destination == NULL)
1145 _dbus_verbose (" (policy) skipping rule because message has no dest\n");
1149 _dbus_string_init_const (&dest_name, destination);
1151 if (!_dbus_string_starts_with_words_c_str (&dest_name,
1152 rule->d.send.destination,
1155 _dbus_verbose (" (policy) skipping rule because message dest doesn't start with %s\n",
1156 rule->d.send.destination);
1162 if (!bus_connection_is_service_owner_by_prefix (match_params->u.sr.peer,
1163 rule->d.send.destination))
1165 _dbus_verbose (" (policy) skipping rule because no dest with prefix %s is owned by receiver\n",
1166 rule->d.send.destination);
1173 if (rule->d.send.min_fds > 0 ||
1174 rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1176 unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1178 if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
1180 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1181 "and that is outside range [%u,%u]",
1182 n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
1188 switch (rule->access)
1190 case BUS_POLICY_RULE_ACCESS_ALLOW:
1191 *result = BUS_RESULT_TRUE;
1193 case BUS_POLICY_RULE_ACCESS_DENY:
1194 *result = BUS_RESULT_FALSE;
1196 case BUS_POLICY_RULE_ACCESS_CHECK:
1197 *result = BUS_RESULT_LATER;
1198 *privilege = rule->privilege;
1201 _dbus_assert_not_reached ("invalid rule access value");
1208 check_rules_list (const DBusList *rules,
1209 CheckRuleFunc check_func,
1210 const RuleParams *params,
1211 dbus_int32_t *toggles,
1214 const char **privilege,
1215 BusPolicyRule **matched_rule,
1216 dbus_bool_t break_on_first_match)
1218 const DBusList *link;
1220 link = _dbus_list_get_first_link ((DBusList **)&rules);
1221 while (link != NULL)
1223 const BusPolicyRule *rule = link->data;
1225 link = _dbus_list_get_next_link ((DBusList **)&rules, link);
1227 if (check_func (rule, params, result, privilege))
1230 *log = rule->d.send.log;
1234 *matched_rule = (BusPolicyRule *)rule;
1236 _dbus_verbose (" (policy) used rule, result now = %d\n",
1239 if (break_on_first_match)
1246 check_rules_list_with_score (DBusList *rules,
1248 CheckRuleFunc check_func,
1249 const RuleParams *params,
1250 dbus_int32_t *toggles,
1253 const char **privilege,
1254 BusPolicyRule **matched_rule,
1255 dbus_bool_t break_on_first_match)
1257 dbus_int32_t local_toggles;
1258 dbus_bool_t local_log;
1259 BusResult local_result;
1260 const char *local_privilege;
1261 BusPolicyRule *local_matched_rule;
1265 check_rules_list (rules, check_func, params,
1266 &local_toggles, &local_log, &local_result, &local_privilege,
1267 &local_matched_rule, break_on_first_match);
1269 if (local_toggles > 0)
1271 _dbus_assert (local_matched_rule != NULL);
1273 if (local_matched_rule->score > score)
1276 *toggles += local_toggles;
1279 *result = local_result;
1280 *privilege = local_privilege;
1282 *matched_rule = local_matched_rule;
1283 return local_matched_rule->score;
1291 check_rules_for_name (DBusHashTable *rules,
1294 CheckRuleFunc check_func,
1296 dbus_int32_t *toggles,
1299 const char **privilege,
1300 BusPolicyRule **matched_rule)
1302 const BusPolicyRulesWithScore *rules_list;
1304 rules_list = _dbus_hash_table_lookup_string (rules, name);
1306 if (rules_list == NULL || rules_list->score <= score)
1309 return check_rules_list_with_score (rules_list->rules, score, check_func, params, toggles, log, result, privilege, matched_rule, TRUE);
1313 find_and_check_rules_for_name (DBusHashTable *rules,
1314 DBusList *prefix_rules,
1317 CheckRuleFunc check_func,
1319 dbus_int32_t *toggles,
1322 const char **privilege,
1323 BusPolicyRule **matched_rule)
1325 score = check_rules_for_name (rules, c_str,
1326 score, check_func, params,
1331 score = check_rules_list_with_score (prefix_rules,
1332 score, check_func, params,
1335 matched_rule, FALSE);
1341 find_and_check_rules (DBusHashTable *rules,
1342 DBusList *prefix_rules,
1343 CheckRuleFunc check_func,
1345 dbus_int32_t *toggles,
1348 const char **privilege,
1349 BusPolicyRule **matched_rule)
1351 const RuleParams *p = params;
1352 const DBusList *services = NULL;
1355 if (p->type == PARAM_SR)
1357 if (p->u.sr.peer != NULL)
1361 services = bus_connection_get_owned_services_list (p->u.sr.peer);
1363 link = _dbus_list_get_first_link ((DBusList **)&services);
1364 while (link != NULL)
1366 const char *name = bus_service_get_name (link->data);
1368 link = _dbus_list_get_next_link ((DBusList **)&services, link);
1370 /* skip unique id names */
1374 score = find_and_check_rules_for_name (rules, prefix_rules, name, score,
1376 toggles, log, result,
1377 privilege, matched_rule);
1380 else if (p->u.sr.name != NULL)
1382 score = find_and_check_rules_for_name (rules, prefix_rules, p->u.sr.name, score,
1384 toggles, log, result,
1385 privilege, matched_rule);
1389 score = find_and_check_rules_for_name (rules, prefix_rules, _dbus_string_get_const_data(p->u.name),
1390 score, check_func, params,
1391 toggles, log, result,
1392 privilege, matched_rule);
1394 /* check also wildcard rules */
1395 score = check_rules_for_name (rules, "", score, check_func, params,
1396 toggles, log, result, privilege, matched_rule);
1400 check_policy (BusClientPolicy *policy,
1401 CheckRuleFunc check_func,
1403 dbus_int32_t *toggles,
1405 const char **privilege,
1406 BusPolicyRule **matched_rule)
1408 BusResult result = BUS_RESULT_FALSE;
1413 find_and_check_rules (policy->policy->default_rules_by_name,
1414 policy->policy->default_prefix_rules,
1416 toggles, log, &result, privilege, matched_rule);
1418 /* we avoid the overhead of looking up user's groups
1419 * if we don't have any group rules anyway
1421 if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_gid) > 0)
1425 for (i = 0; i < policy->n_groups; ++i)
1427 const DBusList **list;
1429 list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_gid,
1433 check_rules_list (*list, check_func, params,
1434 toggles, log, &result, privilege, matched_rule, FALSE);
1438 if (policy->uid_set)
1440 if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_uid) > 0)
1442 const DBusList **list;
1444 list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_uid,
1448 check_rules_list (*list, check_func, params,
1449 toggles, log, &result, privilege, matched_rule, FALSE);
1451 if (policy->at_console)
1452 check_rules_list (policy->policy->at_console_true_rules, check_func,
1453 params, toggles, log, &result, privilege, matched_rule, FALSE);
1455 check_rules_list (policy->policy->at_console_false_rules, check_func,
1456 params, toggles, log, &result, privilege, matched_rule, FALSE);
1460 check_rules_list (policy->policy->mandatory_rules, check_func, params,
1461 toggles, log, &result, privilege, matched_rule, FALSE);
1467 bus_client_policy_check_can_send (DBusConnection *sender,
1468 BusClientPolicy *policy,
1469 BusRegistry *registry,
1470 dbus_bool_t requested_reply,
1471 DBusConnection *addressed_recipient,
1472 DBusConnection *receiver,
1473 DBusMessage *message,
1474 dbus_int32_t *toggles,
1476 const char **privilege_param,
1477 BusDeferredMessage **deferred_message,
1481 const char *privilege;
1482 BusPolicyRule *matched_rule = NULL;
1483 struct RuleParams params;
1485 params.type = PARAM_SR;
1486 params.u.sr.registry = registry;
1487 params.u.sr.requested_reply = requested_reply;
1488 params.u.sr.peer = receiver;
1489 params.u.sr.message = message;
1490 params.u.sr.name = dbus_message_get_destination (message);
1492 _dbus_verbose (" (policy) checking send rules\n");
1494 result = check_policy (policy, check_send_rule, ¶ms,
1495 toggles, log, &privilege, &matched_rule);
1497 if (result == BUS_RESULT_LATER)
1499 BusContext *context = bus_connection_get_context(sender);
1500 BusCheck *check = bus_context_get_check(context);
1502 result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
1503 privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
1504 if (result == BUS_RESULT_LATER && deferred_message != NULL)
1505 bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1506 *toggles, privilege);
1511 if (privilege_param != NULL)
1512 *privilege_param = privilege;
1514 if (result == BUS_RESULT_FALSE)
1516 if (matched_rule && out_rule)
1517 bus_policy_rule_to_string (matched_rule, out_rule);
1524 check_receive_rule (const BusPolicyRule *rule,
1525 const RuleParams *match_params,
1527 const char **privilege)
1529 if (rule->type != BUS_POLICY_RULE_RECEIVE)
1531 _dbus_verbose (" (policy) skipping non-receive rule\n");
1535 if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
1537 if (dbus_message_get_type (match_params->u.sr.message) != rule->d.receive.message_type)
1539 _dbus_verbose (" (policy) skipping rule for different message type\n");
1545 /* for allow or check, eavesdrop=false means the rule doesn't apply when
1546 * eavesdropping. eavesdrop=true means the rule always applies
1548 if (match_params->u.sr.eavesdropping && rule->access != BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.eavesdrop)
1550 _dbus_verbose (" (policy) skipping %s rule since it doesn't apply to eavesdropping\n",
1551 rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
1555 /* for deny, eavesdrop=true means the rule applies only when
1556 * eavesdropping; eavesdrop=false means always deny.
1558 if (!match_params->u.sr.eavesdropping && rule->access == BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.eavesdrop)
1560 _dbus_verbose (" (policy) skipping deny rule since it only applies to eavesdropping\n");
1564 /* If it's a reply, the requested_reply flag kicks in */
1565 if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
1567 /* for allow or check requested_reply=true means the rule applies
1568 * only when reply was requested. requested_reply=false means the
1569 * rule always applies
1571 if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop)
1573 _dbus_verbose (" (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
1574 rule->access == BUS_POLICY_RULE_ACCESS_DENY ? "allow" : "deny");
1578 /* for deny, requested_reply=false means the rule applies only
1579 * when the reply was not requested. requested_reply=true means the
1580 * rule always applies.
1582 if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.requested_reply)
1584 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
1589 if (rule->d.receive.path != NULL)
1591 if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
1592 strcmp (dbus_message_get_path (match_params->u.sr.message),
1593 rule->d.receive.path) != 0)
1595 _dbus_verbose (" (policy) skipping rule for different path\n");
1600 if (rule->d.receive.interface != NULL)
1602 /* The interface is optional in messages. For allow rules, if the message
1603 * has no interface we want to skip the rule (and thus not allow);
1604 * for deny rules, if the message has no interface we want to use the
1605 * rule (and thus deny). Check rules are treated like allow rules.
1607 dbus_bool_t no_interface;
1609 no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1611 if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1613 strcmp (dbus_message_get_interface (match_params->u.sr.message),
1614 rule->d.receive.interface) != 0))
1616 _dbus_verbose (" (policy) skipping rule for different interface\n");
1621 if (rule->d.receive.member != NULL)
1623 if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1624 strcmp (dbus_message_get_member (match_params->u.sr.message),
1625 rule->d.receive.member) != 0)
1627 _dbus_verbose (" (policy) skipping rule for different member\n");
1632 if (rule->d.receive.error != NULL)
1634 if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1635 strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1636 rule->d.receive.error) != 0)
1638 _dbus_verbose (" (policy) skipping rule for different error name\n");
1643 if (rule->d.receive.origin != NULL)
1645 /* sender can be NULL for messages that originate from the
1646 * message bus itself, we check the strings in that case as
1647 * built-in services don't have a DBusConnection but will
1648 * still set the sender on their messages.
1650 if (match_params->u.sr.peer == NULL)
1652 if (!dbus_message_has_sender (match_params->u.sr.message,
1653 rule->d.receive.origin))
1655 _dbus_verbose (" (policy) skipping rule because message sender is not %s\n",
1656 rule->d.receive.origin);
1662 BusService *service;
1665 _dbus_string_init_const (&str, rule->d.receive.origin);
1667 service = bus_registry_lookup (match_params->u.sr.registry, &str);
1669 if (service == NULL)
1671 _dbus_verbose (" (policy) skipping rule because origin %s doesn't exist\n",
1672 rule->d.receive.origin);
1676 if (!bus_service_has_owner (service, match_params->u.sr.peer))
1678 _dbus_verbose (" (policy) skipping rule because origin %s isn't owned by sender\n",
1679 rule->d.receive.origin);
1685 if (rule->d.receive.min_fds > 0 ||
1686 rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1688 unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1690 if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
1692 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1693 "and that is outside range [%u,%u]",
1694 n_fds, rule->d.receive.min_fds,
1695 rule->d.receive.max_fds);
1701 switch (rule->access)
1703 case BUS_POLICY_RULE_ACCESS_ALLOW:
1704 *result = BUS_RESULT_TRUE;
1706 case BUS_POLICY_RULE_ACCESS_DENY:
1707 *result = BUS_RESULT_FALSE;
1709 case BUS_POLICY_RULE_ACCESS_CHECK:
1710 *result = BUS_RESULT_LATER;
1711 *privilege = rule->privilege;
1714 _dbus_assert_not_reached ("invalid rule access value");
1720 /* See docs on what the args mean on bus_context_check_security_policy()
1724 bus_client_policy_check_can_receive (BusClientPolicy *policy,
1725 BusRegistry *registry,
1726 dbus_bool_t requested_reply,
1727 DBusConnection *sender,
1728 DBusConnection *addressed_recipient,
1729 DBusConnection *proposed_recipient,
1730 DBusMessage *message,
1731 dbus_int32_t *toggles,
1732 const char **privilege_param,
1733 BusDeferredMessage **deferred_message,
1737 const char *privilege;
1738 BusPolicyRule *matched_rule = NULL;
1739 struct RuleParams params;
1741 params.type = PARAM_SR;
1742 params.u.sr.registry = registry;
1743 params.u.sr.requested_reply = requested_reply;
1744 params.u.sr.peer = sender;
1745 params.u.sr.message = message;
1746 params.u.sr.eavesdropping =
1747 addressed_recipient != proposed_recipient &&
1748 dbus_message_get_destination (message) != NULL;
1749 params.u.sr.name = dbus_message_get_sender (message);
1751 _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", params.u.sr.eavesdropping);
1753 result = check_policy (policy, check_receive_rule, ¶ms,
1754 toggles, NULL, &privilege, &matched_rule);
1756 if (result == BUS_RESULT_LATER)
1758 BusContext *context = bus_connection_get_context(proposed_recipient);
1759 BusCheck *check = bus_context_get_check(context);
1761 result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
1762 privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
1763 if (result == BUS_RESULT_LATER && deferred_message != NULL)
1764 bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1765 *toggles, privilege);
1770 if (privilege_param != NULL)
1771 *privilege_param = privilege;
1773 if (result == BUS_RESULT_FALSE)
1775 if (matched_rule && out_rule)
1776 bus_policy_rule_to_string (matched_rule, out_rule);
1783 check_own_rule (const BusPolicyRule *rule,
1784 const RuleParams *params,
1786 const char **privilege)
1788 const DBusString *service_name = params->u.name;
1790 /* Rule is skipped if it specifies a different service name from
1794 if (rule->type != BUS_POLICY_RULE_OWN)
1797 if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
1799 if (!_dbus_string_equal_c_str (service_name,
1800 rule->d.own.service_name))
1803 else if (rule->d.own.prefix)
1805 if (!_dbus_string_starts_with_words_c_str (service_name,
1806 rule->d.own.service_name,
1812 switch (rule->access)
1814 case BUS_POLICY_RULE_ACCESS_ALLOW:
1815 *result = BUS_RESULT_TRUE;
1817 case BUS_POLICY_RULE_ACCESS_DENY:
1818 *result = BUS_RESULT_FALSE;
1820 case BUS_POLICY_RULE_ACCESS_CHECK:
1821 *result = BUS_RESULT_LATER;
1822 *privilege = rule->privilege;
1825 _dbus_assert_not_reached ("invalid rule access value");
1832 bus_client_policy_check_can_own (BusClientPolicy *policy,
1833 const DBusString *service_name,
1834 DBusConnection *connection,
1835 DBusMessage *message)
1838 const char *privilege;
1841 params.type = PARAM_OWN;
1842 params.u.name = service_name;
1844 result = check_policy (policy, check_own_rule, ¶ms,
1845 NULL, NULL, &privilege, NULL);
1847 if (result == BUS_RESULT_LATER)
1849 BusContext *context = bus_connection_get_context(connection);
1850 BusCheck *check = bus_context_get_check(context);
1851 BusDeferredMessage *deferred_message = NULL;
1853 result = bus_check_privilege(check, message, connection, NULL, NULL,
1854 privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message);
1855 if (result == BUS_RESULT_LATER)
1857 bus_deferred_message_disable_sender(deferred_message);
1864 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1866 bus_policy_check_can_own (BusPolicy *policy,
1867 const DBusString *service_name)
1869 return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL);
1871 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */