2003-04-12 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sat, 12 Apr 2003 18:32:11 +0000 (18:32 +0000)
committerHavoc Pennington <hp@redhat.com>
Sat, 12 Apr 2003 18:32:11 +0000 (18:32 +0000)
* bus/policy.h: change BusPolicy to be the thing from the config
file, and rename old BusPolicy to BusClientPolicy

* bus/bus.c, bus/connection.c, bus/config-parser.c: change to
match change in how policy works

* dbus/dbus-internals.h: mark assert_not_reached as
__attribute((noreturn))__

12 files changed:
ChangeLog
bus/bus.c
bus/bus.h
bus/config-parser.c
bus/config-parser.h
bus/connection.c
bus/connection.h
bus/policy.c
bus/policy.h
dbus/dbus-internals.h
doc/config-file.txt
test/data/valid-config-files/entities.conf [new file with mode: 0644]

index 3132df6..7808483 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-04-12  Havoc Pennington  <hp@pobox.com>
+
+       * bus/policy.h: change BusPolicy to be the thing from the config
+       file, and rename old BusPolicy to BusClientPolicy
+
+       * bus/bus.c, bus/connection.c, bus/config-parser.c: change to 
+       match change in how policy works
+
+       * dbus/dbus-internals.h: mark assert_not_reached as
+       __attribute((noreturn))__
+
 2003-04-11  Havoc Pennington  <hp@redhat.com>
 
        * configure.in: add another directory to look for qt in.
index 3b2ffc0..31b43f2 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -43,10 +43,7 @@ struct BusContext
   BusConnections *connections;
   BusActivation *activation;
   BusRegistry *registry;
-  DBusList *default_rules;       /**< Default policy rules */
-  DBusList *mandatory_rules;     /**< Mandatory policy rules */
-  DBusHashTable *rules_by_uid;   /**< per-UID policy rules */
-  DBusHashTable *rules_by_gid;   /**< per-GID policy rules */
+  BusPolicy *policy;
   int activation_timeout;        /**< How long to wait for an activation to time out */
   int auth_timeout;              /**< How long to wait for an authentication to time out */
   int max_completed_connections;    /**< Max number of authorized connections */
@@ -214,27 +211,6 @@ new_connection_callback (DBusServer     *server,
 }
 
 static void
-free_rule_func (void *data,
-                void *user_data)
-{
-  BusPolicyRule *rule = data;
-
-  bus_policy_rule_unref (rule);
-}
-
-static void
-free_rule_list_func (void *data)
-{
-  DBusList **list = data;
-
-  _dbus_list_foreach (list, free_rule_func, NULL);
-  
-  _dbus_list_clear (list);
-
-  dbus_free (list);
-}
-
-static void
 free_server_data (void *data)
 {
   BusServerData *bd = data;  
@@ -565,25 +541,10 @@ bus_context_new (const DBusString *config_file,
       BUS_SET_OOM (error);
       goto failed;
     }
-  
-  context->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
-                                                NULL,
-                                                free_rule_list_func);
-  if (context->rules_by_uid == NULL)
-    {
-      BUS_SET_OOM (error);
-      goto failed;
-    }
-
-  context->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
-                                                NULL,
-                                                free_rule_list_func);
-  if (context->rules_by_gid == NULL)
-    {
-      BUS_SET_OOM (error);
-      goto failed;
-    }
 
+  context->policy = bus_config_parser_steal_policy (parser);
+  _dbus_assert (context->policy != NULL);
+  
   /* Now become a daemon if appropriate */
   if (bus_config_parser_get_fork (parser))
     {
@@ -744,18 +705,12 @@ bus_context_unref (BusContext *context)
         }
       _dbus_list_clear (&context->servers);
 
-      if (context->rules_by_uid)
-        {
-          _dbus_hash_table_unref (context->rules_by_uid);
-          context->rules_by_uid = NULL;
-        }
-
-      if (context->rules_by_gid)
+      if (context->policy)
         {
-          _dbus_hash_table_unref (context->rules_by_gid);
-          context->rules_by_gid = NULL;
+          bus_policy_unref (context->policy);
+          context->policy = NULL;
         }
