2004-07-24 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / bus / policy.c
index ed58a95..c7359c8 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: C; c-file-style: "gnu" -*- */
 /* policy.c  Bus security policy
  *
- * Copyright (C) 2003  Red Hat, Inc.
+ * Copyright (C) 2003, 2004  Red Hat, Inc.
  *
  * Licensed under the Academic Free License version 2.0
  * 
@@ -53,6 +53,11 @@ bus_policy_rule_new (BusPolicyRuleType type,
       break;
     case BUS_POLICY_RULE_SEND:
       rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
+
+      /* allow rules default to TRUE (only requested replies allowed)
+       * deny rules default to FALSE (only unrequested replies denied)
+       */
+      rule->d.send.requested_reply = rule->allow;
       break;
     case BUS_POLICY_RULE_RECEIVE:
       rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
@@ -172,7 +177,7 @@ bus_policy_new (void)
                                                free_rule_list_func);
   if (policy->rules_by_gid == NULL)
     goto failed;
-  
+
   return policy;
   
  failed:
@@ -589,9 +594,10 @@ dbus_bool_t
 bus_policy_merge (BusPolicy *policy,
                   BusPolicy *to_absorb)
 {
-  /* Not properly atomic, but as used for configuration files
-   * we don't rely on it.
-   */  
+  /* FIXME Not properly atomic, but as used for configuration files we
+   * don't rely on it quite so much.
+   */
+  
   if (!append_copy_of_policy_list (&policy->default_rules,
                                    &to_absorb->default_rules))
     return FALSE;
@@ -665,7 +671,7 @@ bus_client_policy_unref (BusClientPolicy *policy)
                           NULL);
 
       _dbus_list_clear (&policy->rules);
-      
+
       dbus_free (policy);
     }
 }
@@ -788,6 +794,7 @@ bus_client_policy_append_rule (BusClientPolicy *policy,
 dbus_bool_t
 bus_client_policy_check_can_send (BusClientPolicy *policy,
                                   BusRegistry     *registry,
+                                  dbus_bool_t      requested_reply,
                                   DBusConnection  *receiver,
                                   DBusMessage     *message)
 {
@@ -827,6 +834,30 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
               continue;
             }
         }
+
+      /* If it's a reply, the requested_reply flag kicks in */
+      if (dbus_message_get_reply_serial (message) != 0)
+        {
+          /* for allow, requested_reply=true means the rule applies
+           * only when reply was requested. requested_reply=false means
+           * always allow.
+           */
+          if (!requested_reply && rule->allow && rule->d.send.requested_reply)
+            {
+              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies\n");
+              continue;
+            }
+
+          /* for deny, requested_reply=false means the rule applies only
+           * when the reply was not requested. requested_reply=true means the
+           * rule always applies.
+           */
+          if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
+            {
+              _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
+              continue;
+            }
+        }
       
       if (rule->d.send.path != NULL)
         {