1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* policy.c Bus security policy
3 *
4 * Copyright (C) 2003, 2004 Red Hat, Inc.
5 *
6 * Licensed under the Academic Free License version 2.1
7 *
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.
12 *
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.
17 *
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
21 *
22 */
23
24 #include <config.h>
25 #include "policy.h"
26 #include "services.h"
27 #include "test.h"
28 #include "utils.h"
29 #include <dbus/dbus-list.h>
30 #include <dbus/dbus-hash.h>
31 #include <dbus/dbus-internals.h>
32 #include <dbus/dbus-message-internal.h>
33
34 BusPolicyRule*
bus_policy_rule_new(BusPolicyRuleType type,dbus_bool_t allow)35 bus_policy_rule_new (BusPolicyRuleType type,
36 dbus_bool_t allow)
37 {
38 BusPolicyRule *rule;
39
40 rule = dbus_new0 (BusPolicyRule, 1);
41 if (rule == NULL)
42 return NULL;
43
44 rule->type = type;
45 rule->refcount = 1;
46 rule->allow = allow;
47
48 switch (rule->type)
49 {
50 case BUS_POLICY_RULE_USER:
51 rule->d.user.uid = DBUS_UID_UNSET;
52 break;
53 case BUS_POLICY_RULE_GROUP:
54 rule->d.group.gid = DBUS_GID_UNSET;
55 break;
56 case BUS_POLICY_RULE_SEND:
57 rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
58
59 /* allow rules default to TRUE (only requested replies allowed)
60 * deny rules default to FALSE (only unrequested replies denied)
61 */
62 rule->d.send.requested_reply = rule->allow;
63 break;
64 case BUS_POLICY_RULE_RECEIVE:
65 rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
66 /* allow rules default to TRUE (only requested replies allowed)
67 * deny rules default to FALSE (only unrequested replies denied)
68 */
69 rule->d.receive.requested_reply = rule->allow;
70 break;
71 case BUS_POLICY_RULE_OWN:
72 break;
73 default:
74 _dbus_assert_not_reached ("invalid rule");
75 }
76
77 return rule;
78 }
79
80 BusPolicyRule *
bus_policy_rule_ref(BusPolicyRule * rule)81 bus_policy_rule_ref (BusPolicyRule *rule)
82 {
83 _dbus_assert (rule->refcount > 0);
84
85 rule->refcount += 1;
86
87 return rule;
88 }
89
90 void
bus_policy_rule_unref(BusPolicyRule * rule)91 bus_policy_rule_unref (BusPolicyRule *rule)
92 {
93 _dbus_assert (rule->refcount > 0);
94
95 rule->refcount -= 1;
96
97 if (rule->refcount == 0)
98 {
99 switch (rule->type)
100 {
101 case BUS_POLICY_RULE_SEND:
102 dbus_free (rule->d.send.path);
103 dbus_free (rule->d.send.interface);
104 dbus_free (rule->d.send.member);
105 dbus_free (rule->d.send.error);
106 dbus_free (rule->d.send.destination);
107 break;
108 case BUS_POLICY_RULE_RECEIVE:
109 dbus_free (rule->d.receive.path);
110 dbus_free (rule->d.receive.interface);
111 dbus_free (rule->d.receive.member);
112 dbus_free (rule->d.receive.error);
113 dbus_free (rule->d.receive.origin);
114 break;
115 case BUS_POLICY_RULE_OWN:
116 dbus_free (rule->d.own.service_name);
117 break;
118 case BUS_POLICY_RULE_USER:
119 break;
120 case BUS_POLICY_RULE_GROUP:
121 break;
122 default:
123 _dbus_assert_not_reached ("invalid rule");
124 }
125
126 dbus_free (rule);
127 }
128 }
129
130 struct BusPolicy
131 {
132 int refcount;
133
134 DBusList *default_rules; /**< Default policy rules */
135 DBusList *mandatory_rules; /**< Mandatory policy rules */
136 DBusHashTable *rules_by_uid; /**< per-UID policy rules */
137 DBusHashTable *rules_by_gid; /**< per-GID policy rules */
138 DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
139 DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
140 };
141
142 static void
free_rule_func(void * data,void * user_data)143 free_rule_func (void *data,
144 void *user_data)
145 {
146 BusPolicyRule *rule = data;
147
148 bus_policy_rule_unref (rule);
149 }
150
151 static void
free_rule_list_func(void * data)152 free_rule_list_func (void *data)
153 {
154 DBusList **list = data;
155
156 if (list == NULL) /* DBusHashTable is on crack */
157 return;
158
159 _dbus_list_foreach (list, free_rule_func, NULL);
160
161 _dbus_list_clear (list);
162
163 dbus_free (list);
164 }
165
166 BusPolicy*
bus_policy_new(void)167 bus_policy_new (void)
168 {
169 BusPolicy *policy;
170
171 policy = dbus_new0 (BusPolicy, 1);
172 if (policy == NULL)
173 return NULL;
174
175 policy->refcount = 1;
176
177 policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
178 NULL,
179 free_rule_list_func);
180 if (policy->rules_by_uid == NULL)
181 goto failed;
182
183 policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
184 NULL,
185 free_rule_list_func);
186 if (policy->rules_by_gid == NULL)
187 goto failed;
188
189 return policy;
190
191 failed:
192 bus_policy_unref (policy);
193 return NULL;
194 }
195
196 BusPolicy *
bus_policy_ref(BusPolicy * policy)197 bus_policy_ref (BusPolicy *policy)
198 {
199 _dbus_assert (policy->refcount > 0);
200
201 policy->refcount += 1;
202
203 return policy;
204 }
205
206 void
bus_policy_unref(BusPolicy * policy)207 bus_policy_unref (BusPolicy *policy)
208 {
209 _dbus_assert (policy->refcount > 0);
210
211 policy->refcount -= 1;
212
213 if (policy->refcount == 0)
214 {
215 _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
216 _dbus_list_clear (&policy->default_rules);
217
218 _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
219 _dbus_list_clear (&policy->mandatory_rules);
220
221 _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
222 _dbus_list_clear (&policy->at_console_true_rules);
223
224 _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
225 _dbus_list_clear (&policy->at_console_false_rules);
226
227 if (policy->rules_by_uid)
228 {
229 _dbus_hash_table_unref (policy->rules_by_uid);
230 policy->rules_by_uid = NULL;
231 }
232
233 if (policy->rules_by_gid)
234 {
235 _dbus_hash_table_unref (policy->rules_by_gid);
236 policy->rules_by_gid = NULL;
237 }
238
239 dbus_free (policy);
240 }
241 }
242
243 static dbus_bool_t
add_list_to_client(DBusList ** list,BusClientPolicy * client)244 add_list_to_client (DBusList **list,
245 BusClientPolicy *client)
246 {
247 DBusList *link;
248
249 link = _dbus_list_get_first_link (list);
250 while (link != NULL)
251 {
252 BusPolicyRule *rule = link->data;
253 link = _dbus_list_get_next_link (list, link);
254
255 switch (rule->type)
256 {
257 case BUS_POLICY_RULE_USER:
258 case BUS_POLICY_RULE_GROUP:
259 /* These aren't per-connection policies */
260 break;
261
262 case BUS_POLICY_RULE_OWN:
263 case BUS_POLICY_RULE_SEND:
264 case BUS_POLICY_RULE_RECEIVE:
265 /* These are per-connection */
266 if (!bus_client_policy_append_rule (client, rule))
267 return FALSE;
268 break;
269
270 default:
271 _dbus_assert_not_reached ("invalid rule");
272 }
273 }
274
275 return TRUE;
276 }
277
278 BusClientPolicy*
bus_policy_create_client_policy(BusPolicy * policy,DBusConnection * connection,DBusError * error)279 bus_policy_create_client_policy (BusPolicy *policy,
280 DBusConnection *connection,
281 DBusError *error)
282 {
283 BusClientPolicy *client;
284 dbus_uid_t uid;
285 dbus_bool_t at_console;
286
287 _dbus_assert (dbus_connection_get_is_authenticated (connection));
288 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
289
290 client = bus_client_policy_new ();
291 if (client == NULL)
292 goto nomem;
293
294 if (!add_list_to_client (&policy->default_rules,
295 client))
296 goto nomem;
297
298 /* we avoid the overhead of looking up user's groups
299 * if we don't have any group rules anyway
300 */
301 if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
302 {
303 unsigned long *groups;
304 int n_groups;
305 int i;
306
307 if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error))
308 goto failed;
309
310 i = 0;
311 while (i < n_groups)
312 {
313 DBusList **list;
314
315 list = _dbus_hash_table_lookup_uintptr (policy->rules_by_gid,
316 groups[i]);
317
318 if (list != NULL)
319 {
320 if (!add_list_to_client (list, client))
321 {
322 dbus_free (groups);
323 goto nomem;
324 }
325 }
326
327 ++i;
328 }
329
330 dbus_free (groups);
331 }
332
333 if (dbus_connection_get_unix_user (connection, &uid))
334 {
335 if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
336 {
337 DBusList **list;
338
339 list = _dbus_hash_table_lookup_uintptr (policy->rules_by_uid,
340 uid);
341
342 if (list != NULL)
343 {
344 if (!add_list_to_client (list, client))
345 goto nomem;
346 }
347 }
348
349 /* Add console rules */
350 at_console = _dbus_unix_user_is_at_console (uid, error);
351
352 if (at_console)
353 {
354 if (!add_list_to_client (&policy->at_console_true_rules, client))
355 goto nomem;
356 }
357 else if (dbus_error_is_set (error) == TRUE)
358 {
359 goto failed;
360 }
361 else if (!add_list_to_client (&policy->at_console_false_rules, client))
362 {
363 goto nomem;
364 }
365 }
366
367 if (!add_list_to_client (&policy->mandatory_rules,
368 client))
369 goto nomem;
370
371 bus_client_policy_optimize (client);
372
373 return client;
374
375 nomem:
376 BUS_SET_OOM (error);
377 failed:
378 _DBUS_ASSERT_ERROR_IS_SET (error);
379 if (client)
380 bus_client_policy_unref (client);
381 return NULL;
382 }
383
384 static dbus_bool_t
list_allows_user(dbus_bool_t def,DBusList ** list,unsigned long uid,const unsigned long * group_ids,int n_group_ids)385 list_allows_user (dbus_bool_t def,
386 DBusList **list,
387 unsigned long uid,
388 const unsigned long *group_ids,
389 int n_group_ids)
390 {
391 DBusList *link;
392 dbus_bool_t allowed;
393
394 allowed = def;
395
396 link = _dbus_list_get_first_link (list);
397 while (link != NULL)
398 {
399 BusPolicyRule *rule = link->data;
400 link = _dbus_list_get_next_link (list, link);
401
402 if (rule->type == BUS_POLICY_RULE_USER)
403 {
404 _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
405 list, rule->d.user.uid);
406
407 if (rule->d.user.uid == DBUS_UID_UNSET)
408 ; /* '*' wildcard */
409 else if (rule->d.user.uid != uid)
410 continue;
411 }
412 else if (rule->type == BUS_POLICY_RULE_GROUP)
413 {
414 _dbus_verbose ("List %p group rule gid="DBUS_GID_FORMAT"\n",
415 list, rule->d.group.gid);
416
417 if (rule->d.group.gid == DBUS_GID_UNSET)
418 ; /* '*' wildcard */
419 else
420 {
421 int i;
422
423 i = 0;
424 while (i < n_group_ids)
425 {
426 if (rule->d.group.gid == group_ids[i])
427 break;
428 ++i;
429 }
430
431 if (i == n_group_ids)
432 continue;
433 }
434 }
435 else
436 continue;
437
438 allowed = rule->allow;
439 }
440
441 return allowed;
442 }
443
444 dbus_bool_t
bus_policy_allow_unix_user(BusPolicy * policy,unsigned long uid)445 bus_policy_allow_unix_user (BusPolicy *policy,
446 unsigned long uid)
447 {
448 dbus_bool_t allowed;
449 unsigned long *group_ids;
450 int n_group_ids;
451
452 /* On OOM or error we always reject the user */
453 if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
454 {
455 _dbus_verbose ("Did not get any groups for UID %lu\n",
456 uid);
457 return FALSE;
458 }
459
460 /* Default to "user owning bus" can connect */
461 allowed = _dbus_unix_user_is_process_owner (uid);
462
463 allowed = list_allows_user (allowed,
464 &policy->default_rules,
465 uid,
466 group_ids, n_group_ids);
467
468 allowed = list_allows_user (allowed,
469 &policy->mandatory_rules,
470 uid,
471 group_ids, n_group_ids);
472
473 dbus_free (group_ids);
474
475 _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
476
477 return allowed;
478 }
479
480 /* For now this is never actually called because the default
481 * DBusConnection behavior of 'same user that owns the bus can
482 * connect' is all it would do. Set the windows user function in
483 * connection.c if the config file ever supports doing something
484 * interesting here.
485 */
486 dbus_bool_t
bus_policy_allow_windows_user(BusPolicy * policy,const char * windows_sid)487 bus_policy_allow_windows_user (BusPolicy *policy,
488 const char *windows_sid)
489 {
490 /* Windows has no policies here since only the session bus
491 * is really used for now, so just checking that the
492 * connecting person is the same as the bus owner is fine.
493 */
494 return _dbus_windows_user_is_process_owner (windows_sid);
495 }
496
497 dbus_bool_t
bus_policy_append_default_rule(BusPolicy * policy,BusPolicyRule * rule)498 bus_policy_append_default_rule (BusPolicy *policy,
499 BusPolicyRule *rule)
500 {
501 if (!_dbus_list_append (&policy->default_rules, rule))
502 return FALSE;
503
504 bus_policy_rule_ref (rule);
505
506 return TRUE;
507 }
508
509 dbus_bool_t
bus_policy_append_mandatory_rule(BusPolicy * policy,BusPolicyRule * rule)510 bus_policy_append_mandatory_rule (BusPolicy *policy,
511 BusPolicyRule *rule)
512 {
513 if (!_dbus_list_append (&policy->mandatory_rules, rule))
514 return FALSE;
515
516 bus_policy_rule_ref (rule);
517
518 return TRUE;
519 }
520
521
522
523 static DBusList**
get_list(DBusHashTable * hash,unsigned long key)524 get_list (DBusHashTable *hash,
525 unsigned long key)
526 {
527 DBusList **list;
528
529 list = _dbus_hash_table_lookup_uintptr (hash, key);
530
531 if (list == NULL)
532 {
533 list = dbus_new0 (DBusList*, 1);
534 if (list == NULL)
535 return NULL;
536
537 if (!_dbus_hash_table_insert_uintptr (hash, key, list))
538 {
539 dbus_free (list);
540 return NULL;
541 }
542 }
543
544 return list;
545 }
546
547 dbus_bool_t
bus_policy_append_user_rule(BusPolicy * policy,dbus_uid_t uid,BusPolicyRule * rule)548 bus_policy_append_user_rule (BusPolicy *policy,
549 dbus_uid_t uid,
550 BusPolicyRule *rule)
551 {
552 DBusList **list;
553
554 list = get_list (policy->rules_by_uid, uid);
555
556 if (list == NULL)
557 return FALSE;
558
559 if (!_dbus_list_append (list, rule))
560 return FALSE;
561
562 bus_policy_rule_ref (rule);
563
564 return TRUE;
565 }
566
567 dbus_bool_t
bus_policy_append_group_rule(BusPolicy * policy,dbus_gid_t gid,BusPolicyRule * rule)568 bus_policy_append_group_rule (BusPolicy *policy,
569 dbus_gid_t gid,
570 BusPolicyRule *rule)
571 {
572 DBusList **list;
573
574 list = get_list (policy->rules_by_gid, gid);
575
576 if (list == NULL)
577 return FALSE;
578
579 if (!_dbus_list_append (list, rule))
580 return FALSE;
581
582 bus_policy_rule_ref (rule);
583
584 return TRUE;
585 }
586
587 dbus_bool_t
bus_policy_append_console_rule(BusPolicy * policy,dbus_bool_t at_console,BusPolicyRule * rule)588 bus_policy_append_console_rule (BusPolicy *policy,
589 dbus_bool_t at_console,
590 BusPolicyRule *rule)
591 {
592 if (at_console)
593 {
594 if (!_dbus_list_append (&policy->at_console_true_rules, rule))
595 return FALSE;
596 }
597 else
598 {
599 if (!_dbus_list_append (&policy->at_console_false_rules, rule))
600 return FALSE;
601 }
602
603 bus_policy_rule_ref (rule);
604
605 return TRUE;
606
607 }
608
609 static dbus_bool_t
append_copy_of_policy_list(DBusList ** list,DBusList ** to_append)610 append_copy_of_policy_list (DBusList **list,
611 DBusList **to_append)
612 {
613 DBusList *link;
614 DBusList *tmp_list;
615
616 tmp_list = NULL;
617
618 /* Preallocate all our links */
619 link = _dbus_list_get_first_link (to_append);
620 while (link != NULL)
621 {
622 if (!_dbus_list_append (&tmp_list, link->data))
623 {
624 _dbus_list_clear (&tmp_list);
625 return FALSE;
626 }
627
628 link = _dbus_list_get_next_link (to_append, link);
629 }
630
631 /* Now append them */
632 while ((link = _dbus_list_pop_first_link (&tmp_list)))
633 {
634 bus_policy_rule_ref (link->data);
635 _dbus_list_append_link (list, link);
636 }
637
638 return TRUE;
639 }
640
641 static dbus_bool_t
merge_id_hash(DBusHashTable * dest,DBusHashTable * to_absorb)642 merge_id_hash (DBusHashTable *dest,
643 DBusHashTable *to_absorb)
644 {
645 DBusHashIter iter;
646
647 _dbus_hash_iter_init (to_absorb, &iter);
648 while (_dbus_hash_iter_next (&iter))
649 {
650 unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter);
651 DBusList **list = _dbus_hash_iter_get_value (&iter);
652 DBusList **target = get_list (dest, id);
653
654 if (target == NULL)
655 return FALSE;
656
657 if (!append_copy_of_policy_list (target, list))
658 return FALSE;
659 }
660
661 return TRUE;
662 }
663
664 dbus_bool_t
bus_policy_merge(BusPolicy * policy,BusPolicy * to_absorb)665 bus_policy_merge (BusPolicy *policy,
666 BusPolicy *to_absorb)
667 {
668 /* FIXME Not properly atomic, but as used for configuration files we
669 * don't rely on it quite so much.
670 */
671
672 if (!append_copy_of_policy_list (&policy->default_rules,
673 &to_absorb->default_rules))
674 return FALSE;
675
676 if (!append_copy_of_policy_list (&policy->mandatory_rules,
677 &to_absorb->mandatory_rules))
678 return FALSE;
679
680 if (!append_copy_of_policy_list (&policy->at_console_true_rules,
681 &to_absorb->at_console_true_rules))
682 return FALSE;
683
684 if (!append_copy_of_policy_list (&policy->at_console_false_rules,
685 &to_absorb->at_console_false_rules))
686 return FALSE;
687
688 if (!merge_id_hash (policy->rules_by_uid,
689 to_absorb->rules_by_uid))
690 return FALSE;
691
692 if (!merge_id_hash (policy->rules_by_gid,
693 to_absorb->rules_by_gid))
694 return FALSE;
695
696 return TRUE;
697 }
698
699 struct BusClientPolicy
700 {
701 int refcount;
702
703 DBusList *rules;
704 };
705
706 BusClientPolicy*
bus_client_policy_new(void)707 bus_client_policy_new (void)
708 {
709 BusClientPolicy *policy;
710
711 policy = dbus_new0 (BusClientPolicy, 1);
712 if (policy == NULL)
713 return NULL;
714
715 policy->refcount = 1;
716
717 return policy;
718 }
719
720 BusClientPolicy *
bus_client_policy_ref(BusClientPolicy * policy)721 bus_client_policy_ref (BusClientPolicy *policy)
722 {
723 _dbus_assert (policy->refcount > 0);
724
725 policy->refcount += 1;
726
727 return policy;
728 }
729
730 static void
rule_unref_foreach(void * data,void * user_data)731 rule_unref_foreach (void *data,
732 void *user_data)
733 {
734 BusPolicyRule *rule = data;
735
736 bus_policy_rule_unref (rule);
737 }
738
739 void
bus_client_policy_unref(BusClientPolicy * policy)740 bus_client_policy_unref (BusClientPolicy *policy)
741 {
742 _dbus_assert (policy->refcount > 0);
743
744 policy->refcount -= 1;
745
746 if (policy->refcount == 0)
747 {
748 _dbus_list_foreach (&policy->rules,
749 rule_unref_foreach,
750 NULL);
751
752 _dbus_list_clear (&policy->rules);
753
754 dbus_free (policy);
755 }
756 }
757
758 static void
remove_rules_by_type_up_to(BusClientPolicy * policy,BusPolicyRuleType type,DBusList * up_to)759 remove_rules_by_type_up_to (BusClientPolicy *policy,
760 BusPolicyRuleType type,
761 DBusList *up_to)
762 {
763 DBusList *link;
764
765 link = _dbus_list_get_first_link (&policy->rules);
766 while (link != up_to)
767 {
768 BusPolicyRule *rule = link->data;
769 DBusList *next = _dbus_list_get_next_link (&policy->rules, link);
770
771 if (rule->type == type)
772 {
773 _dbus_list_remove_link (&policy->rules, link);
774 bus_policy_rule_unref (rule);
775 }
776
777 link = next;
778 }
779 }
780
781 void
bus_client_policy_optimize(BusClientPolicy * policy)782 bus_client_policy_optimize (BusClientPolicy *policy)
783 {
784 DBusList *link;
785
786 /* The idea here is that if we have:
787 *
788 * <allow send_interface="foo.bar"/>
789 * <deny send_interface="*"/>
790 *
791 * (for example) the deny will always override the allow. So we
792 * delete the allow. Ditto for deny followed by allow, etc. This is
793 * a dumb thing to put in a config file, but the <include> feature
794 * of files allows for an "inheritance and override" pattern where
795 * it could make sense. If an included file wants to "start over"
796 * with a blanket deny, no point keeping the rules from the parent
797 * file.
798 */
799
800 _dbus_verbose ("Optimizing policy with %d rules\n",
801 _dbus_list_get_length (&policy->rules));
802
803 link = _dbus_list_get_first_link (&policy->rules);
804 while (link != NULL)
805 {
806 BusPolicyRule *rule;
807 DBusList *next;
808 dbus_bool_t remove_preceding;
809
810 next = _dbus_list_get_next_link (&policy->rules, link);
811 rule = link->data;
812
813 remove_preceding = FALSE;
814
815 _dbus_assert (rule != NULL);
816
817 switch (rule->type)
818 {
819 case BUS_POLICY_RULE_SEND:
820 remove_preceding =
821 rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
822 rule->d.send.path == NULL &&
823 rule->d.send.interface == NULL &&
824 rule->d.send.member == NULL &&
825 rule->d.send.error == NULL &&
826 rule->d.send.destination == NULL;
827 break;
828 case BUS_POLICY_RULE_RECEIVE:
829 remove_preceding =
830 rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
831 rule->d.receive.path == NULL &&
832 rule->d.receive.interface == NULL &&
833 rule->d.receive.member == NULL &&
834 rule->d.receive.error == NULL &&
835 rule->d.receive.origin == NULL;
836 break;
837 case BUS_POLICY_RULE_OWN:
838 remove_preceding =
839 rule->d.own.service_name == NULL;
840 break;
841
842 /* The other rule types don't appear in this list */
843 case BUS_POLICY_RULE_USER:
844 case BUS_POLICY_RULE_GROUP:
845 default:
846 _dbus_assert_not_reached ("invalid rule");
847 break;
848 }
849
850 if (remove_preceding)
851 remove_rules_by_type_up_to (policy, rule->type,
852 link);
853
854 link = next;
855 }
856
857 _dbus_verbose ("After optimization, policy has %d rules\n",
858 _dbus_list_get_length (&policy->rules));
859 }
860
861 dbus_bool_t
bus_client_policy_append_rule(BusClientPolicy * policy,BusPolicyRule * rule)862 bus_client_policy_append_rule (BusClientPolicy *policy,
863 BusPolicyRule *rule)
864 {
865 _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
866 rule, rule->type, policy);
867
868 if (!_dbus_list_append (&policy->rules, rule))
869 return FALSE;
870
871 bus_policy_rule_ref (rule);
872
873 return TRUE;
874 }
875
876 dbus_bool_t
bus_client_policy_check_can_send(BusClientPolicy * policy,BusRegistry * registry,dbus_bool_t requested_reply,DBusConnection * receiver,DBusMessage * message,dbus_int32_t * toggles,dbus_bool_t * log)877 bus_client_policy_check_can_send (BusClientPolicy *policy,
878 BusRegistry *registry,
879 dbus_bool_t requested_reply,
880 DBusConnection *receiver,
881 DBusMessage *message,
882 dbus_int32_t *toggles,
883 dbus_bool_t *log)
884 {
885 DBusList *link;
886 dbus_bool_t allowed;
887
888 /* policy->rules is in the order the rules appeared
889 * in the config file, i.e. last rule that applies wins
890 */
891
892 _dbus_verbose (" (policy) checking send rules\n");
893 *toggles = 0;
894
895 allowed = FALSE;
896 link = _dbus_list_get_first_link (&policy->rules);
897 while (link != NULL)
898 {
899 BusPolicyRule *rule = link->data;
900
901 link = _dbus_list_get_next_link (&policy->rules, link);
902
903 /* Rule is skipped if it specifies a different
904 * message name from the message, or a different
905 * destination from the message
906 */
907
908 if (rule->type != BUS_POLICY_RULE_SEND)
909 {
910 _dbus_verbose (" (policy) skipping non-send rule\n");
911 continue;
912 }
913
914 if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
915 {
916 if (dbus_message_get_type (message) != rule->d.send.message_type)
917 {
918 _dbus_verbose (" (policy) skipping rule for different message type\n");
919 continue;
920 }
921 }
922
923 /* If it's a reply, the requested_reply flag kicks in */
924 if (dbus_message_get_reply_serial (message) != 0)
925 {
926 /* for allow, requested_reply=true means the rule applies
927 * only when reply was requested. requested_reply=false means
928 * always allow.
929 */
930 if (!requested_reply && rule->allow && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
931 {
932 _dbus_verbose (" (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
933 continue;
934 }
935
936 /* for deny, requested_reply=false means the rule applies only
937 * when the reply was not requested. requested_reply=true means the
938 * rule always applies.
939 */
940 if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
941 {
942 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
943 continue;
944 }
945 }
946
947 if (rule->d.send.path != NULL)
948 {
949 if (dbus_message_get_path (message) != NULL &&
950 strcmp (dbus_message_get_path (message),
951 rule->d.send.path) != 0)
952 {
953 _dbus_verbose (" (policy) skipping rule for different path\n");
954 continue;
955 }
956 }
957
958 if (rule->d.send.interface != NULL)
959 {
960 /* The interface is optional in messages. For allow rules, if the message
961 * has no interface we want to skip the rule (and thus not allow);
962 * for deny rules, if the message has no interface we want to use the
963 * rule (and thus deny).
964 */
965 dbus_bool_t no_interface;
966
967 no_interface = dbus_message_get_interface (message) == NULL;
968
969 if ((no_interface && rule->allow) ||
970 (!no_interface &&
971 strcmp (dbus_message_get_interface (message),
972 rule->d.send.interface) != 0))
973 {
974 _dbus_verbose (" (policy) skipping rule for different interface\n");
975 continue;
976 }
977 }
978
979 if (rule->d.send.member != NULL)
980 {
981 if (dbus_message_get_member (message) != NULL &&
982 strcmp (dbus_message_get_member (message),
983 rule->d.send.member) != 0)
984 {
985 _dbus_verbose (" (policy) skipping rule for different member\n");
986 continue;
987 }
988 }
989
990 if (rule->d.send.error != NULL)
991 {
992 if (dbus_message_get_error_name (message) != NULL &&
993 strcmp (dbus_message_get_error_name (message),
994 rule->d.send.error) != 0)
995 {
996 _dbus_verbose (" (policy) skipping rule for different error name\n");
997 continue;
998 }
999 }
1000
1001 if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
1002 {
1003 if (dbus_message_get_destination (message) == NULL &&
1004 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
1005 {
1006 /* it's a broadcast */
1007 if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
1008 {
1009 _dbus_verbose (" (policy) skipping rule because message is a broadcast\n");
1010 continue;
1011 }
1012 }
1013 /* else it isn't a broadcast: there is some destination */
1014 else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
1015 {
1016 _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n");
1017 continue;
1018 }
1019 }
1020
1021 if (rule->d.send.destination != NULL)
1022 {
1023 /* receiver can be NULL for messages that are sent to the
1024 * message bus itself, we check the strings in that case as
1025 * built-in services don't have a DBusConnection but messages
1026 * to them have a destination service name.
1027 *
1028 * Similarly, receiver can be NULL when we're deciding whether
1029 * activation should be allowed; we make the authorization decision
1030 * on the assumption that the activated service will have the
1031 * requested name and no others.
1032 */
1033 if (receiver == NULL)
1034 {
1035 if (!dbus_message_has_destination (message,
1036 rule->d.send.destination))
1037 {
1038 _dbus_verbose (" (policy) skipping rule because message dest is not %s\n",
1039 rule->d.send.destination);
1040 continue;
1041 }
1042 }
1043 else
1044 {
1045 DBusString str;
1046 BusService *service;
1047
1048 _dbus_string_init_const (&str, rule->d.send.destination);
1049
1050 service = bus_registry_lookup (registry, &str);
1051 if (service == NULL)
1052 {
1053 _dbus_verbose (" (policy) skipping rule because dest %s doesn't exist\n",
1054 rule->d.send.destination);
1055 continue;
1056 }
1057
1058 if (!bus_service_has_owner (service, receiver))
1059 {
1060 _dbus_verbose (" (policy) skipping rule because dest %s isn't owned by receiver\n",
1061 rule->d.send.destination);
1062 continue;
1063 }
1064 }
1065 }
1066
1067 if (rule->d.send.min_fds > 0 ||
1068 rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1069 {
1070 unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
1071
1072 if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
1073 {
1074 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1075 "and that is outside range [%u,%u]",
1076 n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
1077 continue;
1078 }
1079 }
1080
1081 /* Use this rule */
1082 allowed = rule->allow;
1083 *log = rule->d.send.log;
1084 (*toggles)++;
1085
1086 _dbus_verbose (" (policy) used rule, allow now = %d\n",
1087 allowed);
1088 }
1089
1090 return allowed;
1091 }
1092
1093 /* See docs on what the args mean on bus_context_check_security_policy()
1094 * comment
1095 */
1096 dbus_bool_t
bus_client_policy_check_can_receive(BusClientPolicy * policy,BusRegistry * registry,dbus_bool_t requested_reply,DBusConnection * sender,DBusConnection * addressed_recipient,DBusConnection * proposed_recipient,DBusMessage * message,dbus_int32_t * toggles)1097 bus_client_policy_check_can_receive (BusClientPolicy *policy,
1098 BusRegistry *registry,
1099 dbus_bool_t requested_reply,
1100 DBusConnection *sender,
1101 DBusConnection *addressed_recipient,
1102 DBusConnection *proposed_recipient,
1103 DBusMessage *message,
1104 dbus_int32_t *toggles)
1105 {
1106 DBusList *link;
1107 dbus_bool_t allowed;
1108 dbus_bool_t eavesdropping;
1109
1110 eavesdropping =
1111 addressed_recipient != proposed_recipient &&
1112 dbus_message_get_destination (message) != NULL;
1113
1114 /* policy->rules is in the order the rules appeared
1115 * in the config file, i.e. last rule that applies wins
1116 */
1117
1118 _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
1119 *toggles = 0;
1120
1121 allowed = FALSE;
1122 link = _dbus_list_get_first_link (&policy->rules);
1123 while (link != NULL)
1124 {
1125 BusPolicyRule *rule = link->data;
1126
1127 link = _dbus_list_get_next_link (&policy->rules, link);
1128
1129 if (rule->type != BUS_POLICY_RULE_RECEIVE)
1130 {
1131 _dbus_verbose (" (policy) skipping non-receive rule\n");
1132 continue;
1133 }
1134
1135 if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
1136 {
1137 if (dbus_message_get_type (message) != rule->d.receive.message_type)
1138 {
1139 _dbus_verbose (" (policy) skipping rule for different message type\n");
1140 continue;
1141 }
1142 }
1143
1144 /* for allow, eavesdrop=false means the rule doesn't apply when
1145 * eavesdropping. eavesdrop=true means always allow.
1146 */
1147 if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
1148 {
1149 _dbus_verbose (" (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
1150 continue;
1151 }
1152
1153 /* for deny, eavesdrop=true means the rule applies only when
1154 * eavesdropping; eavesdrop=false means always deny.
1155 */
1156 if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
1157 {
1158 _dbus_verbose (" (policy) skipping deny rule since it only applies to eavesdropping\n");
1159 continue;
1160 }
1161
1162 /* If it's a reply, the requested_reply flag kicks in */
1163 if (dbus_message_get_reply_serial (message) != 0)
1164 {
1165 /* for allow, requested_reply=true means the rule applies
1166 * only when reply was requested. requested_reply=false means
1167 * always allow.
1168 */
1169 if (!requested_reply && rule->allow && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop)
1170 {
1171 _dbus_verbose (" (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
1172 continue;
1173 }
1174
1175 /* for deny, requested_reply=false means the rule applies only
1176 * when the reply was not requested. requested_reply=true means the
1177 * rule always applies.
1178 */
1179 if (requested_reply && !rule->allow && !rule->d.receive.requested_reply)
1180 {
1181 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n");
1182 continue;
1183 }
1184 }
1185
1186 if (rule->d.receive.path != NULL)
1187 {
1188 if (dbus_message_get_path (message) != NULL &&
1189 strcmp (dbus_message_get_path (message),
1190 rule->d.receive.path) != 0)
1191 {
1192 _dbus_verbose (" (policy) skipping rule for different path\n");
1193 continue;
1194 }
1195 }
1196
1197 if (rule->d.receive.interface != NULL)
1198 {
1199 /* The interface is optional in messages. For allow rules, if the message
1200 * has no interface we want to skip the rule (and thus not allow);
1201 * for deny rules, if the message has no interface we want to use the
1202 * rule (and thus deny).
1203 */
1204 dbus_bool_t no_interface;
1205
1206 no_interface = dbus_message_get_interface (message) == NULL;
1207
1208 if ((no_interface && rule->allow) ||
1209 (!no_interface &&
1210 strcmp (dbus_message_get_interface (message),
1211 rule->d.receive.interface) != 0))
1212 {
1213 _dbus_verbose (" (policy) skipping rule for different interface\n");
1214 continue;
1215 }
1216 }
1217
1218 if (rule->d.receive.member != NULL)
1219 {
1220 if (dbus_message_get_member (message) != NULL &&
1221 strcmp (dbus_message_get_member (message),
1222 rule->d.receive.member) != 0)
1223 {
1224 _dbus_verbose (" (policy) skipping rule for different member\n");
1225 continue;
1226 }
1227 }
1228
1229 if (rule->d.receive.error != NULL)
1230 {
1231 if (dbus_message_get_error_name (message) != NULL &&
1232 strcmp (dbus_message_get_error_name (message),
1233 rule->d.receive.error) != 0)
1234 {
1235 _dbus_verbose (" (policy) skipping rule for different error name\n");
1236 continue;
1237 }
1238 }
1239
1240 if (rule->d.receive.origin != NULL)
1241 {
1242 /* sender can be NULL for messages that originate from the
1243 * message bus itself, we check the strings in that case as
1244 * built-in services don't have a DBusConnection but will
1245 * still set the sender on their messages.
1246 */
1247 if (sender == NULL)
1248 {
1249 if (!dbus_message_has_sender (message,
1250 rule->d.receive.origin))
1251 {
1252 _dbus_verbose (" (policy) skipping rule because message sender is not %s\n",
1253 rule->d.receive.origin);
1254 continue;
1255 }
1256 }
1257 else
1258 {
1259 BusService *service;
1260 DBusString str;
1261
1262 _dbus_string_init_const (&str, rule->d.receive.origin);
1263
1264 service = bus_registry_lookup (registry, &str);
1265
1266 if (service == NULL)
1267 {
1268 _dbus_verbose (" (policy) skipping rule because origin %s doesn't exist\n",
1269 rule->d.receive.origin);
1270 continue;
1271 }
1272
1273 if (!bus_service_has_owner (service, sender))
1274 {
1275 _dbus_verbose (" (policy) skipping rule because origin %s isn't owned by sender\n",
1276 rule->d.receive.origin);
1277 continue;
1278 }
1279 }
1280 }
1281
1282 if (rule->d.receive.min_fds > 0 ||
1283 rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1284 {
1285 unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
1286
1287 if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
1288 {
1289 _dbus_verbose (" (policy) skipping rule because message has %u fds "
1290 "and that is outside range [%u,%u]",
1291 n_fds, rule->d.receive.min_fds,
1292 rule->d.receive.max_fds);
1293 continue;
1294 }
1295 }
1296
1297 /* Use this rule */
1298 allowed = rule->allow;
1299 (*toggles)++;
1300
1301 _dbus_verbose (" (policy) used rule, allow now = %d\n",
1302 allowed);
1303 }
1304
1305 return allowed;
1306 }
1307
1308
1309
1310 static dbus_bool_t
bus_rules_check_can_own(DBusList * rules,const DBusString * service_name)1311 bus_rules_check_can_own (DBusList *rules,
1312 const DBusString *service_name)
1313 {
1314 DBusList *link;
1315 dbus_bool_t allowed;
1316
1317 /* rules is in the order the rules appeared
1318 * in the config file, i.e. last rule that applies wins
1319 */
1320
1321 allowed = FALSE;
1322 link = _dbus_list_get_first_link (&rules);
1323 while (link != NULL)
1324 {
1325 BusPolicyRule *rule = link->data;
1326
1327 link = _dbus_list_get_next_link (&rules, link);
1328
1329 /* Rule is skipped if it specifies a different service name from
1330 * the desired one.
1331 */
1332
1333 if (rule->type != BUS_POLICY_RULE_OWN)
1334 continue;
1335
1336 if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
1337 {
1338 if (!_dbus_string_equal_c_str (service_name,
1339 rule->d.own.service_name))
1340 continue;
1341 }
1342 else if (rule->d.own.prefix)
1343 {
1344 const char *data;
1345 char next_char;
1346 if (!_dbus_string_starts_with_c_str (service_name,
1347 rule->d.own.service_name))
1348 continue;
1349
1350 data = _dbus_string_get_const_data (service_name);
1351 next_char = data[strlen (rule->d.own.service_name)];
1352 if (next_char != '\0' && next_char != '.')
1353 continue;
1354 }
1355
1356 /* Use this rule */
1357 allowed = rule->allow;
1358 }
1359
1360 return allowed;
1361 }
1362
1363 dbus_bool_t
bus_client_policy_check_can_own(BusClientPolicy * policy,const DBusString * service_name)1364 bus_client_policy_check_can_own (BusClientPolicy *policy,
1365 const DBusString *service_name)
1366 {
1367 return bus_rules_check_can_own (policy->rules, service_name);
1368 }
1369
1370 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1371 dbus_bool_t
bus_policy_check_can_own(BusPolicy * policy,const DBusString * service_name)1372 bus_policy_check_can_own (BusPolicy *policy,
1373 const DBusString *service_name)
1374 {
1375 return bus_rules_check_can_own (policy->default_rules, service_name);
1376 }
1377 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
1378
1379