-
+      
       if (context->loop)
         {
           _dbus_loop_unref (context->loop);
@@ -821,184 +776,18 @@ bus_context_get_loop (BusContext *context)
   return context->loop;
 }
 
-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)
-{
-  DBusList *link;
-  dbus_bool_t allowed;
-  
-  allowed = def;
-
-  link = _dbus_list_get_first_link (list);
-  while (link != NULL)
-    {
-      BusPolicyRule *rule = link->data;
-      link = _dbus_list_get_next_link (list, link);
-      
-      if (rule->type == BUS_POLICY_RULE_USER)
-        {
-          if (rule->d.user.uid != uid)
-            continue;
-        }
-      else if (rule->type == BUS_POLICY_RULE_GROUP)
-        {
-          int i;
-
-          i = 0;
-          while (i < n_group_ids)
-            {
-              if (rule->d.group.gid == group_ids[i])
-                break;
-              ++i;
-            }
-
-          if (i == n_group_ids)
-            continue;
-        }
-      else
-        continue;
-
-      allowed = rule->allow;
-    }
-  
-  return allowed;
-}
-
 dbus_bool_t
 bus_context_allow_user (BusContext   *context,
                         unsigned long uid)
 {
-  dbus_bool_t allowed;
-  unsigned long *group_ids;
-  int n_group_ids;
-
-  /* On OOM or error we always reject the user */
-  if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
-    {
-      _dbus_verbose ("Did not get any groups for UID %lu\n",
-                     uid);
-      return FALSE;
-    }
-  
-  allowed = FALSE;
-
-  allowed = list_allows_user (allowed,
-                              &context->default_rules,
-                              uid,
-                              group_ids, n_group_ids);
-
-  allowed = list_allows_user (allowed,
-                              &context->mandatory_rules,
-                              uid,
-                              group_ids, n_group_ids);
-
-  dbus_free (group_ids);
-
-  return allowed;
-}
-
-static dbus_bool_t
-add_list_to_policy (DBusList       **list,
-                    BusPolicy       *policy)
-{
-  DBusList *link;
-
-  link = _dbus_list_get_first_link (list);
-  while (link != NULL)
-    {
-      BusPolicyRule *rule = link->data;
-      link = _dbus_list_get_next_link (list, link);
-
-      switch (rule->type)
-        {
-        case BUS_POLICY_RULE_USER:
-        case BUS_POLICY_RULE_GROUP:
-          /* These aren't per-connection policies */
-          break;
-
-        case BUS_POLICY_RULE_OWN:
-        case BUS_POLICY_RULE_SEND:
-        case BUS_POLICY_RULE_RECEIVE:
-          /* These are per-connection */
-          if (!bus_policy_append_rule (policy, rule))
-            return FALSE;
-          break;
-        }
-    }
-  
-  return TRUE;
+  return bus_policy_allow_user (context->policy, uid);
 }
 
-BusPolicy*
-bus_context_create_connection_policy (BusContext      *context,
-                                      DBusConnection  *connection)
+BusClientPolicy*
+bus_context_create_client_policy (BusContext      *context,
+                                  DBusConnection  *connection)
 {
-  BusPolicy *policy;
-  unsigned long uid;
-  DBusList **list;
-
-  _dbus_assert (dbus_connection_get_is_authenticated (connection));
-  
-  policy = bus_policy_new ();
-  if (policy == NULL)
-    return NULL;
-
-  if (!add_list_to_policy (&context->default_rules,
-                                      policy))
-    goto failed;
-
-  /* we avoid the overhead of looking up user's groups
-   * if we don't have any group rules anyway
-   */
-  if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
-    {
-      const unsigned long *groups;
-      int n_groups;
-      int i;
-      
-      if (!bus_connection_get_groups (connection, &groups, &n_groups))
-        goto failed;
-      
-      i = 0;
-      while (i < n_groups)
-        {
-          list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
-                                                groups[i]);
-          
-          if (list != NULL)
-            {
-              if (!add_list_to_policy (list, policy))
-                goto failed;
-            }
-          
-          ++i;
-        }
-    }
-
-  if (!dbus_connection_get_unix_user (connection, &uid))
-    goto failed;
-
-  list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
-                                        uid);
-
-  if (!add_list_to_policy (list, policy))
-    goto failed;
-  
-  if (!add_list_to_policy (&context->mandatory_rules,
-                           policy))
-    goto failed;
-
-  bus_policy_optimize (policy);
-  
-  return policy;
-  
- failed:
-  bus_policy_unref (policy);
-  return NULL;
+  return bus_policy_create_client_policy (context->policy, connection);
 }
 
 int
