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