bus/policy: separate prefix rules in default context
[platform/upstream/dbus.git] / bus / policy.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* policy.c  Bus security policy
3  *
4  * Copyright (C) 2003, 2004  Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <config.h>
25 #include "check.h"
26 #include "policy.h"
27 #include "services.h"
28 #include "test.h"
29 #include "utils.h"
30 #include <dbus/dbus-list.h>
31 #include <dbus/dbus-hash.h>
32 #include <dbus/dbus-internals.h>
33 #include <dbus/dbus-message-internal.h>
34 #include <dbus/dbus-connection-internal.h>
35
36 struct BusClientPolicy
37 {
38   int refcount;
39
40   BusPolicy *policy;
41   unsigned long *groups;
42   int n_groups;
43   dbus_uid_t uid;
44   dbus_bool_t uid_set;
45   dbus_bool_t at_console;
46 };
47
48 BusPolicyRule*
49 bus_policy_rule_new (BusPolicyRuleType type,
50                      BusPolicyRuleAccess access)
51 {
52   BusPolicyRule *rule;
53
54   rule = dbus_new0 (BusPolicyRule, 1);
55   if (rule == NULL)
56     return NULL;
57
58   rule->type = type;
59   rule->refcount = 1;
60   rule->access = access;
61
62   switch (rule->type)
63     {
64     case BUS_POLICY_RULE_USER:
65       rule->d.user.uid = DBUS_UID_UNSET;
66       break;
67     case BUS_POLICY_RULE_GROUP:
68       rule->d.group.gid = DBUS_GID_UNSET;
69       break;
70     case BUS_POLICY_RULE_SEND:
71       rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
72       /* allow rules default to TRUE (only requested replies allowed)
73        * check rules default to TRUE (only requested replies are checked)
74        * deny rules default to FALSE (only unrequested replies denied)
75        */
76       rule->d.send.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
77       break;
78     case BUS_POLICY_RULE_RECEIVE:
79       rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
80       /* allow rules default to TRUE (only requested replies allowed)
81        * check rules default to TRUE (only requested replies are checked)
82        * deny rules default to FALSE (only unrequested replies denied)
83        */
84       rule->d.receive.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
85       break;
86     case BUS_POLICY_RULE_OWN:
87       break;
88     default:
89       _dbus_assert_not_reached ("invalid rule");
90     }
91   
92   return rule;
93 }
94
95 BusPolicyRule *
96 bus_policy_rule_ref (BusPolicyRule *rule)
97 {
98   _dbus_assert (rule->refcount > 0);
99
100   rule->refcount += 1;
101
102   return rule;
103 }
104
105 void
106 bus_policy_rule_unref (BusPolicyRule *rule)
107 {
108   _dbus_assert (rule->refcount > 0);
109
110   rule->refcount -= 1;
111   
112   if (rule->refcount == 0)
113     {
114       switch (rule->type)
115         {
116         case BUS_POLICY_RULE_SEND:
117           dbus_free (rule->d.send.path);
118           dbus_free (rule->d.send.interface);
119           dbus_free (rule->d.send.member);
120           dbus_free (rule->d.send.error);
121           dbus_free (rule->d.send.destination);
122           break;
123         case BUS_POLICY_RULE_RECEIVE:
124           dbus_free (rule->d.receive.path);
125           dbus_free (rule->d.receive.interface);
126           dbus_free (rule->d.receive.member);
127           dbus_free (rule->d.receive.error);
128           dbus_free (rule->d.receive.origin);
129           break;
130         case BUS_POLICY_RULE_OWN:
131           dbus_free (rule->d.own.service_name);
132           break;
133         case BUS_POLICY_RULE_USER:
134           break;
135         case BUS_POLICY_RULE_GROUP:
136           break;
137         default:
138           _dbus_assert_not_reached ("invalid rule");
139         }
140
141       dbus_free (rule->privilege);
142       dbus_free (rule);
143     }
144 }
145
146 struct BusPolicy
147 {
148   int refcount;
149
150   DBusList *default_rules;         /**< Default policy rules */
151   DBusList *mandatory_rules;       /**< Mandatory policy rules */
152   DBusHashTable *rules_by_uid;     /**< per-UID policy rules */
153   DBusHashTable *rules_by_gid;     /**< per-GID policy rules */
154   DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
155   DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
156
157   DBusHashTable *default_rules_by_name;
158   DBusList *default_prefix_rules;
159   unsigned int n_default_rules;
160 };
161
162 typedef struct BusPolicyRulesWithScore
163 {
164   DBusList *rules;
165   int score;
166 } BusPolicyRulesWithScore;
167
168 static void
169 free_rule_func (void *data,
170                 void *user_data)
171 {
172   BusPolicyRule *rule = data;
173
174   bus_policy_rule_unref (rule);
175 }
176
177 static void
178 free_rule_list_func (void *data)
179 {
180   DBusList **list = data;
181
182   if (list == NULL) /* DBusHashTable is on crack */
183     return;
184   
185   _dbus_list_foreach (list, free_rule_func, NULL);
186   
187   _dbus_list_clear (list);
188
189   dbus_free (list);
190 }
191
192 static void
193 free_rule_list_with_score_func (void *data)
194 {
195   BusPolicyRulesWithScore *rules = data;
196
197   if (rules == NULL)
198     return;
199
200   _dbus_list_foreach (&rules->rules, free_rule_func, NULL);
201
202   _dbus_list_clear (&rules->rules);
203
204   dbus_free (rules);
205 }
206
207 BusPolicy*
208 bus_policy_new (void)
209 {
210   BusPolicy *policy;
211
212   policy = dbus_new0 (BusPolicy, 1);
213   if (policy == NULL)
214     return NULL;
215
216   policy->refcount = 1;
217   
218   policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
219                                                NULL,
220                                                free_rule_list_func);
221   if (policy->rules_by_uid == NULL)
222     goto failed;
223
224   policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
225                                                NULL,
226                                                free_rule_list_func);
227   if (policy->rules_by_gid == NULL)
228     goto failed;
229
230   policy->default_rules_by_name = _dbus_hash_table_new (DBUS_HASH_STRING,
231                                                         NULL,
232                                                         free_rule_list_with_score_func);
233   if (policy->default_rules_by_name == NULL)
234     goto failed;
235
236   return policy;
237
238  failed:
239   bus_policy_unref (policy);
240   return NULL;
241 }
242
243 BusPolicy *
244 bus_policy_ref (BusPolicy *policy)
245 {
246   _dbus_assert (policy->refcount > 0);
247
248   policy->refcount += 1;
249
250   return policy;
251 }
252
253 void
254 bus_policy_unref (BusPolicy *policy)
255 {
256   _dbus_assert (policy->refcount > 0);
257
258   policy->refcount -= 1;
259
260   if (policy->refcount == 0)
261     {
262       _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
263       _dbus_list_clear (&policy->default_rules);
264
265       _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
266       _dbus_list_clear (&policy->mandatory_rules);
267
268       _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
269       _dbus_list_clear (&policy->at_console_true_rules);
270
271       _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
272       _dbus_list_clear (&policy->at_console_false_rules);
273
274       if (policy->rules_by_uid)
275         {
276           _dbus_hash_table_unref (policy->rules_by_uid);
277           policy->rules_by_uid = NULL;
278         }
279
280       if (policy->rules_by_gid)
281         {
282           _dbus_hash_table_unref (policy->rules_by_gid);
283           policy->rules_by_gid = NULL;
284         }
285
286       if (policy->default_rules_by_name)
287         {
288           _dbus_hash_table_unref (policy->default_rules_by_name);
289           policy->default_rules_by_name = NULL;
290         }
291
292       _dbus_list_foreach (&policy->default_prefix_rules, free_rule_func, NULL);
293       _dbus_list_clear (&policy->default_prefix_rules);
294
295       dbus_free (policy);
296     }
297 }
298
299 BusClientPolicy*
300 bus_policy_create_client_policy (BusPolicy      *policy,
301                                  DBusConnection *connection,
302                                  DBusError      *error)
303 {
304   BusClientPolicy *client;
305
306   _dbus_assert (dbus_connection_get_is_authenticated (connection));
307   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
308   
309   client = bus_client_policy_new ();
310   if (client == NULL)
311     goto nomem;
312
313   if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
314     {
315       if (!bus_connection_get_unix_groups (connection, &client->groups, &client->n_groups, error))
316         goto failed;
317     }
318   
319   if (dbus_connection_get_unix_user (connection, &client->uid))
320     {
321       client->uid_set = TRUE;
322       client->at_console = _dbus_unix_user_is_at_console (client->uid, error);
323       
324       if (dbus_error_is_set (error) == TRUE)
325           goto failed;
326     }
327
328   client->policy = bus_policy_ref (policy);
329
330   return client;
331
332  nomem:
333   BUS_SET_OOM (error);
334  failed:
335   _DBUS_ASSERT_ERROR_IS_SET (error);
336   if (client)
337     bus_client_policy_unref (client);
338   return NULL;
339 }
340
341 static dbus_bool_t
342 list_allows_user (dbus_bool_t           def,
343                   DBusList            **list,
344                   unsigned long         uid,
345                   const unsigned long  *group_ids,
346                   int                   n_group_ids)
347 {
348   DBusList *link;
349   dbus_bool_t allowed;
350   
351   allowed = def;
352
353   link = _dbus_list_get_first_link (list);
354   while (link != NULL)
355     {
356       BusPolicyRule *rule = link->data;
357       link = _dbus_list_get_next_link (list, link);
358
359       if (rule->type == BUS_POLICY_RULE_USER)
360         {
361           _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
362                          list, rule->d.user.uid);
363           
364           if (rule->d.user.uid == DBUS_UID_UNSET)
365             ; /* '*' wildcard */
366           else if (rule->d.user.uid != uid)
367             continue;
368         }
369       else if (rule->type == BUS_POLICY_RULE_GROUP)
370         {
371           _dbus_verbose ("List %p group rule gid="DBUS_GID_FORMAT"\n",
372                          list, rule->d.group.gid);
373           
374           if (rule->d.group.gid == DBUS_GID_UNSET)
375             ;  /* '*' wildcard */
376           else
377             {
378               int i;
379               
380               i = 0;
381               while (i < n_group_ids)
382                 {
383                   if (rule->d.group.gid == group_ids[i])
384                     break;
385                   ++i;
386                 }
387               
388               if (i == n_group_ids)
389                 continue;
390             }
391         }
392       else
393         continue;
394
395       /* We don't intend to support <check user="..." /> and <check group="..." />
396          rules. They are treated like deny.
397       */
398       allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
399     }
400   
401   return allowed;
402 }
403
404 dbus_bool_t
405 bus_policy_allow_unix_user (BusPolicy        *policy,
406                             unsigned long     uid)
407 {
408   dbus_bool_t allowed;
409   unsigned long *group_ids;
410   int n_group_ids;
411
412   /* On OOM or error we always reject the user */
413   if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
414     {
415       _dbus_verbose ("Did not get any groups for UID %lu\n",
416                      uid);
417       return FALSE;
418     }
419
420   /* Default to "user owning bus" can connect */
421   allowed = _dbus_unix_user_is_process_owner (uid);
422
423   allowed = list_allows_user (allowed,
424                               &policy->default_rules,
425                               uid,
426                               group_ids, n_group_ids);
427
428   allowed = list_allows_user (allowed,
429                               &policy->mandatory_rules,
430                               uid,
431                               group_ids, n_group_ids);
432
433   dbus_free (group_ids);
434
435   _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
436   
437   return allowed;
438 }
439
440 /* For now this is never actually called because the default
441  * DBusConnection behavior of 'same user that owns the bus can
442  * connect' is all it would do. Set the windows user function in
443  * connection.c if the config file ever supports doing something
444  * interesting here.
445  */
446 dbus_bool_t
447 bus_policy_allow_windows_user (BusPolicy        *policy,
448                                const char       *windows_sid)
449 {
450   /* Windows has no policies here since only the session bus
451    * is really used for now, so just checking that the
452    * connecting person is the same as the bus owner is fine.
453    */
454   return _dbus_windows_user_is_process_owner (windows_sid);
455 }
456
457 static BusPolicyRulesWithScore *
458 get_rules_by_string (DBusHashTable *hash,
459                     const char    *key)
460 {
461   BusPolicyRulesWithScore *rules;
462
463   rules = _dbus_hash_table_lookup_string (hash, key);
464   if (rules == NULL)
465     {
466       rules = dbus_new0 (BusPolicyRulesWithScore, 1);
467       if (rules == NULL)
468         return NULL;
469
470       if (!_dbus_hash_table_insert_string (hash, (char *)key, rules))
471         {
472           dbus_free (rules);
473           return NULL;
474         }
475     }
476
477   return rules;
478 }
479
480 static const char *
481 get_name_from_rule (BusPolicyRule *rule)
482 {
483   const char *name = NULL;
484   if (rule->type == BUS_POLICY_RULE_SEND)
485     name = rule->d.send.destination;
486   else if (rule->type == BUS_POLICY_RULE_RECEIVE)
487     name = rule->d.receive.origin;
488   else if (rule->type == BUS_POLICY_RULE_OWN)
489     name = rule->d.own.service_name;
490
491   if (name == NULL)
492     name = "";
493
494   return name;
495 }
496
497 static dbus_bool_t
498 is_prefix_rule (BusPolicyRule *rule)
499 {
500   if (rule->type == BUS_POLICY_RULE_SEND && rule->d.send.destination_prefix)
501     return TRUE;
502   if (rule->type == BUS_POLICY_RULE_OWN && rule->d.own.prefix)
503     return TRUE;
504
505   return FALSE;
506 }
507
508 dbus_bool_t
509 bus_policy_append_default_rule (BusPolicy      *policy,
510                                 BusPolicyRule  *rule)
511 {
512   if (rule->type == BUS_POLICY_RULE_USER || rule->type == BUS_POLICY_RULE_GROUP)
513     {
514       if (!_dbus_list_append (&policy->default_rules, rule))
515         return FALSE;
516     }
517   else
518     {
519       rule->score = ++policy->n_default_rules;
520
521       if (is_prefix_rule (rule))
522         {
523           if (!_dbus_list_append (&policy->default_prefix_rules, rule))
524             return FALSE;
525         }
526       else
527         {
528           DBusList **list;
529           BusPolicyRulesWithScore *rules;
530
531           rules = get_rules_by_string (policy->default_rules_by_name,
532                                        get_name_from_rule (rule));
533
534           if (rules == NULL)
535             return FALSE;
536
537           list = &rules->rules;
538
539           if (!_dbus_list_prepend (list, rule))
540             return FALSE;
541
542           rules->score = rule->score;
543         }
544     }
545
546   bus_policy_rule_ref (rule);
547
548   return TRUE;
549 }
550
551 dbus_bool_t
552 bus_policy_append_mandatory_rule (BusPolicy      *policy,
553                                   BusPolicyRule  *rule)
554 {
555   if (!_dbus_list_append (&policy->mandatory_rules, rule))
556     return FALSE;
557
558   bus_policy_rule_ref (rule);
559
560   return TRUE;
561 }
562
563
564
565 static DBusList**
566 get_list (DBusHashTable *hash,
567           unsigned long  key)
568 {
569   DBusList **list;
570
571   list = _dbus_hash_table_lookup_uintptr (hash, key);
572
573   if (list == NULL)
574     {
575       list = dbus_new0 (DBusList*, 1);
576       if (list == NULL)
577         return NULL;
578
579       if (!_dbus_hash_table_insert_uintptr (hash, key, list))
580         {
581           dbus_free (list);
582           return NULL;
583         }
584     }
585
586   return list;
587 }
588
589 dbus_bool_t
590 bus_policy_append_user_rule (BusPolicy      *policy,
591                              dbus_uid_t      uid,
592                              BusPolicyRule  *rule)
593 {
594   DBusList **list;
595
596   list = get_list (policy->rules_by_uid, uid);
597
598   if (list == NULL)
599     return FALSE;
600
601   if (!_dbus_list_append (list, rule))
602     return FALSE;
603
604   bus_policy_rule_ref (rule);
605
606   return TRUE;
607 }
608
609 dbus_bool_t
610 bus_policy_append_group_rule (BusPolicy      *policy,
611                               dbus_gid_t      gid,
612                               BusPolicyRule  *rule)
613 {
614   DBusList **list;
615
616   list = get_list (policy->rules_by_gid, gid);
617
618   if (list == NULL)
619     return FALSE;
620
621   if (!_dbus_list_append (list, rule))
622     return FALSE;
623
624   bus_policy_rule_ref (rule);
625
626   return TRUE;
627 }
628
629 dbus_bool_t
630 bus_policy_append_console_rule (BusPolicy      *policy,
631                                 dbus_bool_t     at_console,
632                                 BusPolicyRule  *rule)
633 {
634   if (at_console)
635     {
636       if (!_dbus_list_append (&policy->at_console_true_rules, rule))
637         return FALSE;
638     }
639     else
640     {
641       if (!_dbus_list_append (&policy->at_console_false_rules, rule))
642         return FALSE;
643     }
644
645   bus_policy_rule_ref (rule);
646
647   return TRUE;
648
649 }
650
651 static dbus_bool_t
652 append_copy_of_policy_list (DBusList **list,
653                             DBusList **to_append)
654 {
655   DBusList *link;
656   DBusList *tmp_list;
657
658   tmp_list = NULL;
659
660   /* Preallocate all our links */
661   link = _dbus_list_get_first_link (to_append);
662   while (link != NULL)
663     {
664       if (!_dbus_list_append (&tmp_list, link->data))
665         {
666           _dbus_list_clear (&tmp_list);
667           return FALSE;
668         }
669       
670       link = _dbus_list_get_next_link (to_append, link);
671     }
672
673   /* Now append them */
674   while ((link = _dbus_list_pop_first_link (&tmp_list)))
675     {
676       bus_policy_rule_ref (link->data);
677       _dbus_list_append_link (list, link);
678     }
679
680   return TRUE;
681 }
682
683 static dbus_bool_t
684 merge_id_hash (DBusHashTable *dest,
685                DBusHashTable *to_absorb)
686 {
687   DBusHashIter iter;
688   
689   _dbus_hash_iter_init (to_absorb, &iter);
690   while (_dbus_hash_iter_next (&iter))
691     {
692       unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter);
693       DBusList **list = _dbus_hash_iter_get_value (&iter);
694       DBusList **target = get_list (dest, id);
695
696       if (target == NULL)
697         return FALSE;
698
699       if (!append_copy_of_policy_list (target, list))
700         return FALSE;
701     }
702
703   return TRUE;
704 }
705
706 static dbus_bool_t
707 merge_string_hash (unsigned int *n_rules,
708                    unsigned int n_rules_to_absorb,
709                    DBusHashTable *dest,
710                    DBusHashTable *to_absorb)
711 {
712   DBusHashIter iter;
713 #ifndef DBUS_DISABLE_ASSERT
714   int cnt_rules = 0;
715 #endif
716
717   _dbus_hash_iter_init (to_absorb, &iter);
718   while (_dbus_hash_iter_next (&iter))
719     {
720       const char *id = _dbus_hash_iter_get_string_key (&iter);
721       BusPolicyRulesWithScore *to_absorb_rules =_dbus_hash_iter_get_value (&iter);
722       DBusList **list = &to_absorb_rules->rules;
723       BusPolicyRulesWithScore *target_rules = get_rules_by_string (dest, id);
724       DBusList **target;
725       DBusList *list_iter;
726       DBusList *target_first_link;
727
728       if (target_rules == NULL)
729         return FALSE;
730
731       target = &target_rules->rules;
732       target_first_link = _dbus_list_get_first_link (target);
733
734       list_iter = _dbus_list_get_first_link (list);
735       while (list_iter != NULL)
736         {
737           DBusList *new_link;
738           BusPolicyRule *rule = list_iter->data;
739
740           rule->score += *n_rules;
741           list_iter = _dbus_list_get_next_link (list, list_iter);
742 #ifndef DBUS_DISABLE_ASSERT
743           cnt_rules++;
744 #endif
745           new_link = _dbus_list_alloc_link (rule);
746           if (new_link == NULL)
747             return FALSE;
748
749           bus_policy_rule_ref (rule);
750
751           _dbus_list_insert_before_link (target, target_first_link, new_link);
752         }
753
754       target_rules->score = to_absorb_rules->score + *n_rules;
755     }
756
757   _dbus_assert (n_rules_to_absorb == cnt_rules);
758
759   *n_rules += n_rules_to_absorb;
760
761   return TRUE;
762 }
763
764 dbus_bool_t
765 bus_policy_merge (BusPolicy *policy,
766                   BusPolicy *to_absorb)
767 {
768   /* FIXME Not properly atomic, but as used for configuration files we
769    * don't rely on it quite so much.
770    */
771   
772   if (!append_copy_of_policy_list (&policy->default_rules,
773                                    &to_absorb->default_rules))
774     return FALSE;
775   
776   if (!append_copy_of_policy_list (&policy->mandatory_rules,
777                                    &to_absorb->mandatory_rules))
778     return FALSE;
779
780   if (!append_copy_of_policy_list (&policy->at_console_true_rules,
781                                    &to_absorb->at_console_true_rules))
782     return FALSE;
783
784   if (!append_copy_of_policy_list (&policy->at_console_false_rules,
785                                    &to_absorb->at_console_false_rules))
786     return FALSE;
787
788   if (!merge_id_hash (policy->rules_by_uid,
789                       to_absorb->rules_by_uid))
790     return FALSE;
791   
792   if (!merge_id_hash (policy->rules_by_gid,
793                       to_absorb->rules_by_gid))
794     return FALSE;
795
796   if (!merge_string_hash (&policy->n_default_rules,
797                           to_absorb->n_default_rules,
798                           policy->default_rules_by_name,
799                           to_absorb->default_rules_by_name))
800     return FALSE;
801
802   if (!append_copy_of_policy_list (&policy->default_prefix_rules,
803                                    &to_absorb->default_prefix_rules))
804     return FALSE;
805
806   return TRUE;
807 }
808
809 BusClientPolicy*
810 bus_client_policy_new (void)
811 {
812   BusClientPolicy *policy;
813
814   policy = dbus_new0 (BusClientPolicy, 1);
815   if (policy == NULL)
816     return NULL;
817
818   policy->refcount = 1;
819
820   return policy;
821 }
822
823 BusClientPolicy *
824 bus_client_policy_ref (BusClientPolicy *policy)
825 {
826   _dbus_assert (policy->refcount > 0);
827
828   policy->refcount += 1;
829
830   return policy;
831 }
832
833 void
834 bus_client_policy_unref (BusClientPolicy *policy)
835 {
836   _dbus_assert (policy->refcount > 0);
837
838   policy->refcount -= 1;
839
840   if (policy->refcount == 0)
841     {
842       if (policy->policy)
843         bus_policy_unref (policy->policy);
844
845       dbus_free (policy->groups);
846
847       dbus_free (policy);
848     }
849 }
850
851 #define _dbus_string_append_printf_err_check(str, fmt, args...) \
852     if (!_dbus_string_append_printf(str, fmt, ##args)) \
853       { \
854         _dbus_string_free (str); \
855         return FALSE; \
856       }
857
858 static dbus_bool_t
859 bus_policy_rule_to_string (BusPolicyRule *rule,
860                            char **out_rule)
861 {
862   const char *sr;
863   const char *access;
864   const char *dest;
865   const char *msg_type[] = {"Invalid", "method_call", "method_return", "signal", "error"};
866   DBusString str;
867
868   *out_rule = NULL;
869
870   switch (rule->access)
871     {
872     case BUS_POLICY_RULE_ACCESS_ALLOW:
873       access = "allow";
874       break;
875     case BUS_POLICY_RULE_ACCESS_DENY:
876       access = "deny";
877       break;
878     case BUS_POLICY_RULE_ACCESS_CHECK:
879       access = "check";
880       break;
881     default:
882       _dbus_assert_not_reached ("invalid rule access value");
883     }
884
885   if (rule->type == BUS_POLICY_RULE_SEND)
886     {
887       sr = "send";
888       dest = "destination";
889     }
890   else if (rule->type == BUS_POLICY_RULE_RECEIVE)
891     {
892       sr = "receive";
893       dest = "sender";
894     }
895   else
896     return FALSE;
897
898   /* generate xml format */
899   if (!_dbus_string_init (&str))
900     return FALSE;
901
902   _dbus_string_append_printf_err_check (&str, "<%s ", access);
903
904   if (rule->d.send.destination_prefix)
905     {
906       _dbus_string_append_printf_err_check (&str, "%s_destination_prefix=\"%s\" ", sr, rule->d.send.destination);
907     }
908   else if (rule->d.send.destination)
909     {
910       _dbus_string_append_printf_err_check (&str, "%s_%s=\"%s\" ", sr, dest, rule->d.send.destination);
911     }
912
913   if (rule->d.send.path)
914     _dbus_string_append_printf_err_check (&str, "%s_path=\"%s\" ", sr, rule->d.send.path);
915   if (rule->d.send.interface)
916     _dbus_string_append_printf_err_check (&str, "%s_interface=\"%s\" ", sr, rule->d.send.interface);
917   if (rule->d.send.member)
918     _dbus_string_append_printf_err_check (&str, "%s_member=\"%s\" ", sr, rule->d.send.member);
919   if (rule->d.send.message_type)
920     _dbus_string_append_printf_err_check (&str, "%s_type=\"%s\" ", sr, msg_type[rule->d.send.message_type]);
921   if (rule->privilege)
922     _dbus_string_append_printf_err_check (&str, "privilege=\"%s\" ", rule->privilege);
923
924   if (!_dbus_string_append (&str, "/>"))
925     {
926       _dbus_string_free (&str);
927       return FALSE;
928     }
929
930   if (!_dbus_string_steal_data (&str, out_rule))
931     {
932       *out_rule = NULL;
933       _dbus_string_free (&str);
934       return FALSE;
935     }
936
937   _dbus_string_free (&str);
938
939   return TRUE;
940 }
941
942 typedef struct RuleParams {
943   enum {PARAM_SR, PARAM_OWN} type;
944   union {
945     struct {
946       BusRegistry    *registry;
947       dbus_bool_t     requested_reply;
948       DBusConnection *peer;
949       const char     *name;
950       DBusMessage    *message;
951       dbus_bool_t     eavesdropping;
952     } sr;
953     const DBusString *name;
954   } u;
955 } RuleParams;
956
957 typedef dbus_bool_t (*CheckRuleFunc) (const BusPolicyRule *,
958                                       const RuleParams *,
959                                       BusResult *,
960                                       const char **);
961
962 static dbus_bool_t
963 check_send_rule (const BusPolicyRule *rule,
964                  const RuleParams    *match_params,
965                  BusResult           *result,
966                  const char         **privilege)
967 {
968   /* Rule is skipped if it specifies a different
969    * message name from the message, or a different
970    * destination from the message
971    */
972   if (rule->type != BUS_POLICY_RULE_SEND)
973     {
974       _dbus_verbose ("  (policy) skipping non-send rule\n");
975       return FALSE;
976     }
977
978   if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
979     {
980       if (dbus_message_get_type (match_params->u.sr.message) != rule->d.send.message_type)
981         {
982           _dbus_verbose ("  (policy) skipping rule for different message type\n");
983           return FALSE;
984         }
985     }
986
987   /* If it's a reply, the requested_reply flag kicks in */
988   if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
989     {
990       /* for allow or check requested_reply=true means the rule applies
991        * only when reply was requested. requested_reply=false means the
992        * rule always applies
993        */
994       if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
995         {
996           _dbus_verbose ("  (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
997               rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
998           return FALSE;
999         }
1000
1001       /* for deny, requested_reply=false means the rule applies only
1002        * when the reply was not requested. requested_reply=true means the
1003        * rule always applies.
1004        */
1005       if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.send.requested_reply)
1006         {
1007           _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
1008           return FALSE;
1009         }
1010     }
1011
1012   if (rule->d.send.path != NULL)
1013     {
1014       if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
1015           strcmp (dbus_message_get_path (match_params->u.sr.message),
1016                   rule->d.send.path) != 0)
1017         {
1018           _dbus_verbose ("  (policy) skipping rule for different path\n");
1019           return FALSE;
1020         }
1021     }
1022
1023   if (rule->d.send.interface != NULL)
1024     {
1025       /* The interface is optional in messages. For allow rules, if the message
1026        * has no interface we want to skip the rule (and thus not allow);
1027        * for deny rules, if the message has no interface we want to use the
1028        * rule (and thus deny). Check rules are meant to be used like allow
1029        * rules (they can grant access, but not remove it), so we treat it like
1030        * allow here.
1031        */
1032       dbus_bool_t no_interface;
1033
1034       no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1035
1036       if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1037           (!no_interface &&
1038            strcmp (dbus_message_get_interface (match_params->u.sr.message),
1039                    rule->d.send.interface) != 0))
1040         {
1041           _dbus_verbose ("  (policy) skipping rule for different interface\n");
1042           return FALSE;
1043         }
1044     }
1045
1046   if (rule->d.send.member != NULL)
1047     {
1048       if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1049           strcmp (dbus_message_get_member (match_params->u.sr.message),
1050                   rule->d.send.member) != 0)
1051         {
1052           _dbus_verbose ("  (policy) skipping rule for different member\n");
1053           return FALSE;
1054         }
1055     }
1056
1057   if (rule->d.send.error != NULL)
1058     {
1059       if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1060           strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1061                   rule->d.send.error) != 0)
1062         {
1063           _dbus_verbose ("  (policy) skipping rule for different error name\n");
1064           return FALSE;
1065         }
1066     }
1067
1068   if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
1069     {
1070       if (dbus_message_get_destination (match_params->u.sr.message) == NULL &&
1071           dbus_message_get_type (match_params->u.sr.message) == DBUS_MESSAGE_TYPE_SIGNAL)
1072         {
1073           /* it's a broadcast */
1074           if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
1075             {
1076               _dbus_verbose ("  (policy) skipping rule because message is a broadcast\n");
1077               return FALSE;
1078             }
1079         }
1080       /* else it isn't a broadcast: there is some destination */
1081       else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
1082         {
1083           _dbus_verbose ("  (policy) skipping rule because message is not a broadcast\n");
1084           return FALSE;
1085         }
1086     }
1087
1088   if (rule->d.send.destination != NULL)
1089     {
1090       if (!rule->d.send.destination_prefix)
1091         {
1092           /* receiver can be NULL for messages that are sent to the
1093            * message bus itself, we check the strings in that case as
1094            * built-in services don't have a DBusConnection but messages
1095            * to them have a destination service name.
1096            *
1097            * Similarly, receiver can be NULL when we're deciding whether
1098            * activation should be allowed; we make the authorization decision
1099            * on the assumption that the activated service will have the
1100            * requested name and no others.
1101            */
1102           if (match_params->u.sr.peer == NULL)
1103             {
1104               if (!dbus_message_has_destination (match_params->u.sr.message,
1105                                                  rule->d.send.destination))
1106                 {
1107                   _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
1108                                  rule->d.send.destination);
1109                   return FALSE;
1110                 }
1111             }
1112           else
1113             {
1114               DBusString str;
1115               BusService *service;
1116
1117               _dbus_string_init_const (&str, rule->d.send.destination);
1118
1119               service = bus_registry_lookup (match_params->u.sr.registry, &str);
1120               if (service == NULL)
1121                 {
1122                   _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
1123                                  rule->d.send.destination);
1124                   return FALSE;
1125                 }
1126
1127               if (!bus_service_has_owner (service, match_params->u.sr.peer))
1128                 {
1129                   _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
1130                                  rule->d.send.destination);
1131                   return FALSE;
1132                 }
1133             }
1134         }
1135       else if (rule->d.send.destination_prefix)
1136         {
1137           /* receiver can be NULL - the same as in !send.destination_prefix */
1138           if (match_params->u.sr.peer == NULL)
1139             {
1140               const char *destination = dbus_message_get_destination (match_params->u.sr.message);
1141               DBusString dest_name;
1142
1143               if (destination == NULL)
1144                 {
1145                   _dbus_verbose ("  (policy) skipping rule because message has no dest\n");
1146                   return FALSE;
1147                 }
1148
1149               _dbus_string_init_const (&dest_name, destination);
1150
1151               if (!_dbus_string_starts_with_words_c_str (&dest_name,
1152                                                          rule->d.send.destination,
1153                                                          '.'))
1154                 {
1155                   _dbus_verbose ("  (policy) skipping rule because message dest doesn't start with %s\n",
1156                                  rule->d.send.destination);
1157                   return FALSE;
1158                 }
1159             }
1160           else
1161             {
1162               if (!bus_connection_is_service_owner_by_prefix (match_params->u.sr.peer,
1163                                                               rule->d.send.destination))
1164                 {
1165                   _dbus_verbose ("  (policy) skipping rule because no dest with prefix %s is owned by receiver\n",
1166                                  rule->d.send.destination);
1167                   return FALSE;
1168                 }
1169             }
1170         }
1171     }
1172
1173   if (rule->d.send.min_fds > 0 ||
1174       rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1175     {
1176       unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1177
1178       if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
1179         {
1180           _dbus_verbose ("  (policy) skipping rule because message has %u fds "
1181                          "and that is outside range [%u,%u]",
1182                          n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
1183           return FALSE;
1184         }
1185     }
1186
1187   /* Use this rule */
1188   switch (rule->access)
1189   {
1190     case BUS_POLICY_RULE_ACCESS_ALLOW:
1191       *result = BUS_RESULT_TRUE;
1192       break;
1193     case BUS_POLICY_RULE_ACCESS_DENY:
1194       *result = BUS_RESULT_FALSE;
1195       break;
1196     case BUS_POLICY_RULE_ACCESS_CHECK:
1197       *result = BUS_RESULT_LATER;
1198       *privilege = rule->privilege;
1199       break;
1200     default:
1201       _dbus_assert_not_reached ("invalid rule access value");
1202   }
1203
1204   return TRUE;
1205 }
1206
1207 static void
1208 check_rules_list (const DBusList   *rules,
1209                   CheckRuleFunc     check_func,
1210                   const RuleParams *params,
1211                   dbus_int32_t     *toggles,
1212                   dbus_bool_t      *log,
1213                   BusResult        *result,
1214                   const char      **privilege,
1215                   BusPolicyRule   **matched_rule,
1216                   dbus_bool_t       break_on_first_match)
1217 {
1218   const DBusList *link;
1219
1220   link = _dbus_list_get_first_link ((DBusList **)&rules);
1221   while (link != NULL)
1222     {
1223       const BusPolicyRule *rule = link->data;
1224
1225       link = _dbus_list_get_next_link ((DBusList **)&rules, link);
1226
1227       if (check_func (rule, params, result, privilege))
1228         {
1229           if (log)
1230             *log = rule->d.send.log;
1231           if (toggles)
1232             (*toggles)++;
1233           if (matched_rule)
1234             *matched_rule = (BusPolicyRule *)rule;
1235
1236           _dbus_verbose ("  (policy) used rule, result now = %d\n",
1237                          result);
1238
1239           if (break_on_first_match)
1240             break;
1241         }
1242     }
1243 }
1244
1245 static int
1246 check_rules_list_with_score (DBusList         *rules,
1247                              int               score,
1248                              CheckRuleFunc     check_func,
1249                              const RuleParams *params,
1250                              dbus_int32_t     *toggles,
1251                              dbus_bool_t      *log,
1252                              BusResult        *result,
1253                              const char      **privilege,
1254                              BusPolicyRule   **matched_rule,
1255                              dbus_bool_t       break_on_first_match)
1256 {
1257   dbus_int32_t local_toggles;
1258   dbus_bool_t local_log;
1259   BusResult local_result;
1260   const char *local_privilege;
1261   BusPolicyRule *local_matched_rule;
1262
1263   local_toggles = 0;
1264
1265   check_rules_list (rules, check_func, params,
1266                     &local_toggles, &local_log, &local_result, &local_privilege,
1267                     &local_matched_rule, break_on_first_match);
1268
1269   if (local_toggles > 0)
1270     {
1271       _dbus_assert (local_matched_rule != NULL);
1272
1273       if (local_matched_rule->score > score)
1274         {
1275           if (toggles)
1276             *toggles += local_toggles;
1277           if (log)
1278             *log = local_log;
1279           *result = local_result;
1280           *privilege = local_privilege;
1281           if (matched_rule)
1282             *matched_rule = local_matched_rule;
1283           return local_matched_rule->score;
1284         }
1285     }
1286
1287   return score;
1288 }
1289
1290 static int
1291 check_rules_for_name (DBusHashTable  *rules,
1292                       const char     *name,
1293                       int             score,
1294                       CheckRuleFunc   check_func,
1295                       const void     *params,
1296                       dbus_int32_t   *toggles,
1297                       dbus_bool_t    *log,
1298                       BusResult      *result,
1299                       const char    **privilege,
1300                       BusPolicyRule **matched_rule)
1301 {
1302   const BusPolicyRulesWithScore *rules_list;
1303
1304   rules_list = _dbus_hash_table_lookup_string (rules, name);
1305
1306   if (rules_list == NULL || rules_list->score <= score)
1307     return score;
1308
1309   return check_rules_list_with_score (rules_list->rules, score, check_func, params, toggles, log, result, privilege, matched_rule, TRUE);
1310 }
1311
1312 static int
1313 find_and_check_rules_for_name (DBusHashTable  *rules,
1314                                DBusList       *prefix_rules,
1315                                const char     *c_str,
1316                                int             score,
1317                                CheckRuleFunc   check_func,
1318                                const void     *params,
1319                                dbus_int32_t   *toggles,
1320                                dbus_bool_t    *log,
1321                                BusResult      *result,
1322                                const char    **privilege,
1323                                BusPolicyRule **matched_rule)
1324 {
1325   score = check_rules_for_name (rules, c_str,
1326                                 score, check_func, params,
1327                                 toggles, log,
1328                                 result, privilege,
1329                                 matched_rule);
1330
1331   score = check_rules_list_with_score (prefix_rules,
1332                                        score, check_func, params,
1333                                        toggles, log,
1334                                        result, privilege,
1335                                        matched_rule, FALSE);
1336
1337   return score;
1338 }
1339
1340 static void
1341 find_and_check_rules (DBusHashTable  *rules,
1342                       DBusList       *prefix_rules,
1343                       CheckRuleFunc   check_func,
1344                       const void     *params,
1345                       dbus_int32_t   *toggles,
1346                       dbus_bool_t    *log,
1347                       BusResult      *result,
1348                       const char    **privilege,
1349                       BusPolicyRule **matched_rule)
1350 {
1351   const RuleParams *p = params;
1352   const DBusList *services = NULL;
1353   int score = 0;
1354
1355   if (p->type == PARAM_SR)
1356     {
1357       if (p->u.sr.peer != NULL)
1358         {
1359           DBusList *link;
1360
1361           services = bus_connection_get_owned_services_list (p->u.sr.peer);
1362
1363           link = _dbus_list_get_first_link ((DBusList **)&services);
1364           while (link != NULL)
1365             {
1366               const char *name = bus_service_get_name (link->data);
1367
1368               link = _dbus_list_get_next_link ((DBusList **)&services, link);
1369
1370               /* skip unique id names */
1371               if (name[0] == ':')
1372                 continue;
1373
1374               score = find_and_check_rules_for_name (rules, prefix_rules, name, score,
1375                                                      check_func, params,
1376                                                      toggles, log, result,
1377                                                      privilege, matched_rule);
1378             }
1379         }
1380       else if (p->u.sr.name != NULL)
1381         {
1382           score = find_and_check_rules_for_name (rules, prefix_rules, p->u.sr.name, score,
1383                                                  check_func, params,
1384                                                  toggles, log, result,
1385                                                  privilege, matched_rule);
1386         }
1387     }
1388   else
1389     score = find_and_check_rules_for_name (rules, prefix_rules, _dbus_string_get_const_data(p->u.name),
1390                                            score, check_func, params,
1391                                            toggles, log, result,
1392                                            privilege, matched_rule);
1393
1394   /* check also wildcard rules */
1395   score = check_rules_for_name (rules, "", score, check_func, params,
1396                                 toggles, log, result, privilege, matched_rule);
1397 }
1398
1399 static BusResult
1400 check_policy (BusClientPolicy *policy,
1401               CheckRuleFunc    check_func,
1402               const void      *params,
1403               dbus_int32_t    *toggles,
1404               dbus_bool_t     *log,
1405               const char     **privilege,
1406               BusPolicyRule  **matched_rule)
1407 {
1408   BusResult result = BUS_RESULT_FALSE;
1409
1410   if (toggles)
1411     *toggles = 0;
1412
1413   find_and_check_rules (policy->policy->default_rules_by_name,
1414                         policy->policy->default_prefix_rules,
1415                         check_func, params,
1416                         toggles, log, &result, privilege, matched_rule);
1417
1418   /* we avoid the overhead of looking up user's groups
1419    * if we don't have any group rules anyway
1420    */
1421   if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_gid) > 0)
1422     {
1423       int i;
1424
1425       for (i = 0; i < policy->n_groups; ++i)
1426         {
1427           const DBusList **list;
1428
1429           list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_gid,
1430                                                   policy->groups[i]);
1431
1432           if (list != NULL)
1433             check_rules_list (*list, check_func, params,
1434                               toggles, log, &result, privilege, matched_rule, FALSE);
1435         }
1436     }
1437
1438   if (policy->uid_set)
1439     {
1440       if (_dbus_hash_table_get_n_entries (policy->policy->rules_by_uid) > 0)
1441         {
1442           const DBusList **list;
1443
1444           list = _dbus_hash_table_lookup_uintptr (policy->policy->rules_by_uid,
1445                                                   policy->uid);
1446
1447           if (list != NULL)
1448             check_rules_list (*list, check_func, params,
1449                               toggles, log, &result, privilege, matched_rule, FALSE);
1450
1451           if (policy->at_console)
1452             check_rules_list (policy->policy->at_console_true_rules, check_func,
1453                               params, toggles, log, &result, privilege, matched_rule, FALSE);
1454           else
1455             check_rules_list (policy->policy->at_console_false_rules, check_func,
1456                               params, toggles, log, &result, privilege, matched_rule, FALSE);
1457         }
1458     }
1459
1460   check_rules_list (policy->policy->mandatory_rules, check_func, params,
1461                     toggles, log, &result, privilege, matched_rule, FALSE);
1462
1463   return result;
1464 }
1465
1466 BusResult
1467 bus_client_policy_check_can_send (DBusConnection      *sender,
1468                                   BusClientPolicy     *policy,
1469                                   BusRegistry         *registry,
1470                                   dbus_bool_t          requested_reply,
1471                                   DBusConnection      *addressed_recipient,
1472                                   DBusConnection      *receiver,
1473                                   DBusMessage         *message,
1474                                   dbus_int32_t        *toggles,
1475                                   dbus_bool_t         *log,
1476                                   const char         **privilege_param,
1477                                   BusDeferredMessage **deferred_message,
1478                                   char               **out_rule)
1479 {
1480   BusResult result;
1481   const char *privilege;
1482   BusPolicyRule *matched_rule = NULL;
1483   struct RuleParams params;
1484
1485   params.type = PARAM_SR;
1486   params.u.sr.registry = registry;
1487   params.u.sr.requested_reply = requested_reply;
1488   params.u.sr.peer = receiver;
1489   params.u.sr.message = message;
1490   params.u.sr.name = dbus_message_get_destination (message);
1491
1492   _dbus_verbose ("  (policy) checking send rules\n");
1493
1494   result = check_policy (policy, check_send_rule, &params,
1495                          toggles, log, &privilege, &matched_rule);
1496
1497   if (result == BUS_RESULT_LATER)
1498     {
1499       BusContext *context = bus_connection_get_context(sender);
1500       BusCheck *check = bus_context_get_check(context);
1501
1502       result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
1503           privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
1504       if (result == BUS_RESULT_LATER && deferred_message != NULL)
1505         bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1506             *toggles, privilege);
1507     }
1508   else
1509     privilege = NULL;
1510
1511   if (privilege_param != NULL)
1512     *privilege_param = privilege;
1513
1514   if (result == BUS_RESULT_FALSE)
1515     {
1516       if (matched_rule && out_rule)
1517         bus_policy_rule_to_string (matched_rule, out_rule);
1518     }
1519
1520   return result;
1521 }
1522
1523 static dbus_bool_t
1524 check_receive_rule (const BusPolicyRule *rule,
1525                     const RuleParams    *match_params,
1526                     BusResult           *result,
1527                     const char         **privilege)
1528 {
1529   if (rule->type != BUS_POLICY_RULE_RECEIVE)
1530     {
1531       _dbus_verbose ("  (policy) skipping non-receive rule\n");
1532       return FALSE;
1533     }
1534
1535   if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
1536     {
1537       if (dbus_message_get_type (match_params->u.sr.message) != rule->d.receive.message_type)
1538         {
1539           _dbus_verbose ("  (policy) skipping rule for different message type\n");
1540           return FALSE;
1541         }
1542     }
1543
1544
1545   /* for allow or check, eavesdrop=false means the rule doesn't apply when
1546    * eavesdropping. eavesdrop=true means the rule always applies
1547    */
1548   if (match_params->u.sr.eavesdropping && rule->access != BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.eavesdrop)
1549     {
1550       _dbus_verbose ("  (policy) skipping %s rule since it doesn't apply to eavesdropping\n",
1551           rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
1552       return FALSE;
1553     }
1554
1555   /* for deny, eavesdrop=true means the rule applies only when
1556    * eavesdropping; eavesdrop=false means always deny.
1557    */
1558   if (!match_params->u.sr.eavesdropping && rule->access == BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.eavesdrop)
1559     {
1560       _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
1561       return FALSE;
1562     }
1563
1564   /* If it's a reply, the requested_reply flag kicks in */
1565   if (dbus_message_get_reply_serial (match_params->u.sr.message) != 0)
1566     {
1567       /* for allow or check requested_reply=true means the rule applies
1568        * only when reply was requested. requested_reply=false means the
1569        * rule always applies
1570        */
1571       if (!match_params->u.sr.requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop)
1572         {
1573           _dbus_verbose ("  (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
1574               rule->access == BUS_POLICY_RULE_ACCESS_DENY ? "allow" : "deny");
1575           return FALSE;
1576         }
1577
1578       /* for deny, requested_reply=false means the rule applies only
1579        * when the reply was not requested. requested_reply=true means the
1580        * rule always applies.
1581        */
1582       if (match_params->u.sr.requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.requested_reply)
1583         {
1584           _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
1585           return FALSE;
1586         }
1587     }
1588
1589   if (rule->d.receive.path != NULL)
1590     {
1591       if (dbus_message_get_path (match_params->u.sr.message) != NULL &&
1592           strcmp (dbus_message_get_path (match_params->u.sr.message),
1593                   rule->d.receive.path) != 0)
1594         {
1595           _dbus_verbose ("  (policy) skipping rule for different path\n");
1596           return FALSE;
1597         }
1598     }
1599
1600   if (rule->d.receive.interface != NULL)
1601     {
1602       /* The interface is optional in messages. For allow rules, if the message
1603        * has no interface we want to skip the rule (and thus not allow);
1604        * for deny rules, if the message has no interface we want to use the
1605        * rule (and thus deny). Check rules are treated like allow rules.
1606        */
1607       dbus_bool_t no_interface;
1608
1609       no_interface = dbus_message_get_interface (match_params->u.sr.message) == NULL;
1610
1611       if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
1612           (!no_interface &&
1613            strcmp (dbus_message_get_interface (match_params->u.sr.message),
1614                    rule->d.receive.interface) != 0))
1615         {
1616           _dbus_verbose ("  (policy) skipping rule for different interface\n");
1617           return FALSE;
1618         }
1619     }
1620
1621   if (rule->d.receive.member != NULL)
1622     {
1623       if (dbus_message_get_member (match_params->u.sr.message) != NULL &&
1624           strcmp (dbus_message_get_member (match_params->u.sr.message),
1625                   rule->d.receive.member) != 0)
1626         {
1627           _dbus_verbose ("  (policy) skipping rule for different member\n");
1628           return FALSE;
1629         }
1630     }
1631
1632   if (rule->d.receive.error != NULL)
1633     {
1634       if (dbus_message_get_error_name (match_params->u.sr.message) != NULL &&
1635           strcmp (dbus_message_get_error_name (match_params->u.sr.message),
1636                   rule->d.receive.error) != 0)
1637         {
1638           _dbus_verbose ("  (policy) skipping rule for different error name\n");
1639           return FALSE;
1640         }
1641     }
1642
1643   if (rule->d.receive.origin != NULL)
1644     {
1645       /* sender can be NULL for messages that originate from the
1646        * message bus itself, we check the strings in that case as
1647        * built-in services don't have a DBusConnection but will
1648        * still set the sender on their messages.
1649        */
1650       if (match_params->u.sr.peer == NULL)
1651         {
1652           if (!dbus_message_has_sender (match_params->u.sr.message,
1653                                         rule->d.receive.origin))
1654             {
1655               _dbus_verbose ("  (policy) skipping rule because message sender is not %s\n",
1656                              rule->d.receive.origin);
1657               return FALSE;
1658             }
1659         }
1660       else
1661         {
1662           BusService *service;
1663           DBusString str;
1664
1665           _dbus_string_init_const (&str, rule->d.receive.origin);
1666
1667           service = bus_registry_lookup (match_params->u.sr.registry, &str);
1668           
1669           if (service == NULL)
1670             {
1671               _dbus_verbose ("  (policy) skipping rule because origin %s doesn't exist\n",
1672                              rule->d.receive.origin);
1673               return FALSE;
1674             }
1675
1676           if (!bus_service_has_owner (service, match_params->u.sr.peer))
1677             {
1678               _dbus_verbose ("  (policy) skipping rule because origin %s isn't owned by sender\n",
1679                              rule->d.receive.origin);
1680               return FALSE;
1681             }
1682         }
1683     }
1684
1685   if (rule->d.receive.min_fds > 0 ||
1686       rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
1687     {
1688       unsigned int n_fds = _dbus_message_get_n_unix_fds (match_params->u.sr.message);
1689
1690       if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
1691         {
1692           _dbus_verbose ("  (policy) skipping rule because message has %u fds "
1693                          "and that is outside range [%u,%u]",
1694                          n_fds, rule->d.receive.min_fds,
1695                          rule->d.receive.max_fds);
1696           return FALSE;
1697         }
1698     }
1699
1700   /* Use this rule */
1701   switch (rule->access)
1702   {
1703     case BUS_POLICY_RULE_ACCESS_ALLOW:
1704       *result = BUS_RESULT_TRUE;
1705       break;
1706     case BUS_POLICY_RULE_ACCESS_DENY:
1707       *result = BUS_RESULT_FALSE;
1708       break;
1709     case BUS_POLICY_RULE_ACCESS_CHECK:
1710       *result = BUS_RESULT_LATER;
1711       *privilege = rule->privilege;
1712       break;
1713     default:
1714       _dbus_assert_not_reached ("invalid rule access value");
1715   }
1716
1717   return TRUE;
1718 }
1719
1720 /* See docs on what the args mean on bus_context_check_security_policy()
1721  * comment
1722  */
1723 BusResult
1724 bus_client_policy_check_can_receive (BusClientPolicy     *policy,
1725                                      BusRegistry         *registry,
1726                                      dbus_bool_t          requested_reply,
1727                                      DBusConnection      *sender,
1728                                      DBusConnection      *addressed_recipient,
1729                                      DBusConnection      *proposed_recipient,
1730                                      DBusMessage         *message,
1731                                      dbus_int32_t        *toggles,
1732                                      const char         **privilege_param,
1733                                      BusDeferredMessage **deferred_message,
1734                                      char               **out_rule)
1735 {
1736   BusResult result;
1737   const char *privilege;
1738   BusPolicyRule *matched_rule = NULL;
1739   struct RuleParams params;
1740
1741   params.type = PARAM_SR;
1742   params.u.sr.registry = registry;
1743   params.u.sr.requested_reply = requested_reply;
1744   params.u.sr.peer = sender;
1745   params.u.sr.message = message;
1746   params.u.sr.eavesdropping =
1747     addressed_recipient != proposed_recipient &&
1748     dbus_message_get_destination (message) != NULL;
1749   params.u.sr.name = dbus_message_get_sender (message);
1750
1751   _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", params.u.sr.eavesdropping);
1752
1753   result = check_policy (policy, check_receive_rule, &params,
1754                          toggles, NULL, &privilege, &matched_rule);
1755
1756   if (result == BUS_RESULT_LATER)
1757     {
1758       BusContext *context = bus_connection_get_context(proposed_recipient);
1759       BusCheck *check = bus_context_get_check(context);
1760
1761       result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
1762                  privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
1763       if (result == BUS_RESULT_LATER && deferred_message != NULL)
1764         bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
1765                     *toggles, privilege);
1766     }
1767   else
1768       privilege = NULL;
1769
1770   if (privilege_param != NULL)
1771      *privilege_param = privilege;
1772
1773   if (result == BUS_RESULT_FALSE)
1774     {
1775       if (matched_rule && out_rule)
1776         bus_policy_rule_to_string (matched_rule, out_rule);
1777     }
1778
1779   return result;
1780 }
1781
1782 static dbus_bool_t
1783 check_own_rule (const BusPolicyRule *rule,
1784                 const RuleParams    *params,
1785                 BusResult           *result,
1786                 const char         **privilege)
1787 {
1788   const DBusString *service_name = params->u.name;
1789
1790   /* Rule is skipped if it specifies a different service name from
1791    * the desired one.
1792    */
1793
1794   if (rule->type != BUS_POLICY_RULE_OWN)
1795     return FALSE;
1796
1797   if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
1798     {
1799       if (!_dbus_string_equal_c_str (service_name,
1800                                      rule->d.own.service_name))
1801         return FALSE;
1802     }
1803   else if (rule->d.own.prefix)
1804     {
1805       if (!_dbus_string_starts_with_words_c_str (service_name,
1806                                                  rule->d.own.service_name,
1807                                                  '.'))
1808         return FALSE;
1809     }
1810
1811   /* Use this rule */
1812   switch (rule->access)
1813   {
1814   case BUS_POLICY_RULE_ACCESS_ALLOW:
1815     *result = BUS_RESULT_TRUE;
1816     break;
1817   case BUS_POLICY_RULE_ACCESS_DENY:
1818     *result = BUS_RESULT_FALSE;
1819     break;
1820   case BUS_POLICY_RULE_ACCESS_CHECK:
1821     *result = BUS_RESULT_LATER;
1822     *privilege = rule->privilege;
1823     break;
1824   default:
1825     _dbus_assert_not_reached ("invalid rule access value");
1826   }
1827
1828   return TRUE;
1829 }
1830
1831 BusResult
1832 bus_client_policy_check_can_own (BusClientPolicy  *policy,
1833                                  const DBusString *service_name,
1834                                  DBusConnection   *connection,
1835                                  DBusMessage      *message)
1836 {
1837   BusResult result;
1838   const char *privilege;
1839   RuleParams params;
1840
1841   params.type = PARAM_OWN;
1842   params.u.name = service_name;
1843   
1844   result = check_policy (policy, check_own_rule, &params,
1845                          NULL, NULL, &privilege, NULL);
1846
1847   if (result == BUS_RESULT_LATER)
1848     {
1849       BusContext *context = bus_connection_get_context(connection);
1850       BusCheck *check = bus_context_get_check(context);
1851       BusDeferredMessage *deferred_message = NULL;
1852
1853       result = bus_check_privilege(check, message, connection, NULL, NULL,
1854           privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message);
1855       if (result == BUS_RESULT_LATER)
1856         {
1857           bus_deferred_message_disable_sender(deferred_message);
1858         }
1859     }
1860
1861   return result;
1862 }
1863
1864 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1865 dbus_bool_t
1866 bus_policy_check_can_own (BusPolicy  *policy,
1867                           const DBusString *service_name)
1868 {
1869   return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL);
1870 }
1871 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
1872