index 60290c0..754fab0 100644 (file)
--- a/bus/bus.h
+++ b/bus/bus.h
 #include <dbus/dbus-string.h>
 #include <dbus/dbus-mainloop.h>
 
-typedef struct BusActivation  BusActivation;
-typedef struct BusConnections BusConnections;
-typedef struct BusContext     BusContext;
-typedef struct BusPolicy      BusPolicy;
-typedef struct BusPolicyRule  BusPolicyRule;
-typedef struct BusRegistry    BusRegistry;
-typedef struct BusService     BusService;
-typedef struct BusTransaction BusTransaction;
+typedef struct BusActivation    BusActivation;
+typedef struct BusConnections   BusConnections;
+typedef struct BusContext       BusContext;
+typedef struct BusPolicy        BusPolicy;
+typedef struct BusClientPolicy  BusClientPolicy;
+typedef struct BusPolicyRule    BusPolicyRule;
+typedef struct BusRegistry      BusRegistry;
+typedef struct BusService       BusService;
+typedef struct BusTransaction   BusTransaction;
+
+BusContext*      bus_context_new                    (const DBusString *config_file,
+                                                     int               print_addr_fd,
+                                                     DBusError        *error);
+void             bus_context_shutdown               (BusContext       *context);
+void             bus_context_ref                    (BusContext       *context);
+void             bus_context_unref                  (BusContext       *context);
+const char*      bus_context_get_type               (BusContext       *context);
+const char*      bus_context_get_address            (BusContext       *context);
+BusRegistry*     bus_context_get_registry           (BusContext       *context);
+BusConnections*  bus_context_get_connections        (BusContext       *context);
+BusActivation*   bus_context_get_activation         (BusContext       *context);
+DBusLoop*        bus_context_get_loop               (BusContext       *context);
+dbus_bool_t      bus_context_allow_user             (BusContext       *context,
+                                                     unsigned long     uid);
+BusClientPolicy* bus_context_create_client_policy   (BusContext       *context,
+                                                     DBusConnection   *connection);
+int              bus_context_get_activation_timeout (BusContext       *context);
 
-BusContext*     bus_context_new                      (const DBusString *config_file,
-                                                      int               print_addr_fd,
-                                                      DBusError        *error);
-void            bus_context_shutdown                 (BusContext       *context);
-void            bus_context_ref                      (BusContext       *context);
-void            bus_context_unref                    (BusContext       *context);
-const char*     bus_context_get_type                 (BusContext       *context);
-const char*     bus_context_get_address              (BusContext       *context);
-BusRegistry*    bus_context_get_registry             (BusContext       *context);
-BusConnections* bus_context_get_connections          (BusContext       *context);
-BusActivation*  bus_context_get_activation           (BusContext       *context);
-DBusLoop*       bus_context_get_loop                 (BusContext       *context);
-dbus_bool_t     bus_context_allow_user               (BusContext       *context,
-                                                      unsigned long     uid);
-BusPolicy*      bus_context_create_connection_policy (BusContext       *context,
-                                                      DBusConnection   *connection);
-int             bus_context_get_activation_timeout   (BusContext       *context);
 
 #endif /* BUS_BUS_H */
index 1052dc2..780d175 100644 (file)
@@ -23,6 +23,7 @@
 #include "config-parser.h"
 #include "test.h"
 #include "utils.h"
+#include "policy.h"
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-internals.h>
 #include <string.h>
@@ -93,6 +94,8 @@ struct BusConfigParser
   DBusList *mechanisms; /**< Auth mechanisms */
 
   DBusList *service_dirs; /**< Directories to look for services in */
+
+  BusPolicy *policy;     /**< Security policy */
   
   unsigned int fork : 1; /**< TRUE to fork into daemon mode */
 
@@ -262,7 +265,8 @@ bus_config_parser_new (const DBusString *basedir)
       return NULL;
     }
 
