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