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