-  if (!_dbus_string_copy (basedir, 0, &parser->basedir, 0))
+  if (((parser->policy = bus_policy_new ()) == NULL) ||
+      !_dbus_string_copy (basedir, 0, &parser->basedir, 0))
     {
       _dbus_string_free (&parser->basedir);
       dbus_free (parser);
@@ -317,6 +321,9 @@ bus_config_parser_unref (BusConfigParser *parser)
       _dbus_list_clear (&parser->mechanisms);
       
       _dbus_string_free (&parser->basedir);
+
+      if (parser->policy)
+        bus_policy_unref (parser->policy);
       
       dbus_free (parser);
     }
@@ -627,7 +634,7 @@ start_busconfig_child (BusConfigParser   *parser,
           return FALSE;
         }
 
-      if (!locate_attributes (parser, "include",
+      if (!locate_attributes (parser, "policy",
                               attribute_names,
                               attribute_values,
                               error,
@@ -637,7 +644,51 @@ start_busconfig_child (BusConfigParser   *parser,
                               NULL))
         return FALSE;
 
-      /* FIXME */
+      if (((context && user) ||
+           (context && group)) ||
+          (user && group) ||
+          !(context || user || group))
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "<policy> element must have exactly one of (context|user|group) attributes");
+          return FALSE;
+        }
+
+      if (context != NULL)
+        {
+          if (strcmp (context, "default") == 0)
+            {
+
+            }
+          else if (strcmp (context, "mandatory") == 0)
+            {
+
+            }
+          else
+            {
+              dbus_set_error (error, DBUS_ERROR_FAILED,
+                              "context attribute on <policy> must have the value \"default\" or \"mandatory\", not \"%s\"",
+                              context);
+              return FALSE;
+            }
+          
+          /* FIXME */
+
+        }
+      else if (user != NULL)
+        {
+          /* FIXME */
+
+        }
+      else if (group != NULL)
+        {
+          /* FIXME */
+
+        }
+      else
+        {
+          _dbus_assert_not_reached ("all <policy> attributes null and we didn't set error");
+        }
       
       return TRUE;
     }
@@ -1269,6 +1320,20 @@ bus_config_parser_get_pidfile (BusConfigParser   *parser)
   return parser->pidfile;
 }
 
+BusPolicy*
+bus_config_parser_steal_policy (BusConfigParser *parser)
+{
+  BusPolicy *policy;
+
+  _dbus_assert (parser->policy != NULL); /* can only steal the policy 1 time */
+  
+  policy = parser->policy;
+
+  parser->policy = NULL;
+
+  return policy;
+}
+
 #ifdef DBUS_BUILD_TESTS
 #include <stdio.h>
 
index 93d4100..15644ee 100644 (file)
@@ -29,6 +29,7 @@
 #include <dbus/dbus.h>
 #include <dbus/dbus-string.h>
 #include <dbus/dbus-list.h>
+#include "bus.h"
 
 /* Whatever XML library we're using just pushes data into this API */
 
@@ -62,6 +63,7 @@ DBusList**  bus_config_parser_get_mechanisms   (BusConfigParser *parser);
 dbus_bool_t bus_config_parser_get_fork         (BusConfigParser *parser);
 const char* bus_config_parser_get_pidfile      (BusConfigParser *parser);
 DBusList**  bus_config_parser_get_service_dirs (BusConfigParser *parser);
