Remove legacy smack support, keep upstream smack 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           /* receiver can be NULL for messages that are sent to the
1007            * message bus itself, we check the strings in that case as
1008            * built-in services don't have a DBusConnection but messages
1009            * to them have a destination service name.
1010            */
1011           if (receiver == NULL)
1012             {
1013               if (!dbus_message_has_destination (message,
1014                                                  rule->d.send.destination))
1015                 {
1016                   _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
1017                                  rule->d.send.destination);
1018                   continue;
1019                 }
1020             }
1021           else
1022             {
1023               DBusString str;
1024               BusService *service;
1025               
1026               _dbus_string_init_const (&str, rule->d.send.destination);
1027               
1028               service = bus_registry_lookup (registry, &str);
1029               if (service == NULL)
1030                 {
1031                   _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
1032                                  rule->d.send.destination);
1033                   continue;
1034                 }
1035
1036               if (!bus_service_has_owner (service, receiver))
1037                 {
1038                   _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
1039                                  rule->d.send.destination);
1040                   continue;
1041                 }
1042             }
1043         }
1044
1045       /* Use this rule */
1046       switch (rule->access)
1047         {
1048         case BUS_POLICY_RULE_ACCESS_ALLOW:
1049           result = BUS_RESULT_TRUE;
1050           break;
1051         case BUS_POLICY_RULE_ACCESS_DENY:
1052           result = BUS_RESULT_FALSE;
1053           break;
1054         case BUS_POLICY_RULE_ACCESS_CHECK:
1055           result = BUS_RESULT_LATER;
1056           privilege = rule->privilege;
1057           break;
1058         }
1059
1060       *log = rule->d.send.log;
1061       (*toggles)++;
1062
1063       _dbus_verbose ("  (policy) used rule, result now = %d\n",
1064                      result);
1065     }
1066
1067   if (result == BUS_RESULT_LATER)
1068     {
1069       BusContext *context = bus_connection_get_context(sender);
1070       BusCheck *check = bus_context_get_check(context);
1071
1072       result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
1073           privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
1074       if (result == BUS_RESULT_LATER && deferred_message != NULL)
1075         bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1076             *toggles, privilege);
1077     }
1078   else
1079     privilege = NULL;
1080
1081   if (privilege_param != NULL)
1082     *privilege_param = privilege;
1083
1084   return result;
1085 }
1086
1087 /* See docs on what the args mean on bus_context_check_security_policy()
1088  * comment
1089  */
1090 BusResult
1091 bus_client_policy_check_can_receive (BusClientPolicy     *policy,
1092                                      BusRegistry         *registry,
1093                                      dbus_bool_t          requested_reply,
1094                                      DBusConnection      *sender,
1095                                      DBusConnection      *addressed_recipient,
1096                                      DBusConnection      *proposed_recipient,
1097                                      DBusMessage         *message,
1098                                      dbus_int32_t        *toggles,
1099                                      const char         **privilege_param,
1100                                      BusDeferredMessage **deferred_message)
1101 {
1102   DBusList *link;
1103   dbus_bool_t eavesdropping;
1104   BusResult result;
1105   const char *privilege;
1106
1107   eavesdropping =
1108     addressed_recipient != proposed_recipient &&
1109     dbus_message_get_destination (message) != NULL;
1110   
1111   /* policy->rules is in the order the rules appeared
1112    * in the config file, i.e. last rule that applies wins
1113    */
1114
1115   _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
1116   *toggles = 0;
1117   
1118   result = BUS_RESULT_FALSE;
1119   link = _dbus_list_get_first_link (&policy->rules);
1120   while (link != NULL)
1121     {
1122       BusPolicyRule *rule = link->data;
1123
1124       link = _dbus_list_get_next_link (&policy->rules, link);      
1125       
1126       if (rule->type != BUS_POLICY_RULE_RECEIVE)
1127         {
1128           _dbus_verbose ("  (policy) skipping non-receive rule\n");
1129           continue;
1130         }
1131
1132       if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
1133         {
1134           if (dbus_message_get_type (message) != rule->d.receive.message_type)
1135             {
1136               _dbus_verbose ("  (policy) skipping rule for different message type\n");
1137               continue;
1138             }
1139         }
1140
1141
1142       /* for allow or check, eavesdrop=false means the rule doesn't apply when
1143        * eavesdropping. eavesdrop=true means the rule always applies
1144        */
1145       if (eavesdropping && rule->access != BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.eavesdrop)
1146         {
1147           _dbus_verbose ("  (policy) skipping %s rule since it doesn't apply to eavesdropping\n",
1148               rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
1149           continue;
1150         }
1151
1152       /* for deny, eavesdrop=true means the rule applies only when
1153        * eavesdropping; eavesdrop=false means always deny.
1154        */
1155       if (!eavesdropping && rule->access == BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.eavesdrop)
1156         {
1157           _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
1158           continue;
1159         }
1160
1161       /* If it's a reply, the requested_reply flag kicks in */
1162       if (dbus_message_get_reply_serial (message) != 0)
1163         {
1164           /* for allow or check requested_reply=true means the rule applies
1165            * only when reply was requested. requested_reply=false means the
1166            * rule always applies
1167            */
1168           if (!requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
1169             {
1170               _dbus_verbose ("  (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
1171                   rule->access == BUS_POLICY_RULE_ACCESS_DENY ? "allow" : "deny");
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->access == BUS_POLICY_RULE_ACCESS_DENY && !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). Check rules are treated like allow rules.
1203            */
1204           dbus_bool_t no_interface;
1205
1206           no_interface = dbus_message_get_interface (message) == NULL;
1207           
1208           if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
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       /* Use this rule */
1283       switch (rule->access)
1284       {
1285         case BUS_POLICY_RULE_ACCESS_ALLOW:
1286           result = BUS_RESULT_TRUE;
1287           break;
1288         case BUS_POLICY_RULE_ACCESS_DENY:
1289           result = BUS_RESULT_FALSE;
1290           break;
1291         case BUS_POLICY_RULE_ACCESS_CHECK:
1292           result = BUS_RESULT_LATER;
1293           privilege = rule->privilege;
1294           break;
1295       }
1296
1297       (*toggles)++;
1298
1299       _dbus_verbose ("  (policy) used rule, result now = %d\n",
1300                      result);
1301     }
1302
1303
1304   if (result == BUS_RESULT_LATER)
1305     {
1306       BusContext *context = bus_connection_get_context(proposed_recipient);
1307       BusCheck *check = bus_context_get_check(context);
1308
1309       result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
1310                  privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
1311       if (result == BUS_RESULT_LATER && deferred_message != NULL)
1312         bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1313                     *toggles, privilege);
1314     }
1315   else
1316       privilege = NULL;
1317
1318   if (privilege_param != NULL)
1319      *privilege_param = privilege;
1320
1321   return result;
1322 }
1323
1324
1325
1326 static BusResult
1327 bus_rules_check_can_own (DBusList *rules,
1328                          const DBusString *service_name,
1329                          DBusConnection   *connection,
1330                          DBusMessage      *message)
1331 {
1332   DBusList *link;
1333   BusResult result;
1334   const char *privilege;
1335   
1336   /* rules is in the order the rules appeared
1337    * in the config file, i.e. last rule that applies wins
1338    */
1339
1340   result = BUS_RESULT_FALSE;
1341   link = _dbus_list_get_first_link (&rules);
1342   while (link != NULL)
1343     {
1344       BusPolicyRule *rule = link->data;
1345
1346       link = _dbus_list_get_next_link (&rules, link);
1347       
1348       /* Rule is skipped if it specifies a different service name from
1349        * the desired one.
1350        */
1351       
1352       if (rule->type != BUS_POLICY_RULE_OWN)
1353         continue;
1354
1355       if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
1356         {
1357           if (!_dbus_string_equal_c_str (service_name,
1358                                          rule->d.own.service_name))
1359             continue;
1360         }
1361       else if (rule->d.own.prefix)
1362         {
1363           const char *data;
1364           char next_char;
1365           if (!_dbus_string_starts_with_c_str (service_name,
1366                                                rule->d.own.service_name))
1367             continue;
1368
1369           data = _dbus_string_get_const_data (service_name);
1370           next_char = data[strlen (rule->d.own.service_name)];
1371           if (next_char != '\0' && next_char != '.')
1372             continue;
1373         }
1374
1375       /* Use this rule */
1376       switch (rule->access)
1377       {
1378       case BUS_POLICY_RULE_ACCESS_ALLOW:
1379         result = BUS_RESULT_TRUE;
1380         break;
1381       case BUS_POLICY_RULE_ACCESS_DENY:
1382         result = BUS_RESULT_FALSE;
1383         break;
1384       case BUS_POLICY_RULE_ACCESS_CHECK:
1385         result = BUS_RESULT_LATER;
1386         privilege = rule->privilege;
1387         break;
1388       }
1389     }
1390
1391   if (result == BUS_RESULT_LATER)
1392     {
1393       BusContext *context = bus_connection_get_context(connection);
1394       BusCheck *check = bus_context_get_check(context);
1395       BusDeferredMessage *deferred_message;
1396
1397       result = bus_check_privilege(check, message, connection, NULL, NULL,
1398           privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message);
1399       if (result == BUS_RESULT_LATER)
1400         {
1401           bus_deferred_message_disable_sender(deferred_message);
1402         }
1403     }
1404
1405   return result;
1406 }
1407
1408 BusResult
1409 bus_client_policy_check_can_own (BusClientPolicy  *policy,
1410                                  const DBusString *service_name,
1411                                  DBusConnection   *connection,
1412                                  DBusMessage      *message)
1413 {
1414   return bus_rules_check_can_own (policy->rules, service_name, connection, message);
1415 }
1416
1417 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1418 dbus_bool_t
1419 bus_policy_check_can_own (BusPolicy  *policy,
1420                           const DBusString *service_name)
1421 {
1422   return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL);
1423 }
1424 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
1425