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