+BusPolicy*  bus_config_parser_steal_policy     (BusConfigParser *parser);
 
 /* Loader functions (backended off one of the XML parsers).  Returns a
  * finished ConfigParser.
index 2cfbeb2..21c8f1a 100644 (file)
@@ -50,7 +50,7 @@ typedef struct
   DBusPreallocatedSend *oom_preallocated;
   unsigned long *group_ids;
   int n_group_ids;
-  BusPolicy *policy;
+  BusClientPolicy *policy;
 } BusConnectionData;
 
 #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
@@ -306,7 +306,7 @@ free_connection_data (void *data)
     dbus_message_unref (d->oom_message);
 
   if (d->policy)
-    bus_policy_unref (d->policy);
+    bus_client_policy_unref (d->policy);
   
   dbus_free (d->group_ids);
   
@@ -541,7 +541,7 @@ bus_connection_is_in_group (DBusConnection *connection,
   return FALSE;
 }
 
-BusPolicy*
+BusClientPolicy*
 bus_connection_get_policy (DBusConnection *connection)
 {
   BusConnectionData *d;
@@ -562,8 +562,8 @@ bus_connection_get_policy (DBusConnection *connection)
   if (d->policy == NULL)
     {
       d->policy =
-        bus_context_create_connection_policy (d->connections->context,
-                                              connection);
+        bus_context_create_client_policy (d->connections->context,
+                                          connection);
 
       /* we may have a NULL policy on OOM or error getting list of
        * groups for a user. In the latter case we don't handle it so
index 6108bdf..4962211 100644 (file)
@@ -70,12 +70,12 @@ const char *bus_connection_get_name (DBusConnection               *connection);
 /* called by dispatch.c when the connection is dropped */
 void        bus_connection_disconnected (DBusConnection *connection);
 
-dbus_bool_t bus_connection_is_in_group (DBusConnection       *connection,
-                                        unsigned long         gid);
-dbus_bool_t bus_connection_get_groups  (DBusConnection       *connection,
-                                        const unsigned long **groups,
-                                        int                  *n_groups);
-BusPolicy*  bus_connection_get_policy  (DBusConnection       *connection);
+dbus_bool_t      bus_connection_is_in_group (DBusConnection       *connection,
+                                             unsigned long         gid);
+dbus_bool_t      bus_connection_get_groups  (DBusConnection       *connection,
+                                             const unsigned long **groups,
+                                             int                  *n_groups);
+BusClientPolicy* bus_connection_get_policy  (DBusConnection       *connection);
 
 /* transaction API so we can send or not send a block of messages as a whole */
 
index b518771..cff2509 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- mode: C; c-file-style: "gnu" -*- */
-/* policy.c  Policies for what a connection can do
+/* policy.c  Bus security policy
  *
  * Copyright (C) 2003  Red Hat, Inc.
  *
@@ -25,6 +25,7 @@
 #include "services.h"
 #include "test.h"
 #include <dbus/dbus-list.h>
+#include <dbus/dbus-hash.h>
 #include <dbus/dbus-internals.h>
 
 BusPolicyRule*
@@ -88,9 +89,33 @@ struct BusPolicy
 {
   int refcount;
 
-  DBusList *rules;
+  DBusList *default_rules;       /**< Default policy rules */
+  DBusList *mandatory_rules;     /**< Mandatory policy rules */
+  DBusHashTable *rules_by_uid;   /**< per-UID policy rules */
+  DBusHashTable *rules_by_gid;   /**< per-GID policy rules */
 };
 
+static void
+free_rule_func (void *data,
+                void *user_data)
+{
+  BusPolicyRule *rule = data;
+
+  bus_policy_rule_unref (rule);
+}
+
+static void
+free_rule_list_func (void *data)
+{
+  DBusList **list = data;
+
+  _dbus_list_foreach (list, free_rule_func, NULL);
+  
+  _dbus_list_clear (list);
+
+  dbus_free (list);
+}
+
 BusPolicy*
 bus_policy_new (void)
 {
@@ -101,8 +126,24 @@ bus_policy_new (void)
     return NULL;
 
   policy->refcount = 1;
-
+  
+  policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
+                                               NULL,
+                                               free_rule_list_func);
+  if (policy->rules_by_uid == NULL)
+    goto failed;
+
+  policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
+                                               NULL,
+                                               free_rule_list_func);
+  if (policy->rules_by_gid == NULL)
+    goto failed;
+  
   return policy;
+  
+ failed:
+  bus_policy_unref (policy);
+  return NULL;
 }
 
 void
@@ -113,6 +154,240 @@ bus_policy_ref (BusPolicy *policy)
   policy->refcount += 1;
 }
 
