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