2003-04-27 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / bus / policy.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* policy.c  Bus security policy
3  *
4  * Copyright (C) 2003  Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "policy.h"
25 #include "services.h"
26 #include "test.h"
27 #include "utils.h"
28 #include <dbus/dbus-list.h>
29 #include <dbus/dbus-hash.h>
30 #include <dbus/dbus-internals.h>
31
32 BusPolicyRule*
33 bus_policy_rule_new (BusPolicyRuleType type,
34                      dbus_bool_t       allow)
35 {
36   BusPolicyRule *rule;
37
38   rule = dbus_new0 (BusPolicyRule, 1);
39   if (rule == NULL)
40     return NULL;
41
42   rule->type = type;
43   rule->refcount = 1;
44   rule->allow = allow;
45
46   switch (rule->type)
47     {
48     case BUS_POLICY_RULE_USER:
49       rule->d.user.uid = DBUS_UID_UNSET;
50       break;
51     case BUS_POLICY_RULE_GROUP:
52       rule->d.group.gid = DBUS_GID_UNSET;
53       break;
54     case BUS_POLICY_RULE_SEND:
55     case BUS_POLICY_RULE_RECEIVE:
56     case BUS_POLICY_RULE_OWN:
57       break;
58     }
59   
60   return rule;
61 }
62
63 void
64 bus_policy_rule_ref (BusPolicyRule *rule)
65 {
66   _dbus_assert (rule->refcount > 0);
67
68   rule->refcount += 1;
69 }
70
71 void
72 bus_policy_rule_unref (BusPolicyRule *rule)
73 {
74   _dbus_assert (rule->refcount > 0);
75
76   rule->refcount -= 1;
77   
78   if (rule->refcount == 0)
79     {
80       switch (rule->type)
81         {
82         case BUS_POLICY_RULE_SEND:
83           dbus_free (rule->d.send.message_name);
84           dbus_free (rule->d.send.destination);
85           break;
86         case BUS_POLICY_RULE_RECEIVE:
87           dbus_free (rule->d.receive.message_name);
88           dbus_free (rule->d.receive.origin);
89           break;
90         case BUS_POLICY_RULE_OWN:
91           dbus_free (rule->d.own.service_name);
92           break;
93         case BUS_POLICY_RULE_USER:
94           break;
95         case BUS_POLICY_RULE_GROUP:
96           break;
97         }
98       
99       dbus_free (rule);
100     }
101 }
102
103 struct BusPolicy
104 {
105   int refcount;
106
107   DBusList *default_rules;       /**< Default policy rules */
108   DBusList *mandatory_rules;     /**< Mandatory policy rules */
109   DBusHashTable *rules_by_uid;   /**< per-UID policy rules */
110   DBusHashTable *rules_by_gid;   /**< per-GID policy rules */
111 };
112
113 static void
114 free_rule_func (void *data,
115                 void *user_data)
116 {
117   BusPolicyRule *rule = data;
118
119   bus_policy_rule_unref (rule);
120 }
121
122 static void
123 free_rule_list_func (void *data)
124 {
125   DBusList **list = data;
126
127   _dbus_list_foreach (list, free_rule_func, NULL);
128   
129   _dbus_list_clear (list);
130
131   dbus_free (list);
132 }
133
134 BusPolicy*
135 bus_policy_new (void)
136 {
137   BusPolicy *policy;
138
139   policy = dbus_new0 (BusPolicy, 1);
140   if (policy == NULL)
141     return NULL;
142
143   policy->refcount = 1;
144   
145   policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
146                                                NULL,
147                                                free_rule_list_func);
148   if (policy->rules_by_uid == NULL)
149     goto failed;
150
151   policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
152                                                NULL,
153                                                free_rule_list_func);
154   if (policy->rules_by_gid == NULL)
155     goto failed;
156   
157   return policy;
158   
159  failed:
160   bus_policy_unref (policy);
161   return NULL;
162 }
163
164 void
165 bus_policy_ref (BusPolicy *policy)
166 {
167   _dbus_assert (policy->refcount > 0);
168
169   policy->refcount += 1;
170 }
171
172 void
173 bus_policy_unref (BusPolicy *policy)
174 {
175   _dbus_assert (policy->refcount > 0);
176
177   policy->refcount -= 1;
178
179   if (policy->refcount == 0)
180     {
181       _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
182       _dbus_list_clear (&policy->default_rules);
183
184       _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
185       _dbus_list_clear (&policy->mandatory_rules);
186       
187       if (policy->rules_by_uid)
188         {
189           _dbus_hash_table_unref (policy->rules_by_uid);
190           policy->rules_by_uid = NULL;
191         }
192
193       if (policy->rules_by_gid)
194         {
195           _dbus_hash_table_unref (policy->rules_by_gid);
196           policy->rules_by_gid = NULL;
197         }
198       
199       dbus_free (policy);
200     }
201 }
202
203 static dbus_bool_t
204 add_list_to_client (DBusList        **list,
205                     BusClientPolicy  *client)
206 {
207   DBusList *link;
208
209   link = _dbus_list_get_first_link (list);
210   while (link != NULL)
211     {
212       BusPolicyRule *rule = link->data;
213       link = _dbus_list_get_next_link (list, link);
214
215       switch (rule->type)
216         {
217         case BUS_POLICY_RULE_USER:
218         case BUS_POLICY_RULE_GROUP:
219           /* These aren't per-connection policies */
220           break;
221
222         case BUS_POLICY_RULE_OWN:
223         case BUS_POLICY_RULE_SEND:
224         case BUS_POLICY_RULE_RECEIVE:
225           /* These are per-connection */
226           if (!bus_client_policy_append_rule (client, rule))
227             return FALSE;
228           break;
229         }
230     }
231   
232   return TRUE;
233 }
234
235 BusClientPolicy*
236 bus_policy_create_client_policy (BusPolicy      *policy,
237                                  DBusConnection *connection,
238                                  DBusError      *error)
239 {
240   BusClientPolicy *client;
241   unsigned long uid;
242
243   _dbus_assert (dbus_connection_get_is_authenticated (connection));
244   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
245   
246   client = bus_client_policy_new ();
247   if (client == NULL)
248     goto nomem;
249
250   if (!add_list_to_client (&policy->default_rules,
251                            client))
252     goto nomem;
253
254   /* we avoid the overhead of looking up user's groups
255    * if we don't have any group rules anyway
256    */
257   if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
258     {
259       unsigned long *groups;
260       int n_groups;
261       int i;
262       
263       if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
264         goto failed;
265       
266       i = 0;
267       while (i < n_groups)
268         {
269           DBusList **list;
270           
271           list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,
272                                                 groups[i]);
273           
274           if (list != NULL)
275             {
276               if (!add_list_to_client (list, client))
277                 {
278                   dbus_free (groups);
279                   goto nomem;
280                 }
281             }
282           
283           ++i;
284         }
285
286       dbus_free (groups);
287     }
288
289   if (!dbus_connection_get_unix_user (connection, &uid))
290     {
291       dbus_set_error (error, DBUS_ERROR_FAILED,
292                       "No user ID known for connection, cannot determine security policy\n");
293       goto failed;
294     }
295
296   if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
297     {
298       DBusList **list;
299       
300       list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
301                                             uid);
302
303       if (list != NULL)
304         {
305           if (!add_list_to_client (list, client))
306             goto nomem;
307         }
308     }
309
310   if (!add_list_to_client (&policy->mandatory_rules,
311                            client))
312     goto nomem;
313
314   bus_client_policy_optimize (client);
315   
316   return client;
317
318  nomem:
319   BUS_SET_OOM (error);
320  failed:
321   _DBUS_ASSERT_ERROR_IS_SET (error);
322   if (client)
323     bus_client_policy_unref (client);
324   return NULL;
325 }
326
327 static dbus_bool_t
328 list_allows_user (dbus_bool_t           def,
329                   DBusList            **list,
330                   unsigned long         uid,
331                   const unsigned long  *group_ids,
332                   int                   n_group_ids)
333 {
334   DBusList *link;
335   dbus_bool_t allowed;
336   
337   allowed = def;
338
339   link = _dbus_list_get_first_link (list);
340   while (link != NULL)
341     {
342       BusPolicyRule *rule = link->data;
343       link = _dbus_list_get_next_link (list, link);
344       
345       if (rule->type == BUS_POLICY_RULE_USER)
346         {
347           _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
348                          list, rule->d.user.uid);
349           
350           if (rule->d.user.uid == DBUS_UID_UNSET)
351             ; /* '*' wildcard */
352           else if (rule->d.user.uid != uid)
353             continue;
354         }
355       else if (rule->type == BUS_POLICY_RULE_GROUP)
356         {
357           _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n",
358                          list, rule->d.user.uid);
359           
360           if (rule->d.group.gid == DBUS_GID_UNSET)
361             ;  /* '*' wildcard */
362           else
363             {
364               int i;
365               
366               i = 0;
367               while (i < n_group_ids)
368                 {
369                   if (rule->d.group.gid == group_ids[i])
370                     break;
371                   ++i;
372                 }
373               
374               if (i == n_group_ids)
375                 continue;
376             }
377         }
378       else
379         continue;
380
381       allowed = rule->allow;
382     }
383   
384   return allowed;
385 }
386
387 dbus_bool_t
388 bus_policy_allow_user (BusPolicy        *policy,
389                        DBusUserDatabase *user_database,
390                        unsigned long     uid)
391 {
392   dbus_bool_t allowed;
393   unsigned long *group_ids;
394   int n_group_ids;
395
396   /* On OOM or error we always reject the user */
397   if (!_dbus_user_database_get_groups (user_database,
398                                        uid, &group_ids, &n_group_ids, NULL))
399     {
400       _dbus_verbose ("Did not get any groups for UID %lu\n",
401                      uid);
402       return FALSE;
403     }
404   
405   allowed = FALSE;
406
407   allowed = list_allows_user (allowed,
408                               &policy->default_rules,
409                               uid,
410                               group_ids, n_group_ids);
411
412   allowed = list_allows_user (allowed,
413                               &policy->mandatory_rules,
414                               uid,
415                               group_ids, n_group_ids);
416
417   dbus_free (group_ids);
418
419   _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
420   
421   return allowed;
422 }
423
424 dbus_bool_t
425 bus_policy_append_default_rule (BusPolicy      *policy,
426                                 BusPolicyRule  *rule)
427 {
428   if (!_dbus_list_append (&policy->default_rules, rule))
429     return FALSE;
430
431   bus_policy_rule_ref (rule);
432
433   return TRUE;
434 }
435
436 dbus_bool_t
437 bus_policy_append_mandatory_rule (BusPolicy      *policy,
438                                   BusPolicyRule  *rule)
439 {
440   if (!_dbus_list_append (&policy->mandatory_rules, rule))
441     return FALSE;
442
443   bus_policy_rule_ref (rule);
444
445   return TRUE;
446 }
447
448 static DBusList**
449 get_list (DBusHashTable *hash,
450           unsigned long  key)
451 {
452   DBusList **list;
453
454   list = _dbus_hash_table_lookup_ulong (hash, key);
455
456   if (list == NULL)
457     {
458       list = dbus_new0 (DBusList*, 1);
459       if (list == NULL)
460         return NULL;
461
462       if (!_dbus_hash_table_insert_ulong (hash, key, list))
463         {
464           dbus_free (list);
465           return NULL;
466         }
467     }
468
469   return list;
470 }
471
472 dbus_bool_t
473 bus_policy_append_user_rule (BusPolicy      *policy,
474                              dbus_uid_t      uid,
475                              BusPolicyRule  *rule)
476 {
477   DBusList **list;
478
479   list = get_list (policy->rules_by_uid, uid);
480
481   if (list == NULL)
482     return FALSE;
483
484   if (!_dbus_list_append (list, rule))
485     return FALSE;
486
487   bus_policy_rule_ref (rule);
488
489   return TRUE;
490 }
491
492 dbus_bool_t
493 bus_policy_append_group_rule (BusPolicy      *policy,
494                               dbus_gid_t      gid,
495                               BusPolicyRule  *rule)
496 {
497   DBusList **list;
498
499   list = get_list (policy->rules_by_gid, gid);
500
501   if (list == NULL)
502     return FALSE;
503
504   if (!_dbus_list_append (list, rule))
505     return FALSE;
506
507   bus_policy_rule_ref (rule);
508
509   return TRUE;
510 }
511
512 struct BusClientPolicy
513 {
514   int refcount;
515
516   DBusList *rules;
517 };
518
519 BusClientPolicy*
520 bus_client_policy_new (void)
521 {
522   BusClientPolicy *policy;
523
524   policy = dbus_new0 (BusClientPolicy, 1);
525   if (policy == NULL)
526     return NULL;
527
528   policy->refcount = 1;
529
530   return policy;
531 }
532
533 void
534 bus_client_policy_ref (BusClientPolicy *policy)
535 {
536   _dbus_assert (policy->refcount > 0);
537
538   policy->refcount += 1;
539 }
540
541 static void
542 rule_unref_foreach (void *data,
543                     void *user_data)
544 {
545   BusPolicyRule *rule = data;
546
547   bus_policy_rule_unref (rule);
548 }
549
550 void
551 bus_client_policy_unref (BusClientPolicy *policy)
552 {
553   _dbus_assert (policy->refcount > 0);
554
555   policy->refcount -= 1;
556
557   if (policy->refcount == 0)
558     {
559       _dbus_list_foreach (&policy->rules,
560                           rule_unref_foreach,
561                           NULL);
562
563       _dbus_list_clear (&policy->rules);
564       
565       dbus_free (policy);
566     }
567 }
568
569 static void
570 remove_rules_by_type_up_to (BusClientPolicy   *policy,
571                             BusPolicyRuleType  type,
572                             DBusList          *up_to)
573 {
574   DBusList *link;
575
576   link = _dbus_list_get_first_link (&policy->rules);
577   while (link != up_to)
578     {
579       BusPolicyRule *rule = link->data;
580       DBusList *next = _dbus_list_get_next_link (&policy->rules, link);
581
582       if (rule->type == type)
583         {
584           _dbus_list_remove_link (&policy->rules, link);
585           bus_policy_rule_unref (rule);
586         }
587       
588       link = next;
589     }
590 }
591
592 void
593 bus_client_policy_optimize (BusClientPolicy *policy)
594 {
595   DBusList *link;
596
597   /* The idea here is that if we have:
598    * 
599    * <allow send="foo"/>
600    * <deny send="*"/>
601    *
602    * (for example) the deny will always override the allow.  So we
603    * delete the allow. Ditto for deny followed by allow, etc. This is
604    * a dumb thing to put in a config file, but the <include> feature
605    * of files allows for an "inheritance and override" pattern where
606    * it could make sense. If an included file wants to "start over"
607    * with a blanket deny, no point keeping the rules from the parent
608    * file.
609    */
610
611   _dbus_verbose ("Optimizing policy with %d rules\n",
612                  _dbus_list_get_length (&policy->rules));
613   
614   link = _dbus_list_get_first_link (&policy->rules);
615   while (link != NULL)
616     {
617       BusPolicyRule *rule;
618       DBusList *next;
619       dbus_bool_t remove_preceding;
620
621       next = _dbus_list_get_next_link (&policy->rules, link);
622       rule = link->data;
623       
624       remove_preceding = FALSE;
625
626       _dbus_assert (rule != NULL);
627       
628       switch (rule->type)
629         {
630         case BUS_POLICY_RULE_SEND:
631           remove_preceding =
632             rule->d.send.message_name == NULL &&
633             rule->d.send.destination == NULL;
634           break;
635         case BUS_POLICY_RULE_RECEIVE:
636           remove_preceding =
637             rule->d.receive.message_name == NULL &&
638             rule->d.receive.origin == NULL;
639           break;
640         case BUS_POLICY_RULE_OWN:
641           remove_preceding =
642             rule->d.own.service_name == NULL;
643           break;
644         case BUS_POLICY_RULE_USER:
645         case BUS_POLICY_RULE_GROUP:
646           _dbus_assert_not_reached ("invalid rule");
647           break;
648         }
649
650       if (remove_preceding)
651         remove_rules_by_type_up_to (policy, rule->type,
652                                     link);
653       
654       link = next;
655     }
656
657   _dbus_verbose ("After optimization, policy has %d rules\n",
658                  _dbus_list_get_length (&policy->rules));
659 }
660
661 dbus_bool_t
662 bus_client_policy_append_rule (BusClientPolicy *policy,
663                                BusPolicyRule   *rule)
664 {
665   _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
666                  rule, rule->type, policy);
667   
668   if (!_dbus_list_append (&policy->rules, rule))
669     return FALSE;
670
671   bus_policy_rule_ref (rule);
672
673   return TRUE;
674 }
675
676 dbus_bool_t
677 bus_client_policy_check_can_send (BusClientPolicy *policy,
678                                   BusRegistry     *registry,
679                                   DBusConnection  *receiver,
680                                   DBusMessage     *message)
681 {
682   DBusList *link;
683   dbus_bool_t allowed;
684   
685   /* policy->rules is in the order the rules appeared
686    * in the config file, i.e. last rule that applies wins
687    */
688
689   _dbus_verbose ("  (policy) checking send rules\n");
690   
691   allowed = FALSE;
692   link = _dbus_list_get_first_link (&policy->rules);
693   while (link != NULL)
694     {
695       BusPolicyRule *rule = link->data;
696
697       link = _dbus_list_get_next_link (&policy->rules, link);
698       
699       /* Rule is skipped if it specifies a different
700        * message name from the message, or a different
701        * destination from the message
702        */
703       
704       if (rule->type != BUS_POLICY_RULE_SEND)
705         {
706           _dbus_verbose ("  (policy) skipping non-send rule\n");
707           continue;
708         }
709
710       if (rule->d.send.message_name != NULL)
711         {
712           if (!dbus_message_has_name (message,
713                                       rule->d.send.message_name))
714             {
715               _dbus_verbose ("  (policy) skipping rule for different message name\n");
716               continue;
717             }
718         }
719
720       if (rule->d.send.destination != NULL)
721         {
722           /* receiver can be NULL for messages that are sent to the
723            * message bus itself, we check the strings in that case as
724            * built-in services don't have a DBusConnection but messages
725            * to them have a destination service name.
726            */
727           if (receiver == NULL)
728             {
729               if (!dbus_message_has_destination (message,
730                                                  rule->d.send.destination))
731                 {
732                   _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
733                                  rule->d.send.destination);
734                   continue;
735                 }
736             }
737           else
738             {
739               DBusString str;
740               BusService *service;
741               
742               _dbus_string_init_const (&str, rule->d.send.destination);
743               
744               service = bus_registry_lookup (registry, &str);
745               if (service == NULL)
746                 {
747                   _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
748                                  rule->d.send.destination);
749                   continue;
750                 }
751
752               if (!bus_service_has_owner (service, receiver))
753                 {
754                   _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
755                                  rule->d.send.destination);
756                   continue;
757                 }
758             }
759         }
760
761       /* Use this rule */
762       allowed = rule->allow;
763
764       _dbus_verbose ("  (policy) used rule, allow now = %d\n",
765                      allowed);
766     }
767
768   return allowed;
769 }
770
771 dbus_bool_t
772 bus_client_policy_check_can_receive (BusClientPolicy *policy,
773                                      BusRegistry     *registry,
774                                      DBusConnection  *sender,
775                                      DBusMessage     *message)
776 {
777   DBusList *link;
778   dbus_bool_t allowed;
779   
780   /* policy->rules is in the order the rules appeared
781    * in the config file, i.e. last rule that applies wins
782    */
783
784   _dbus_verbose ("  (policy) checking receive rules\n");
785   
786   allowed = FALSE;
787   link = _dbus_list_get_first_link (&policy->rules);
788   while (link != NULL)
789     {
790       BusPolicyRule *rule = link->data;
791
792       link = _dbus_list_get_next_link (&policy->rules, link);
793       
794       /* Rule is skipped if it specifies a different
795        * message name from the message, or a different
796        * origin from the message
797        */
798       
799       if (rule->type != BUS_POLICY_RULE_RECEIVE)
800         {
801           _dbus_verbose ("  (policy) skipping non-receive rule\n");
802           continue;
803         }
804
805       if (rule->d.receive.message_name != NULL)
806         {
807           if (!dbus_message_has_name (message,
808                                       rule->d.receive.message_name))
809             {
810               _dbus_verbose ("  (policy) skipping rule for different message name\n");
811               continue;
812             }
813         }
814
815       if (rule->d.receive.origin != NULL)
816         {          
817           /* sender can be NULL for messages that originate from the
818            * message bus itself, we check the strings in that case as
819            * built-in services don't have a DBusConnection but will
820            * still set the sender on their messages.
821            */
822           if (sender == NULL)
823             {
824               if (!dbus_message_has_sender (message,
825                                             rule->d.receive.origin))
826                 {
827                   _dbus_verbose ("  (policy) skipping rule because message sender is not %s\n",
828                                  rule->d.receive.origin);
829                   continue;
830                 }
831             }
832           else
833             {
834               BusService *service;
835               DBusString str;
836
837               _dbus_string_init_const (&str, rule->d.receive.origin);
838               
839               service = bus_registry_lookup (registry, &str);
840               
841               if (service == NULL)
842                 {
843                   _dbus_verbose ("  (policy) skipping rule because origin %s doesn't exist\n",
844                                  rule->d.receive.origin);
845                   continue;
846                 }
847
848               if (!bus_service_has_owner (service, sender))
849                 {
850                   _dbus_verbose ("  (policy) skipping rule because origin %s isn't owned by sender\n",
851                                  rule->d.receive.origin);
852                   continue;
853                 }
854             }
855         }
856
857       /* Use this rule */
858       allowed = rule->allow;
859
860       _dbus_verbose ("  (policy) used rule, allow now = %d\n",
861                      allowed);
862     }
863
864   return allowed;
865 }
866
867 dbus_bool_t
868 bus_client_policy_check_can_own (BusClientPolicy  *policy,
869                                  DBusConnection   *connection,
870                                  const DBusString *service_name)
871 {
872   DBusList *link;
873   dbus_bool_t allowed;
874   
875   /* policy->rules is in the order the rules appeared
876    * in the config file, i.e. last rule that applies wins
877    */
878
879   allowed = FALSE;
880   link = _dbus_list_get_first_link (&policy->rules);
881   while (link != NULL)
882     {
883       BusPolicyRule *rule = link->data;
884
885       link = _dbus_list_get_next_link (&policy->rules, link);
886       
887       /* Rule is skipped if it specifies a different service name from
888        * the desired one.
889        */
890       
891       if (rule->type != BUS_POLICY_RULE_OWN)
892         continue;
893
894       if (rule->d.own.service_name != NULL)
895         {
896           if (!_dbus_string_equal_c_str (service_name,
897                                          rule->d.own.service_name))
898             continue;
899         }
900
901       /* Use this rule */
902       allowed = rule->allow;
903     }
904
905   return allowed;
906 }
907
908 #ifdef DBUS_BUILD_TESTS
909
910 dbus_bool_t
911 bus_policy_test (const DBusString *test_data_dir)
912 {
913   /* This doesn't do anything for now because I decided to do it in
914    * dispatch.c instead by having some of the clients in dispatch.c
915    * have particular policies applied to them.
916    */
917   
918   return TRUE;
919 }
920
921 #endif /* DBUS_BUILD_TESTS */