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 unsigned int n_default_rules;
161 typedef struct BusPolicyRulesWithScore
165 } BusPolicyRulesWithScore;
168 free_rule_func (void *data,
171 BusPolicyRule *rule = data;
173 bus_policy_rule_unref (rule);
177 free_rule_list_func (void *data)
179 DBusList **list = data;
181 if (list == NULL) /* DBusHashTable is on crack */
184 _dbus_list_foreach (list, free_rule_func, NULL);
186 _dbus_list_clear (list);
192 free_rule_list_with_score_func (void *data)
194 BusPolicyRulesWithScore *rules = data;
199 _dbus_list_foreach (&rules->rules, free_rule_func, NULL);
201 _dbus_list_clear (&rules->rules);
207 bus_policy_new (void)
211 policy = dbus_new0 (BusPolicy, 1);
215 policy->refcount = 1;
217 policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
219 free_rule_list_func);
220 if (policy->rules_by_uid == NULL)
223 policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
225 free_rule_list_func);
226 if (policy->rules_by_gid == NULL)
229 policy->default_rules_by_name = _dbus_hash_table_new (DBUS_HASH_STRING,
231 free_rule_list_with_score_func);
232 if (policy->default_rules_by_name == NULL)
238 bus_policy_unref (policy);
243 bus_policy_ref (BusPolicy *policy)
245 _dbus_assert (policy->refcount > 0);
247 policy->refcount += 1;
253 bus_policy_unref (BusPolicy *policy)
255 _dbus_assert (policy->refcount > 0);
257 policy->refcount -= 1;
259 if (policy->refcount == 0)
261 _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
262 _dbus_list_clear (&policy->default_rules);
264 _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
265 _dbus_list_clear (&policy->mandatory_rules);
267 _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
268 _dbus_list_clear (&policy->at_console_true_rules);
270 _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
271 _dbus_list_clear (&policy->at_console_false_rules);
273 if (policy->rules_by_uid)
275 _dbus_hash_table_unref (policy->rules_by_uid);
276 policy->rules_by_uid = NULL;
279 if (policy->rules_by_gid)
281 _dbus_hash_table_unref (policy->rules_by_gid);
282 policy->rules_by_gid = NULL;
285 if (policy->default_rules_by_name)
287 _dbus_hash_table_unref (policy->default_rules_by_name);
288 policy->default_rules_by_name = NULL;
296 bus_policy_create_client_policy (BusPolicy *policy,
297 DBusConnection *connection,
300 BusClientPolicy *client;
302 _dbus_assert (dbus_connection_get_is_authenticated (connection));
303 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
305 client = bus_client_policy_new ();
309 if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
311 if (!bus_connection_get_unix_groups (connection, &client->groups, &client->n_groups, error))
315 if (dbus_connection_get_unix_user (connection, &client->uid))
317 client->uid_set = TRUE;
318 client->at_console = _dbus_unix_user_is_at_console (client->uid, error);
320 if (dbus_error_is_set (error) == TRUE)
324 client->policy = bus_policy_ref (policy);
331 _DBUS_ASSERT_ERROR_IS_SET (error);
333 bus_client_policy_unref (client);
338 list_allows_user (dbus_bool_t def,
341 const unsigned long *group_ids,
349 link = _dbus_list_get_first_link (list);
352 BusPolicyRule *rule = link->data;
353 link = _dbus_list_get_next_link (list, link);
355 if (rule->type == BUS_POLICY_RULE_USER)
357 _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
358 list, rule->d.user.uid);
360 if (rule->d.user.uid == DBUS_UID_UNSET)
362 else if (rule->d.user.uid != uid)
365 else if (rule->type == BUS_POLICY_RULE_GROUP)
367 _dbus_verbose ("List %p group rule gid="DBUS_GID_FORMAT"\n",
368 list, rule->d.group.gid);
370 if (rule->d.group.gid == DBUS_GID_UNSET)
377 while (i < n_group_ids)
379 if (rule->d.group.gid == group_ids[i])
384 if (i == n_group_ids)
391 /* We don't intend to support <check user="..." /> and <check group="..." />
392 rules. They are treated like deny.
394 allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
401 bus_policy_allow_unix_user (BusPolicy *policy,
405 unsigned long *group_ids;
408 /* On OOM or error we always reject the user */
409 if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
411 _dbus_verbose ("Did not get any groups for UID %lu\n",
416 /* Default to "user owning bus" can connect */
417 allowed = _dbus_unix_user_is_process_owner (uid);
419 allowed = list_allows_user (allowed,
420 &policy->default_rules,
422 group_ids, n_group_ids);
424 allowed = list_allows_user (allowed,
425 &policy->mandatory_rules,
427 group_ids, n_group_ids);
429 dbus_free (group_ids);
431 _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
436 /* For now this is never actually called because the default
437 * DBusConnection behavior of 'same user that owns the bus can
438 * connect' is all it would do. Set the windows user function in
439 * connection.c if the config file ever supports doing something
443 bus_policy_allow_windows_user (BusPolicy *policy,
444 const char *windows_sid)
446 /* Windows has no policies here since only the session bus
447 * is really used for now, so just checking that the
448 * connecting person is the same as the bus owner is fine.
450 return _dbus_windows_user_is_process_owner (windows_sid);
453 static BusPolicyRulesWithScore *
454 get_rules_by_string (DBusHashTable *hash,
457 BusPolicyRulesWithScore *rules;
459 rules = _dbus_hash_table_lookup_string (hash, key);
462 rules = dbus_new0 (BusPolicyRulesWithScore, 1);
466 if (!_dbus_hash_table_insert_string (hash, (char *)key, rules))
477 get_name_from_rule (BusPolicyRule *rule)
479 const char *name = NULL;
480 if (rule->type == BUS_POLICY_RULE_SEND)
481 name = rule->d.send.destination;
482 else if (rule->type == BUS_POLICY_RULE_RECEIVE)
483 name = rule->d.receive.origin;
484 else if (rule->type == BUS_POLICY_RULE_OWN)
485 name = rule->d.own.service_name;
494 bus_policy_append_default_rule (BusPolicy *policy,
497 if (rule->type == BUS_POLICY_RULE_USER || rule->type == BUS_POLICY_RULE_GROUP)
499 if (!_dbus_list_append (&policy->default_rules, rule))
505 BusPolicyRulesWithScore *rules;
507 rules = get_rules_by_string (policy->default_rules_by_name,
508 get_name_from_rule (rule));
513 list = &rules->rules;
515 if (!_dbus_list_prepend (list, rule))
518 rule->score = ++policy->n_default_rules;
519 rules->score = rule->score;
522 bus_policy_rule_ref (rule);
528 bus_policy_append_mandatory_rule (BusPolicy *policy,
531 if (!_dbus_list_append (&policy->mandatory_rules, rule))
534 bus_policy_rule_ref (rule);
542 get_list (DBusHashTable *hash,
547 list = _dbus_hash_table_lookup_uintptr (hash, key);
551 list = dbus_new0 (DBusList*, 1);
555 if (!_dbus_hash_table_insert_uintptr (hash, key, list))
566 bus_policy_append_user_rule (BusPolicy *policy,
572 list = get_list (policy->rules_by_uid, uid);
577 if (!_dbus_list_append (list, rule))
580 bus_policy_rule_ref (rule);
586 bus_policy_append_group_rule (BusPolicy *policy,
592 list = get_list (policy->rules_by_gid, gid);
597 if (!_dbus_list_append (list, rule))
600 bus_policy_rule_ref (rule);
606 bus_policy_append_console_rule (BusPolicy *policy,
607 dbus_bool_t at_console,
612 if (!_dbus_list_append (&policy->at_console_true_rules, rule))
617 if (!_dbus_list_append (&policy->at_console_false_rules, rule))
621 bus_policy_rule_ref (rule);
628 append_copy_of_policy_list (DBusList **list,
629 DBusList **to_append)
636 /* Preallocate all our links */
637 link = _dbus_list_get_first_link (to_append);
640 if (!_dbus_list_append (&tmp_list, link->data))
642 _dbus_list_clear (&tmp_list);
646 link = _dbus_list_get_next_link (to_append, link);
649 /* Now append them */
650 while ((link = _dbus_list_pop_first_link (&tmp_list)))
652 bus_policy_rule_ref (link->data);
653 _dbus_list_append_link (list, link);
660 merge_id_hash (DBusHashTable *dest,
661 DBusHashTable *to_absorb)
665 _dbus_hash_iter_init (to_absorb, &iter);
666 while (_dbus_hash_iter_next (&iter))
668 unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter);
669 DBusList **list = _dbus_hash_iter_get_value (&iter);
670 DBusList **target = get_list (dest, id);
675 if (!append_copy_of_policy_list (target, list))
683 merge_string_hash (unsigned int *n_rules,
684 unsigned int n_rules_to_absorb,
686 DBusHashTable *to_absorb)
689 #ifndef DBUS_DISABLE_ASSERT
693 _dbus_hash_iter_init (to_absorb, &iter);
694 while (_dbus_hash_iter_next (&iter))
696 const char *id = _dbus_hash_iter_get_string_key (&iter);
697 BusPolicyRulesWithScore *to_absorb_rules =_dbus_hash_iter_get_value (&iter);
698 DBusList **list = &to_absorb_rules->rules;
699 BusPolicyRulesWithScore *target_rules = get_rules_by_string (dest, id);
702 DBusList *target_first_link;
704 if (target_rules == NULL)
707 target = &target_rules->rules;
708 target_first_link = _dbus_list_get_first_link (target);
710 list_iter = _dbus_list_get_first_link (list);
711 while (list_iter != NULL)
714 BusPolicyRule *rule = list_iter->data;
716 rule->score += *n_rules;
717 list_iter = _dbus_list_get_next_link (list, list_iter);
718 #ifndef DBUS_DISABLE_ASSERT
721 new_link = _dbus_list_alloc_link (rule);
722 if (new_link == NULL)
725 bus_policy_rule_ref (rule);
727 _dbus_list_insert_before_link (target, target_first_link, new_link);
730 target_rules->score = to_absorb_rules->score + *n_rules;
733 _dbus_assert (n_rules_to_absorb == cnt_rules);
735 *n_rules += n_rules_to_absorb;
741 bus_policy_merge (BusPolicy *policy,
742 BusPolicy *to_absorb)
744 /* FIXME Not properly atomic, but as used for configuration files we
745 * don't rely on it quite so much.
748 if (!append_copy_of_policy_list (&policy->default_rules,
749 &to_absorb->default_rules))
752 if (!append_copy_of_policy_list (&policy->mandatory_rules,
753 &to_absorb->mandatory_rules))
756 if (!append_copy_of_policy_list (&policy->at_console_true_rules,
757 &to_absorb->at_console_true_rules))
760 if (!append_copy_of_policy_list (&policy->at_console_false_rules,
761 &to_absorb->at_console_false_rules))
764 if (!merge_id_hash (policy->rules_by_uid,
765 to_absorb->rules_by_uid))
768 if (!merge_id_hash (policy->rules_by_gid,
769 to_absorb->rules_by_gid))
772 if (!merge_string_hash (&policy->n_default_rules,
773 to_absorb->n_default_rules,
774 policy->default_rules_by_name,
775 to_absorb->default_rules_by_name))
782 bus_client_policy_new (void)
784 BusClientPolicy *policy;
786 policy = dbus_new0 (BusClientPolicy, 1);
790 policy->refcount = 1;
796 bus_client_policy_ref (BusClientPolicy *policy)
798 _dbus_assert (policy->refcount > 0);
800 policy->refcount += 1;
806 bus_client_policy_unref (BusClientPolicy *policy)
808 _dbus_assert (policy->refcount > 0);
810 policy->refcount -= 1;
812 if (policy->refcount == 0)
815 bus_policy_unref (policy->policy);
817 dbus_free (policy->groups);
823 #define _dbus_string_append_printf_err_check(str, fmt, args...) \
824 if (!_dbus_string_append_printf(str, fmt, ##args)) \
826 _dbus_string_free (str); \
831 bus_policy_rule_to_string (BusPolicyRule *rule,
837 const char *msg_type[] = {"Invalid", "method_call", "method_return", "signal", "error"};
842 switch (rule->access)
844 case BUS_POLICY_RULE_ACCESS_ALLOW:
847 case BUS_POLICY_RULE_ACCESS_DENY:
850 case BUS_POLICY_RULE_ACCESS_CHECK:
854 _dbus_assert_not_reached ("invalid rule access value");
857 if (rule->type == BUS_POLICY_RULE_SEND)
860 dest = "destination";
862 else if (rule->type == BUS_POLICY_RULE_RECEIVE)
870 /* generate xml format */
871 if (!_dbus_string_init (&str))
874 _dbus_string_append_printf_err_check (&str, "<%s ", access);
876 if (rule->d.send.destination_prefix)
878 _dbus_string_append_printf_err_check (&str, "%s_destination_prefix=\"%s\" ", sr, rule->d.send.destination);
880 else if (rule->d.send.destination)
882 _dbus_string_append_printf_err_check (&str, "%s_%s=\"%s\" ", sr, dest, rule->d.send.destination);
885 if (rule->d.send.path)
886 _dbus_string_append_printf_err_check (&str, "%s_path=\"%s\" ", sr, rule->d.send.path);
887 if (rule->d.send.interface)
888 _dbus_string_append_printf_err_check (&str, "%s_interface=\"%s\" ", sr, rule->d.send.interface);
889 if (rule->d.send.member)
890 _dbus_string_append_printf_err_check (&str, "%s_member=\"%s\" ", sr, rule->d.send.member);
891 if (rule->d.send.message_type)
892 _dbus_string_append_printf_err_check (&str, "%s_type=\"%s\" ", sr, msg_type[rule->d.send.message_type]);
894 _dbus_string_append_printf_err_check (&str, "privilege=\"%s\" ", rule->privilege);
896 if (!_dbus_string_append (&str, "/>"))
898 _dbus_string_free (&str);
902 if (!_dbus_string_steal_data (&str, out_rule))
905 _dbus_string_free (&str);
909 _dbus_string_free (&str);
914 typedef struct RuleParams {
915 enum {PARAM_SR, PARAM_OWN} type;
918 BusRegistry *registry;
919 dbus_bool_t requested_reply;
920 DBusConnection *peer;
922 DBusMessage *message;
923 dbus_bool_t eavesdropping;
925 const DBusString *name;
929 typedef dbus_bool_t (*CheckRuleFunc) (const BusPolicyRule *,
935 check_send_rule (const BusPolicyRule *rule,
936 const RuleParams *match_params,
938 const char **privilege)
940 /* Rule is skipped if it specifies a different
941 * message name from the message, or a different
942 * destination from the message
944 if (rule->type != BUS_POLICY_RULE_SEND)
946 _dbus_verbose (" (policy) skipping non-send rule\n");
950 if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
952 if (dbus_message_get_type (match_params->u.sr.message) != rule->d.send.message_type)
954 _dbus_verbose (" (policy) skipping rule for different message type\n");
959 /* If it's a reply, the requested_reply flag kicks in */
960 if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
962 /* for allow or check requested_reply=true means the rule applies
963 * only when reply was requested. requested_reply=false means the
964 * rule always applies
966 if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
968 _dbus_verbose (" (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
969 rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
973 /* for deny, requested_reply=false means the rule applies only
974 * when the reply was not requested. requested_reply=true means the
975 * rule always applies.
977 if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.send.requested_reply)
979 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
984 if (rule->d.send.path != NULL)
986 if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
987 strcmp (dbus_message_get_path (match_params->u.sr.message),
988 rule->d.send.path) != 0)
990 _dbus_verbose (" (policy) skipping rule for different path\n");
995 if (rule->d.send.interface != NULL)
997 /* The interface is optional in messages. For allow rules, if the message
998 * has no interface we want to skip the rule (and thus not allow);
999 * for deny rules, if the message has no interface we want to use the
1000 * rule (and thus deny). Check rules are meant to be used like allow
1001 * rules (they can grant access, but not remove it), so we treat it like
1004 dbus_bool_t no_interface;
1006 no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1008 if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1010 strcmp (dbus_message_get_interface (match_params->u.sr.message),
1011 rule->d.send.interface) != 0))
1013 _dbus_verbose (" (policy) skipping rule for different interface\n");
1018 if (rule->d.send.member != NULL)
1020 if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1021 strcmp (dbus_message_get_member (match_params->u.sr.message),
1022 rule->d.send.member) != 0)
1024 _dbus_verbose (" (policy) skipping rule for different member\n");
1029 if (rule->d.send.error != NULL)
1031 if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1032 strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1033 rule->d.send.error) != 0)
1035 _dbus_verbose (" (policy) skipping rule for different error name\n");
1040 if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
1042 if (dbus_message_get_destination (match_params->u.sr.message) == NULL &&
1043 dbus_message_get_type (match_params->u.sr.message) == DBUS_MESSAGE_TYPE_SIGNAL)
1045 /* it's a broadcast */
1046 if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
1048 _dbus_verbose (" (policy) skipping rule because message is a broadcast\n");
1052 /* else it isn't a broadcast: there is some destination */
1053 else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
1055 _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n");
1060 if (rule->d.send.destination != NULL)
1062 if (!rule->d.send.destination_prefix)
1064 /* receiver can be NULL for messages that are sent to the
1065 * message bus itself, we check the strings in that case as
1066 * built-in services don't have a DBusConnection but messages
1067 * to them have a destination service name.
1069 * Similarly, receiver can be NULL when we're deciding whether
1070 * activation should be allowed; we make the authorization decision
1071 * on the assumption that the activated service will have the
1072 * requested name and no others.
1074 if (match_params->u.sr.peer == NULL)
1076 if (!dbus_message_has_destination (match_params->u.sr.message,
1077 rule->d.send.destination))
1079 _dbus_verbose (" (policy) skipping rule because message dest is not %s\n",
1080 rule->d.send.destination);
1087 BusService *service;
1089 _dbus_string_init_const (&str, rule->d.send.destination);
1091 service = bus_registry_lookup (match_params->u.sr.registry, &str);
1092 if (service == NULL)
1094 _dbus_verbose (" (policy) skipping rule because dest %s doesn't exist\n",
1095 rule->d.send.destination);
1099 if (!bus_service_has_owner (service, match_params->u.sr.peer))
1101 _dbus_verbose (" (policy) skipping rule because dest %s isn't owned by receiver\n",
1102 rule->d.send.destination);
1107 else if (rule->d.send.destination_prefix)
1109 /* receiver can be NULL - the same as in !send.destination_prefix */
1110 if (match_params->u.sr.peer == NULL)
1112 const char *destination = dbus_message_get_destination (match_params->u.sr.message);
1113 DBusString dest_name;
1115 if (destination == NULL)
1117 _dbus_verbose (" (policy) skipping rule because message has no dest\n");
1121 _dbus_string_init_const (&dest_name, destination);
1123 if (!_dbus_string_starts_with_words_c_str (&dest_name,
1124 rule->d.send.destination,
1127 _dbus_verbose (" (policy) skipping rule because message dest doesn't start with %s\n",
1128 rule->d.send.destination);
1134 if (!bus_connection_is_service_owner_by_prefix (match_params->u.sr.peer,
1135 rule->d.send.destination))
1137 _dbus_verbose (" (policy) skipping rule because no dest with prefix %s is owned by receiver\n",
1138 rule->d.send.destination);
1145 if (rule->d.send.min_fds > 0 ||
1146 rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1148 unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1150 if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
1152 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1153 "and that is outside range [%u,%u]",
1154 n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
1160 switch (rule->access)
1162 case BUS_POLICY_RULE_ACCESS_ALLOW:
1163 *result = BUS_RESULT_TRUE;
1165 case BUS_POLICY_RULE_ACCESS_DENY:
1166 *result = BUS_RESULT_FALSE;
1168 case BUS_POLICY_RULE_ACCESS_CHECK:
1169 *result = BUS_RESULT_LATER;
1170 *privilege = rule->privilege;
1173 _dbus_assert_not_reached ("invalid rule access value");
1180 check_rules_list (const DBusList *rules,
1181 CheckRuleFunc check_func,
1182 const RuleParams *params,
1183 dbus_int32_t *toggles,
1186 const char **privilege,
1187 BusPolicyRule **matched_rule,
1188 dbus_bool_t break_on_first_match)
1190 const DBusList *link;
1192 link = _dbus_list_get_first_link ((DBusList **)&rules);
1193 while (link != NULL)
1195 const BusPolicyRule *rule = link->data;
1197 link = _dbus_list_get_next_link ((DBusList **)&rules, link);
1199 if (check_func (rule, params, result, privilege))
1202 *log = rule->d.send.log;
1206 *matched_rule = (BusPolicyRule *)rule;
1208 _dbus_verbose (" (policy) used rule, result now = %d\n",
1211 if (break_on_first_match)
1218 check_rules_for_name (DBusHashTable *rules,
1221 CheckRuleFunc check_func,
1223 dbus_int32_t *toggles,
1226 const char **privilege,
1227 BusPolicyRule **matched_rule)
1229 dbus_int32_t local_toggles;
1230 dbus_bool_t local_log;
1231 BusResult local_result;
1232 const char *local_privilege;
1233 BusPolicyRule *local_matched_rule;
1234 const BusPolicyRulesWithScore *rules_list;
1236 rules_list = _dbus_hash_table_lookup_string (rules, name);
1238 if (rules_list == NULL || rules_list->score <= score)
1243 check_rules_list (rules_list->rules, check_func, params,
1244 &local_toggles, &local_log, &local_result, &local_privilege,
1245 &local_matched_rule, TRUE);
1247 if (local_toggles > 0)
1249 _dbus_assert (local_matched_rule != NULL);
1251 if (local_matched_rule->score > score)
1254 *toggles += local_toggles;
1257 *result = local_result;
1258 *privilege = local_privilege;
1260 *matched_rule = local_matched_rule;
1261 return local_matched_rule->score;
1269 find_and_check_rules_for_name (DBusHashTable *rules,
1272 CheckRuleFunc check_func,
1274 dbus_int32_t *toggles,
1277 const char **privilege,
1278 BusPolicyRule **matched_rule)
1280 char name[DBUS_MAXIMUM_NAME_LENGTH+1];
1281 int pos = strlen(c_str);
1283 _dbus_assert (pos <= DBUS_MAXIMUM_NAME_LENGTH);
1285 strncpy (name, c_str, pos);
1290 score = check_rules_for_name (rules, name,
1291 score, check_func, params,
1296 while (pos > 0 && name[pos] != '.')
1306 find_and_check_rules (DBusHashTable *rules,
1307 CheckRuleFunc check_func,
1309 dbus_int32_t *toggles,
1312 const char **privilege,
1313 BusPolicyRule **matched_rule)
1315 const RuleParams *p = params;
1316 const DBusList *services = NULL;
1319 if (p->type == PARAM_SR)
1321 if (p->u.sr.peer != NULL)
1325 services = bus_connection_get_owned_services_list (p->u.sr.peer);
1327 link = _dbus_list_get_first_link ((DBusList **)&services);
1328 while (link != NULL)
1330 const char *name = bus_service_get_name (link->data);
1332 link = _dbus_list_get_next_link ((DBusList **)&services, link);
1334 /* skip unique id names */
1338 score = find_and_check_rules_for_name (rules, name, score,
1340 toggles, log, result,
1341 privilege, matched_rule);
1344 else if (p->u.sr.name != NULL)
1346 score = find_and_check_rules_for_name (rules, p->u.sr.name, score,
1348 toggles, log, result,
1349 privilege, matched_rule);
1353 score = find_and_check_rules_for_name (rules, _dbus_string_get_data(p->u.name),
1354 score, check_func, params,
1355 toggles, log, result,
1356 privilege, matched_rule);
1358 /* check also wildcard rules */
1359 score = check_rules_for_name (rules, "", score, check_func, params,
1360 toggles, log, result, privilege, matched_rule);
1364 check_policy (BusClientPolicy *policy,
1365 CheckRuleFunc check_func,
1367 dbus_int32_t *toggles,
1369 const char **privilege,
1370 BusPolicyRule **matched_rule)
1372 BusResult result = BUS_RESULT_FALSE;
1377 find_and_check_rules (policy->policy->default_rules_by_name, check_func, params,
1378 toggles, log, &result, privilege, matched_rule);
1380 /* we avoid the overhead of looking up user's groups
1381 * if we don't have any group rules anyway
1383 if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_gid) > 0)
1387 for (i = 0; i < policy->n_groups; ++i)
1389 const DBusList **list;
1391 list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_gid,
1395 check_rules_list (*list, check_func, params,
1396 toggles, log, &result, privilege, matched_rule, FALSE);
1400 if (policy->uid_set)
1402 if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_uid) > 0)
1404 const DBusList **list;
1406 list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_uid,
1410 check_rules_list (*list, check_func, params,
1411 toggles, log, &result, privilege, matched_rule, FALSE);
1413 if (policy->at_console)
1414 check_rules_list (policy->policy->at_console_true_rules, check_func,
1415 params, toggles, log, &result, privilege, matched_rule, FALSE);
1417 check_rules_list (policy->policy->at_console_false_rules, check_func,
1418 params, toggles, log, &result, privilege, matched_rule, FALSE);
1422 check_rules_list (policy->policy->mandatory_rules, check_func, params,
1423 toggles, log, &result, privilege, matched_rule, FALSE);
1429 bus_client_policy_check_can_send (DBusConnection *sender,
1430 BusClientPolicy *policy,
1431 BusRegistry *registry,
1432 dbus_bool_t requested_reply,
1433 DBusConnection *addressed_recipient,
1434 DBusConnection *receiver,
1435 DBusMessage *message,
1436 dbus_int32_t *toggles,
1438 const char **privilege_param,
1439 BusDeferredMessage **deferred_message,
1443 const char *privilege;
1444 BusPolicyRule *matched_rule = NULL;
1445 struct RuleParams params;
1447 params.type = PARAM_SR;
1448 params.u.sr.registry = registry;
1449 params.u.sr.requested_reply = requested_reply;
1450 params.u.sr.peer = receiver;
1451 params.u.sr.message = message;
1452 params.u.sr.name = dbus_message_get_destination (message);
1454 _dbus_verbose (" (policy) checking send rules\n");
1456 result = check_policy (policy, check_send_rule, ¶ms,
1457 toggles, log, &privilege, &matched_rule);
1459 if (result == BUS_RESULT_LATER)
1461 BusContext *context = bus_connection_get_context(sender);
1462 BusCheck *check = bus_context_get_check(context);
1464 result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
1465 privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
1466 if (result == BUS_RESULT_LATER && deferred_message != NULL)
1467 bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1468 *toggles, privilege);
1473 if (privilege_param != NULL)
1474 *privilege_param = privilege;
1476 if (result == BUS_RESULT_FALSE)
1478 if (matched_rule && out_rule)
1479 bus_policy_rule_to_string (matched_rule, out_rule);
1486 check_receive_rule (const BusPolicyRule *rule,
1487 const RuleParams *match_params,
1489 const char **privilege)
1491 if (rule->type != BUS_POLICY_RULE_RECEIVE)
1493 _dbus_verbose (" (policy) skipping non-receive rule\n");
1497 if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
1499 if (dbus_message_get_type (match_params->u.sr.message) != rule->d.receive.message_type)
1501 _dbus_verbose (" (policy) skipping rule for different message type\n");
1507 /* for allow or check, eavesdrop=false means the rule doesn't apply when
1508 * eavesdropping. eavesdrop=true means the rule always applies
1510 if (match_params->u.sr.eavesdropping && rule->access != BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.eavesdrop)
1512 _dbus_verbose (" (policy) skipping %s rule since it doesn't apply to eavesdropping\n",
1513 rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
1517 /* for deny, eavesdrop=true means the rule applies only when
1518 * eavesdropping; eavesdrop=false means always deny.
1520 if (!match_params->u.sr.eavesdropping && rule->access == BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.eavesdrop)
1522 _dbus_verbose (" (policy) skipping deny rule since it only applies to eavesdropping\n");
1526 /* If it's a reply, the requested_reply flag kicks in */
1527 if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
1529 /* for allow or check requested_reply=true means the rule applies
1530 * only when reply was requested. requested_reply=false means the
1531 * rule always applies
1533 if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
1535 _dbus_verbose (" (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
1536 rule->access == BUS_POLICY_RULE_ACCESS_DENY ? "allow" : "deny");
1540 /* for deny, requested_reply=false means the rule applies only
1541 * when the reply was not requested. requested_reply=true means the
1542 * rule always applies.
1544 if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.requested_reply)
1546 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
1551 if (rule->d.receive.path != NULL)
1553 if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
1554 strcmp (dbus_message_get_path (match_params->u.sr.message),
1555 rule->d.receive.path) != 0)
1557 _dbus_verbose (" (policy) skipping rule for different path\n");
1562 if (rule->d.receive.interface != NULL)
1564 /* The interface is optional in messages. For allow rules, if the message
1565 * has no interface we want to skip the rule (and thus not allow);
1566 * for deny rules, if the message has no interface we want to use the
1567 * rule (and thus deny). Check rules are treated like allow rules.
1569 dbus_bool_t no_interface;
1571 no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1573 if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1575 strcmp (dbus_message_get_interface (match_params->u.sr.message),
1576 rule->d.receive.interface) != 0))
1578 _dbus_verbose (" (policy) skipping rule for different interface\n");
1583 if (rule->d.receive.member != NULL)
1585 if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1586 strcmp (dbus_message_get_member (match_params->u.sr.message),
1587 rule->d.receive.member) != 0)
1589 _dbus_verbose (" (policy) skipping rule for different member\n");
1594 if (rule->d.receive.error != NULL)
1596 if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1597 strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1598 rule->d.receive.error) != 0)
1600 _dbus_verbose (" (policy) skipping rule for different error name\n");
1605 if (rule->d.receive.origin != NULL)
1607 /* sender can be NULL for messages that originate from the
1608 * message bus itself, we check the strings in that case as
1609 * built-in services don't have a DBusConnection but will
1610 * still set the sender on their messages.
1612 if (match_params->u.sr.peer == NULL)
1614 if (!dbus_message_has_sender (match_params->u.sr.message,
1615 rule->d.receive.origin))
1617 _dbus_verbose (" (policy) skipping rule because message sender is not %s\n",
1618 rule->d.receive.origin);
1624 BusService *service;
1627 _dbus_string_init_const (&str, rule->d.receive.origin);
1629 service = bus_registry_lookup (match_params->u.sr.registry, &str);
1631 if (service == NULL)
1633 _dbus_verbose (" (policy) skipping rule because origin %s doesn't exist\n",
1634 rule->d.receive.origin);
1638 if (!bus_service_has_owner (service, match_params->u.sr.peer))
1640 _dbus_verbose (" (policy) skipping rule because origin %s isn't owned by sender\n",
1641 rule->d.receive.origin);
1647 if (rule->d.receive.min_fds > 0 ||
1648 rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1650 unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1652 if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
1654 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1655 "and that is outside range [%u,%u]",
1656 n_fds, rule->d.receive.min_fds,
1657 rule->d.receive.max_fds);
1663 switch (rule->access)
1665 case BUS_POLICY_RULE_ACCESS_ALLOW:
1666 *result = BUS_RESULT_TRUE;
1668 case BUS_POLICY_RULE_ACCESS_DENY:
1669 *result = BUS_RESULT_FALSE;
1671 case BUS_POLICY_RULE_ACCESS_CHECK:
1672 *result = BUS_RESULT_LATER;
1673 *privilege = rule->privilege;
1676 _dbus_assert_not_reached ("invalid rule access value");
1682 /* See docs on what the args mean on bus_context_check_security_policy()
1686 bus_client_policy_check_can_receive (BusClientPolicy *policy,
1687 BusRegistry *registry,
1688 dbus_bool_t requested_reply,
1689 DBusConnection *sender,
1690 DBusConnection *addressed_recipient,
1691 DBusConnection *proposed_recipient,
1692 DBusMessage *message,
1693 dbus_int32_t *toggles,
1694 const char **privilege_param,
1695 BusDeferredMessage **deferred_message,
1699 const char *privilege;
1700 BusPolicyRule *matched_rule = NULL;
1701 struct RuleParams params;
1703 params.type = PARAM_SR;
1704 params.u.sr.registry = registry;
1705 params.u.sr.requested_reply = requested_reply;
1706 params.u.sr.peer = sender;
1707 params.u.sr.message = message;
1708 params.u.sr.eavesdropping =
1709 addressed_recipient != proposed_recipient &&
1710 dbus_message_get_destination (message) != NULL;
1711 params.u.sr.name = dbus_message_get_sender (message);
1713 _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
1715 result = check_policy (policy, check_receive_rule, ¶ms,
1716 toggles, NULL, &privilege, &matched_rule);
1718 if (result == BUS_RESULT_LATER)
1720 BusContext *context = bus_connection_get_context(proposed_recipient);
1721 BusCheck *check = bus_context_get_check(context);
1723 result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
1724 privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
1725 if (result == BUS_RESULT_LATER && deferred_message != NULL)
1726 bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1727 *toggles, privilege);
1732 if (privilege_param != NULL)
1733 *privilege_param = privilege;
1735 if (result == BUS_RESULT_FALSE)
1737 if (matched_rule && out_rule)
1738 bus_policy_rule_to_string (matched_rule, out_rule);
1745 check_own_rule (const BusPolicyRule *rule,
1746 const RuleParams *params,
1748 const char **privilege)
1750 const DBusString *service_name = params->u.name;
1752 /* Rule is skipped if it specifies a different service name from
1756 if (rule->type != BUS_POLICY_RULE_OWN)
1759 if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
1761 if (!_dbus_string_equal_c_str (service_name,
1762 rule->d.own.service_name))
1765 else if (rule->d.own.prefix)
1767 if (!_dbus_string_starts_with_words_c_str (service_name,
1768 rule->d.own.service_name,
1774 switch (rule->access)
1776 case BUS_POLICY_RULE_ACCESS_ALLOW:
1777 *result = BUS_RESULT_TRUE;
1779 case BUS_POLICY_RULE_ACCESS_DENY:
1780 *result = BUS_RESULT_FALSE;
1782 case BUS_POLICY_RULE_ACCESS_CHECK:
1783 *result = BUS_RESULT_LATER;
1784 *privilege = rule->privilege;
1787 _dbus_assert_not_reached ("invalid rule access value");
1794 bus_client_policy_check_can_own (BusClientPolicy *policy,
1795 const DBusString *service_name,
1796 DBusConnection *connection,
1797 DBusMessage *message)
1800 const char *privilege;
1803 params.type = PARAM_OWN;
1804 params.u.name = service_name;
1806 result = check_policy (policy, check_own_rule, ¶ms,
1807 NULL, NULL, &privilege, NULL);
1809 if (result == BUS_RESULT_LATER)
1811 BusContext *context = bus_connection_get_context(connection);
1812 BusCheck *check = bus_context_get_check(context);
1813 BusDeferredMessage *deferred_message;
1815 result = bus_check_privilege(check, message, connection, NULL, NULL,
1816 privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message);
1817 if (result == BUS_RESULT_LATER)
1819 bus_deferred_message_disable_sender(deferred_message);
1826 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1828 bus_policy_check_can_own (BusPolicy *policy,
1829 const DBusString *service_name)
1831 return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL);
1833 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */