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