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