2004-05-29 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   /* Not properly atomic, but as used for configuration files
598    * we don't rely on it.
599    */  
600   if (!append_copy_of_policy_list (&policy->default_rules,
601                                    &to_absorb->default_rules))
602     return FALSE;
603   
604   if (!append_copy_of_policy_list (&policy->mandatory_rules,
605                                    &to_absorb->mandatory_rules))
606     return FALSE;
607
608   if (!merge_id_hash (policy->rules_by_uid,
609                       to_absorb->rules_by_uid))
610     return FALSE;
611   
612   if (!merge_id_hash (policy->rules_by_gid,
613                       to_absorb->rules_by_gid))
614     return FALSE;
615
616   return TRUE;
617 }
618
619 struct BusClientPolicy
620 {
621   int refcount;
622
623   DBusList *rules;
624 };
625
626 BusClientPolicy*
627 bus_client_policy_new (void)
628 {
629   BusClientPolicy *policy;
630
631   policy = dbus_new0 (BusClientPolicy, 1);
632   if (policy == NULL)
633     return NULL;
634
635   policy->refcount = 1;
636
637   return policy;
638 }
639
640 BusClientPolicy *
641 bus_client_policy_ref (BusClientPolicy *policy)
642 {
643   _dbus_assert (policy->refcount > 0);
644
645   policy->refcount += 1;
646
647   return policy;
648 }
649
650 static void
651 rule_unref_foreach (void *data,
652                     void *user_data)
653 {
654   BusPolicyRule *rule = data;
655
656   bus_policy_rule_unref (rule);
657 }
658
659 void
660 bus_client_policy_unref (BusClientPolicy *policy)
661 {
662   _dbus_assert (policy->refcount > 0);
663
664   policy->refcount -= 1;
665
666   if (policy->refcount == 0)
667     {
668       _dbus_list_foreach (&policy->rules,
669                           rule_unref_foreach,
670                           NULL);
671
672       _dbus_list_clear (&policy->rules);
673       
674       dbus_free (policy);
675     }
676 }
677
678 static void
679 remove_rules_by_type_up_to (BusClientPolicy   *policy,
680                             BusPolicyRuleType  type,
681                             DBusList          *up_to)
682 {
683   DBusList *link;
684
685   link = _dbus_list_get_first_link (&policy->rules);
686   while (link != up_to)
687     {
688       BusPolicyRule *rule = link->data;
689       DBusList *next = _dbus_list_get_next_link (&policy->rules, link);
690
691       if (rule->type == type)
692         {
693           _dbus_list_remove_link (&policy->rules, link);
694           bus_policy_rule_unref (rule);
695         }
696       
697       link = next;
698     }
699 }
700
701 void
702 bus_client_policy_optimize (BusClientPolicy *policy)
703 {
704   DBusList *link;
705
706   /* The idea here is that if we have:
707    * 
708    * <allow send_interface="foo.bar"/>
709    * <deny send_interface="*"/>
710    *
711    * (for example) the deny will always override the allow.  So we
712    * delete the allow. Ditto for deny followed by allow, etc. This is
713    * a dumb thing to put in a config file, but the <include> feature
714    * of files allows for an "inheritance and override" pattern where
715    * it could make sense. If an included file wants to "start over"
716    * with a blanket deny, no point keeping the rules from the parent
717    * file.
718    */
719
720   _dbus_verbose ("Optimizing policy with %d rules\n",
721                  _dbus_list_get_length (&policy->rules));
722   
723   link = _dbus_list_get_first_link (&policy->rules);
724   while (link != NULL)
725     {
726       BusPolicyRule *rule;
727       DBusList *next;
728       dbus_bool_t remove_preceding;
729
730       next = _dbus_list_get_next_link (&policy->rules, link);
731       rule = link->data;
732       
733       remove_preceding = FALSE;
734
735       _dbus_assert (rule != NULL);
736       
737       switch (rule->type)
738         {
739         case BUS_POLICY_RULE_SEND:
740           remove_preceding =
741             rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
742             rule->d.send.path == NULL &&
743             rule->d.send.interface == NULL &&
744             rule->d.send.member == NULL &&
745             rule->d.send.error == NULL &&
746             rule->d.send.destination == NULL;
747           break;
748         case BUS_POLICY_RULE_RECEIVE:
749           remove_preceding =
750             rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
751             rule->d.receive.path == NULL &&
752             rule->d.receive.interface == NULL &&
753             rule->d.receive.member == NULL &&
754             rule->d.receive.error == NULL &&
755             rule->d.receive.origin == NULL;
756           break;
757         case BUS_POLICY_RULE_OWN:
758           remove_preceding =
759             rule->d.own.service_name == NULL;
760           break;
761         case BUS_POLICY_RULE_USER:
762         case BUS_POLICY_RULE_GROUP:
763           _dbus_assert_not_reached ("invalid rule");
764           break;
765         }
766
767       if (remove_preceding)
768         remove_rules_by_type_up_to (policy, rule->type,
769                                     link);
770       
771       link = next;
772     }
773
774   _dbus_verbose ("After optimization, policy has %d rules\n",
775                  _dbus_list_get_length (&policy->rules));
776 }
777
778 dbus_bool_t
779 bus_client_policy_append_rule (BusClientPolicy *policy,
780                                BusPolicyRule   *rule)
781 {
782   _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
783                  rule, rule->type, policy);
784   
785   if (!_dbus_list_append (&policy->rules, rule))
786     return FALSE;
787
788   bus_policy_rule_ref (rule);
789
790   return TRUE;
791 }
792
793 dbus_bool_t
794 bus_client_policy_check_can_send (BusClientPolicy *policy,
795                                   BusRegistry     *registry,
796                                   dbus_bool_t      requested_reply,
797                                   DBusConnection  *receiver,
798                                   DBusMessage     *message)
799 {
800   DBusList *link;
801   dbus_bool_t allowed;
802   
803   /* policy->rules is in the order the rules appeared
804    * in the config file, i.e. last rule that applies wins
805    */
806
807   _dbus_verbose ("  (policy) checking send rules\n");
808   
809   allowed = FALSE;
810   link = _dbus_list_get_first_link (&policy->rules);
811   while (link != NULL)
812     {
813       BusPolicyRule *rule = link->data;
814
815       link = _dbus_list_get_next_link (&policy->rules, link);
816       
817       /* Rule is skipped if it specifies a different
818        * message name from the message, or a different
819        * destination from the message
820        */
821       
822       if (rule->type != BUS_POLICY_RULE_SEND)
823         {
824           _dbus_verbose ("  (policy) skipping non-send rule\n");
825           continue;
826         }
827
828       if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
829         {
830           if (dbus_message_get_type (message) != rule->d.send.message_type)
831             {
832               _dbus_verbose ("  (policy) skipping rule for different message type\n");
833               continue;
834             }
835         }
836
837       /* If it's a reply, the requested_reply flag kicks in */
838       if (dbus_message_get_reply_serial (message) != 0)
839         {
840           /* for allow, requested_reply=true means the rule applies
841            * only when reply was requested. requested_reply=false means
842            * always allow.
843            */
844           if (!requested_reply && rule->allow && rule->d.send.requested_reply)
845             {
846               _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies\n");
847               continue;
848             }
849
850           /* for deny, requested_reply=false means the rule applies only
851            * when the reply was not requested. requested_reply=true means the
852            * rule always applies.
853            */
854           if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
855             {
856               _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
857               continue;
858             }
859         }
860       
861       if (rule->d.send.path != NULL)
862         {
863           if (dbus_message_get_path (message) != NULL &&
864               strcmp (dbus_message_get_path (message),
865                       rule->d.send.path) != 0)
866             {
867               _dbus_verbose ("  (policy) skipping rule for different path\n");
868               continue;
869             }
870         }
871       
872       if (rule->d.send.interface != NULL)
873         {
874           if (dbus_message_get_interface (message) != NULL &&
875               strcmp (dbus_message_get_interface (message),
876                       rule->d.send.interface) != 0)
877             {
878               _dbus_verbose ("  (policy) skipping rule for different interface\n");
879               continue;
880             }
881         }
882
883       if (rule->d.send.member != NULL)
884         {
885           if (dbus_message_get_member (message) != NULL &&
886               strcmp (dbus_message_get_member (message),
887                       rule->d.send.member) != 0)
888             {
889               _dbus_verbose ("  (policy) skipping rule for different member\n");
890               continue;
891             }
892         }
893
894       if (rule->d.send.error != NULL)
895         {
896           if (dbus_message_get_error_name (message) != NULL &&
897               strcmp (dbus_message_get_error_name (message),
898                       rule->d.send.error) != 0)
899             {
900               _dbus_verbose ("  (policy) skipping rule for different error name\n");
901               continue;
902             }
903         }
904       
905       if (rule->d.send.destination != NULL)
906         {
907           /* receiver can be NULL for messages that are sent to the
908            * message bus itself, we check the strings in that case as
909            * built-in services don't have a DBusConnection but messages
910            * to them have a destination service name.
911            */
912           if (receiver == NULL)
913             {
914               if (!dbus_message_has_destination (message,
915                                                  rule->d.send.destination))
916                 {
917                   _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
918                                  rule->d.send.destination);
919                   continue;
920                 }
921             }
922           else
923             {
924               DBusString str;
925               BusService *service;
926               
927               _dbus_string_init_const (&str, rule->d.send.destination);
928               
929               service = bus_registry_lookup (registry, &str);
930               if (service == NULL)
931                 {
932                   _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
933                                  rule->d.send.destination);
934                   continue;
935                 }
936
937               if (!bus_service_has_owner (service, receiver))
938                 {
939                   _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
940                                  rule->d.send.destination);
941                   continue;
942                 }
943             }
944         }
945
946       /* Use this rule */
947       allowed = rule->allow;
948
949       _dbus_verbose ("  (policy) used rule, allow now = %d\n",
950                      allowed);
951     }
952
953   return allowed;
954 }
955
956 /* See docs on what the args mean on bus_context_check_security_policy()
957  * comment
958  */
959 dbus_bool_t
960 bus_client_policy_check_can_receive (BusClientPolicy *policy,
961                                      BusRegistry     *registry,
962                                      dbus_bool_t      requested_reply,
963                                      DBusConnection  *sender,
964                                      DBusConnection  *addressed_recipient,
965                                      DBusConnection  *proposed_recipient,
966                                      DBusMessage     *message)
967 {
968   DBusList *link;
969   dbus_bool_t allowed;
970   dbus_bool_t eavesdropping;
971
972   eavesdropping =
973     addressed_recipient != proposed_recipient &&
974     dbus_message_get_destination (message) != NULL;
975   
976   /* policy->rules is in the order the rules appeared
977    * in the config file, i.e. last rule that applies wins
978    */
979
980   _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
981   
982   allowed = FALSE;
983   link = _dbus_list_get_first_link (&policy->rules);
984   while (link != NULL)
985     {
986       BusPolicyRule *rule = link->data;
987
988       link = _dbus_list_get_next_link (&policy->rules, link);      
989       
990       if (rule->type != BUS_POLICY_RULE_RECEIVE)
991         {
992           _dbus_verbose ("  (policy) skipping non-receive rule\n");
993           continue;
994         }
995
996       if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
997         {
998           if (dbus_message_get_type (message) != rule->d.receive.message_type)
999             {
1000               _dbus_verbose ("  (policy) skipping rule for different message type\n");
1001               continue;
1002             }
1003         }
1004
1005       /* for allow, eavesdrop=false means the rule doesn't apply when
1006        * eavesdropping. eavesdrop=true means always allow.
1007        */
1008       if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
1009         {
1010           _dbus_verbose ("  (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
1011           continue;
1012         }
1013
1014       /* for deny, eavesdrop=true means the rule applies only when
1015        * eavesdropping; eavesdrop=false means always deny.
1016        */
1017       if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
1018         {
1019           _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
1020           continue;
1021         }
1022
1023       /* If it's a reply, the requested_reply flag kicks in */
1024       if (dbus_message_get_reply_serial (message) != 0)
1025         {
1026           /* for allow, requested_reply=true means the rule applies
1027            * only when reply was requested. requested_reply=false means
1028            * always allow.
1029            */
1030           if (!requested_reply && rule->allow && rule->d.receive.requested_reply)
1031             {
1032               _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies\n");
1033               continue;
1034             }
1035
1036           /* for deny, requested_reply=false means the rule applies only
1037            * when the reply was not requested. requested_reply=true means the
1038            * rule always applies.
1039            */
1040           if (requested_reply && !rule->allow && !rule->d.receive.requested_reply)
1041             {
1042               _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
1043               continue;
1044             }
1045         }
1046       
1047       if (rule->d.receive.path != NULL)
1048         {
1049           if (dbus_message_get_path (message) != NULL &&
1050               strcmp (dbus_message_get_path (message),
1051                       rule->d.receive.path) != 0)
1052             {
1053               _dbus_verbose ("  (policy) skipping rule for different path\n");
1054               continue;
1055             }
1056         }
1057       
1058       if (rule->d.receive.interface != NULL)
1059         {
1060           if (dbus_message_get_interface (message) != NULL &&
1061               strcmp (dbus_message_get_interface (message),
1062                       rule->d.receive.interface) != 0)
1063             {
1064               _dbus_verbose ("  (policy) skipping rule for different interface\n");
1065               continue;
1066             }
1067         }      
1068
1069       if (rule->d.receive.member != NULL)
1070         {
1071           if (dbus_message_get_member (message) != NULL &&
1072               strcmp (dbus_message_get_member (message),
1073                       rule->d.receive.member) != 0)
1074             {
1075               _dbus_verbose ("  (policy) skipping rule for different member\n");
1076               continue;
1077             }
1078         }
1079
1080       if (rule->d.receive.error != NULL)
1081         {
1082           if (dbus_message_get_error_name (message) != NULL &&
1083               strcmp (dbus_message_get_error_name (message),
1084                       rule->d.receive.error) != 0)
1085             {
1086               _dbus_verbose ("  (policy) skipping rule for different error name\n");
1087               continue;
1088             }
1089         }
1090       
1091       if (rule->d.receive.origin != NULL)
1092         {          
1093           /* sender can be NULL for messages that originate from the
1094            * message bus itself, we check the strings in that case as
1095            * built-in services don't have a DBusConnection but will
1096            * still set the sender on their messages.
1097            */
1098           if (sender == NULL)
1099             {
1100               if (!dbus_message_has_sender (message,
1101                                             rule->d.receive.origin))
1102                 {
1103                   _dbus_verbose ("  (policy) skipping rule because message sender is not %s\n",
1104                                  rule->d.receive.origin);
1105                   continue;
1106                 }
1107             }
1108           else
1109             {
1110               BusService *service;
1111               DBusString str;
1112
1113               _dbus_string_init_const (&str, rule->d.receive.origin);
1114               
1115               service = bus_registry_lookup (registry, &str);
1116               
1117               if (service == NULL)
1118                 {
1119                   _dbus_verbose ("  (policy) skipping rule because origin %s doesn't exist\n",
1120                                  rule->d.receive.origin);
1121                   continue;
1122                 }
1123
1124               if (!bus_service_has_owner (service, sender))
1125                 {
1126                   _dbus_verbose ("  (policy) skipping rule because origin %s isn't owned by sender\n",
1127                                  rule->d.receive.origin);
1128                   continue;
1129                 }
1130             }
1131         }
1132       
1133       /* Use this rule */
1134       allowed = rule->allow;
1135
1136       _dbus_verbose ("  (policy) used rule, allow now = %d\n",
1137                      allowed);
1138     }
1139
1140   return allowed;
1141 }
1142
1143 dbus_bool_t
1144 bus_client_policy_check_can_own (BusClientPolicy  *policy,
1145                                  DBusConnection   *connection,
1146                                  const DBusString *service_name)
1147 {
1148   DBusList *link;
1149   dbus_bool_t allowed;
1150   
1151   /* policy->rules is in the order the rules appeared
1152    * in the config file, i.e. last rule that applies wins
1153    */
1154
1155   allowed = FALSE;
1156   link = _dbus_list_get_first_link (&policy->rules);
1157   while (link != NULL)
1158     {
1159       BusPolicyRule *rule = link->data;
1160
1161       link = _dbus_list_get_next_link (&policy->rules, link);
1162       
1163       /* Rule is skipped if it specifies a different service name from
1164        * the desired one.
1165        */
1166       
1167       if (rule->type != BUS_POLICY_RULE_OWN)
1168         continue;
1169
1170       if (rule->d.own.service_name != NULL)
1171         {
1172           if (!_dbus_string_equal_c_str (service_name,
1173                                          rule->d.own.service_name))
1174             continue;
1175         }
1176
1177       /* Use this rule */
1178       allowed = rule->allow;
1179     }
1180
1181   return allowed;
1182 }
1183
1184 #ifdef DBUS_BUILD_TESTS
1185
1186 dbus_bool_t
1187 bus_policy_test (const DBusString *test_data_dir)
1188 {
1189   /* This doesn't do anything for now because I decided to do it in
1190    * dispatch.c instead by having some of the clients in dispatch.c
1191    * have particular policies applied to them.
1192    */
1193   
1194   return TRUE;
1195 }
1196
1197 #endif /* DBUS_BUILD_TESTS */