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