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