+void
+bus_policy_unref (BusPolicy *policy)
+{
+  _dbus_assert (policy->refcount > 0);
+
+  policy->refcount -= 1;
+
+  if (policy->refcount == 0)
+    {
+      if (policy->rules_by_uid)
+        {
+          _dbus_hash_table_unref (policy->rules_by_uid);
+          policy->rules_by_uid = NULL;
+        }
+
+      if (policy->rules_by_gid)
+        {
+          _dbus_hash_table_unref (policy->rules_by_gid);
+          policy->rules_by_gid = NULL;
+        }
+      
+      dbus_free (policy);
+    }
+}
+
+static dbus_bool_t
+add_list_to_client (DBusList        **list,
+                    BusClientPolicy  *client)
+{
+  DBusList *link;
+
+  link = _dbus_list_get_first_link (list);
+  while (link != NULL)
+    {
+      BusPolicyRule *rule = link->data;
+      link = _dbus_list_get_next_link (list, link);
+
+      switch (rule->type)
+        {
+        case BUS_POLICY_RULE_USER:
+        case BUS_POLICY_RULE_GROUP:
+          /* These aren't per-connection policies */
+          break;
+
+        case BUS_POLICY_RULE_OWN:
+        case BUS_POLICY_RULE_SEND:
+        case BUS_POLICY_RULE_RECEIVE:
+          /* These are per-connection */
+          if (!bus_client_policy_append_rule (client, rule))
+            return FALSE;
+          break;
+        }
+    }
+  
+  return TRUE;
+}
+
+BusClientPolicy*
+bus_policy_create_client_policy (BusPolicy      *policy,
+                                 DBusConnection *connection)
+{
+  BusClientPolicy *client;
+  unsigned long uid;
+  DBusList **list;
+
+  _dbus_assert (dbus_connection_get_is_authenticated (connection));
+  
+  client = bus_client_policy_new ();
+  if (client == NULL)
+    return NULL;
+
+  if (!add_list_to_client (&policy->default_rules,
+                           client))
+    goto failed;
+
+  /* we avoid the overhead of looking up user's groups
+   * if we don't have any group rules anyway
+   */
+  if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
+    {
+      const unsigned long *groups;
+      int n_groups;
+      int i;
+      
+      if (!bus_connection_get_groups (connection, &groups, &n_groups))
+        goto failed;
+      
+      i = 0;
+      while (i < n_groups)
+        {
+          list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,
+                                                groups[i]);
+          
+          if (list != NULL)
+            {
+              if (!add_list_to_client (list, client))
+                goto failed;
+            }
+          
+          ++i;
+        }
+    }
+
+  if (!dbus_connection_get_unix_user (connection, &uid))
+    goto failed;
+
+  list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
+                                        uid);
+
+  if (!add_list_to_client (list, client))
+    goto failed;
+  
+  if (!add_list_to_client (&policy->mandatory_rules,
+                           client))
+    goto failed;
+
+  bus_client_policy_optimize (client);
+  
+  return client;
+  
+ failed:
+  bus_client_policy_unref (client);
+  return NULL;
+}
+
+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)
+{
+  DBusList *link;
+  dbus_bool_t allowed;
+  
+  allowed = def;
+
+  link = _dbus_list_get_first_link (list);
+  while (link != NULL)
+    {
+      BusPolicyRule *rule = link->data;
+      link = _dbus_list_get_next_link (list, link);
+      
+      if (rule->type == BUS_POLICY_RULE_USER)
+        {
+          if (rule->d.user.uid != uid)
+            continue;
+        }
+      else if (rule->type == BUS_POLICY_RULE_GROUP)
+        {
+          int i;
+
+          i = 0;
+          while (i < n_group_ids)
+            {
+              if (rule->d.group.gid == group_ids[i])
+                break;
+              ++i;
+            }
+
+          if (i == n_group_ids)
+            continue;
+        }
+      else
+        continue;
+
+      allowed = rule->allow;
+    }
+  
+  return allowed;
+}
+
+dbus_bool_t
+bus_policy_allow_user (BusPolicy    *policy,
+                       unsigned long uid)
+{
+  dbus_bool_t allowed;
+  unsigned long *group_ids;
+  int n_group_ids;
+
+  /* On OOM or error we always reject the user */
+  if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
+    {
+      _dbus_verbose ("Did not get any groups for UID %lu\n",
+                     uid);
+      return FALSE;
+    }
+  
+  allowed = FALSE;
+
+  allowed = list_allows_user (allowed,
+                              &policy->default_rules,
+                              uid,
+                              group_ids, n_group_ids);
+
+  allowed = list_allows_user (allowed,
+                              &policy->mandatory_rules,
+                              uid,
+                              group_ids, n_group_ids);
+
+  dbus_free (group_ids);
+
+  return allowed;
+}
+
+struct BusClientPolicy
+{
+  int refcount;
+
+  DBusList *rules;
+};
+
+BusClientPolicy*
+bus_client_policy_new (void)
+{
+  BusClientPolicy *policy;
+
+  policy = dbus_new0 (BusClientPolicy, 1);
+  if (policy == NULL)
+    return NULL;
+
+  policy->refcount = 1;
+
+  return policy;
+}
+
+void
+bus_client_policy_ref (BusClientPolicy *policy)
+{
+  _dbus_assert (policy->refcount > 0);
+
+  policy->refcount += 1;
+}
+
 static void
 rule_unref_foreach (void *data,
                     void *user_data)
@@ -123,7 +398,7 @@ rule_unref_foreach (void *data,
 }
 
 void
-bus_policy_unref (BusPolicy *policy)
+bus_client_policy_unref (BusClientPolicy *policy)
 {
   _dbus_assert (policy->refcount > 0);
 
@@ -142,7 +417,7 @@ bus_policy_unref (BusPolicy *policy)
 }
 
 static void
-remove_rules_by_type_up_to (BusPolicy         *policy,
+remove_rules_by_type_up_to (BusClientPolicy   *policy,
                             BusPolicyRuleType  type,
                             DBusList          *up_to)
 {
@@ -162,7 +437,7 @@ remove_rules_by_type_up_to (BusPolicy         *policy,
 }
 
 void
-bus_policy_optimize (BusPolicy *policy)
+bus_client_policy_optimize (BusClientPolicy *policy)
 {
   DBusList *link;
 
@@ -226,8 +501,8 @@ bus_policy_optimize (BusPolicy *policy)
 }
 
 dbus_bool_t
-bus_policy_append_rule (BusPolicy     *policy,
-                        BusPolicyRule *rule)
+bus_client_policy_append_rule (BusClientPolicy *policy,
+                               BusPolicyRule   *rule)
 {
   if (!_dbus_list_append (&policy->rules, rule))
     return FALSE;
@@ -238,10 +513,10 @@ bus_policy_append_rule (BusPolicy     *policy,
 }
 
 dbus_bool_t
-bus_policy_check_can_send (BusPolicy      *policy,
-                           BusRegistry    *registry,
-                           DBusConnection *receiver,
-                           DBusMessage    *message)
+bus_client_policy_check_can_send (BusClientPolicy *policy,
+                                  BusRegistry     *registry,
+                                  DBusConnection  *receiver,
+                                  DBusMessage     *message)
 {
   DBusList *link;
   dbus_bool_t allowed;
@@ -310,10 +585,10 @@ bus_policy_check_can_send (BusPolicy      *policy,
 }
 
 dbus_bool_t
-bus_policy_check_can_receive (BusPolicy      *policy,
-                              BusRegistry    *registry,
-                              DBusConnection *sender,
-                              DBusMessage    *message)
+bus_client_policy_check_can_receive (BusClientPolicy *policy,
+                                     BusRegistry     *registry,
+                                     DBusConnection  *sender,
+                                     DBusMessage     *message)
 {
   DBusList *link;
   dbus_bool_t allowed;
@@ -383,9 +658,9 @@ bus_policy_check_can_receive (BusPolicy      *policy,
 }
 
 dbus_bool_t
-bus_policy_check_can_own (BusPolicy        *policy,
-                          DBusConnection   *connection,
-                          const DBusString *service_name)
+bus_client_policy_check_can_own (BusClientPolicy  *policy,
+                                 DBusConnection   *connection,
+                                 const DBusString *service_name)
 {
   DBusList *link;
   dbus_bool_t allowed;
index 680ad58..194bd00 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- mode: C; c-file-style: "gnu" -*- */
-/* policy.h  Policies for what a connection can do
+/* policy.h  Bus security policy
  *
  * Copyright (C) 2003  Red Hat, Inc.
  *
@@ -87,22 +87,31 @@ BusPolicyRule* bus_policy_rule_new   (BusPolicyRuleType type,
 void           bus_policy_rule_ref   (BusPolicyRule    *rule);
 void           bus_policy_rule_unref (BusPolicyRule    *rule);
 
-BusPolicy*  bus_policy_new               (void);
-void        bus_policy_ref               (BusPolicy        *policy);
-void        bus_policy_unref             (BusPolicy        *policy);
-dbus_bool_t bus_policy_check_can_send    (BusPolicy        *policy,
-                                          BusRegistry      *registry,
-                                          DBusConnection   *receiver,
-                                          DBusMessage      *message);
-dbus_bool_t bus_policy_check_can_receive (BusPolicy        *policy,
-                                          BusRegistry      *registry,
-                                          DBusConnection   *sender,
-                                          DBusMessage      *message);
-dbus_bool_t bus_policy_check_can_own     (BusPolicy        *policy,
-                                          DBusConnection   *connection,
-                                          const DBusString *service_name);
-dbus_bool_t bus_policy_append_rule       (BusPolicy        *policy,
-                                          BusPolicyRule    *rule);
-void        bus_policy_optimize          (BusPolicy        *policy);
+BusPolicy*       bus_policy_new                  (void);
+void             bus_policy_ref                  (BusPolicy      *policy);
+void             bus_policy_unref                (BusPolicy      *policy);
+BusClientPolicy* bus_policy_create_client_policy (BusPolicy      *policy,
+                                                  DBusConnection *connection);
+dbus_bool_t      bus_policy_allow_user           (BusPolicy      *policy,
+                                                  unsigned long   uid);
+
+BusClientPolicy* bus_client_policy_new               (void);
+void             bus_client_policy_ref               (BusClientPolicy  *policy);
+void             bus_client_policy_unref             (BusClientPolicy  *policy);
+dbus_bool_t      bus_client_policy_check_can_send    (BusClientPolicy  *policy,
+                                                      BusRegistry      *registry,
+                                                      DBusConnection   *receiver,
+                                                      DBusMessage      *message);
+dbus_bool_t      bus_client_policy_check_can_receive (BusClientPolicy  *policy,
+                                                      BusRegistry      *registry,
+                                                      DBusConnection   *sender,
+                                                      DBusMessage      *message);
+dbus_bool_t      bus_client_policy_check_can_own     (BusClientPolicy  *policy,
+                                                      DBusConnection   *connection,
+                                                      const DBusString *service_name);
+dbus_bool_t      bus_client_policy_append_rule       (BusClientPolicy  *policy,
+                                                      BusPolicyRule    *rule);
+void             bus_client_policy_optimize          (BusClientPolicy  *policy);
+
 
 #endif /* BUS_POLICY_H */
index b0f4127..04859ef 100644 (file)
@@ -91,7 +91,7 @@ void _dbus_real_assert (dbus_bool_t  condition,
 #else
 void _dbus_real_assert_not_reached (const char *explanation,
                                     const char *file,
-                                    int         line);
+                                    int         line) _DBUS_GNUC_NORETURN;
 #define _dbus_assert_not_reached(explanation)                                   \
   _dbus_real_assert_not_reached (explanation, __FILE__, __LINE__)
 #endif /* !DBUS_DISABLE_ASSERT */
index 897c238..62bb413 100644 (file)
@@ -167,7 +167,7 @@ Elements:
 
     It does not make sense to deny a user or group inside a <policy>
     for a user or group; user/group denials can only be inside
-    context="default" or context="required" policies.
+    context="default" or context="mandatory" policies.
 
     A single <deny> rule may specify both send and send_to, OR both
     receive and receive_from. In this case, the denial applies only if
diff --git a/test/data/valid-config-files/entities.conf b/test/data/valid-config-files/entities.conf
new file mode 100644 (file)
index 0000000..3d3cea7
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- This config file contains XML entities -->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <user>mybususer</user>
+  <listen>unix:path=/foo/&lt;bar&gt;</listen>
+  <listen>tcp:port=1234</listen>
+  <includedir>basic.&#100;</includedir>
+  <servicedir>/usr/&amp;share/foo</servicedir>
+  <include ignore_missing="ye&#115;">nonexistent.conf&#110;</include>
+  <policy context="&#100;efault">
+    <allow user="*"/>
+  </policy>
+</busconfig>