diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-04-12 18:32:11 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-04-12 18:32:11 +0000 | 
| commit | bc983ecf15455f49e7a92d038c93e181ae2cb438 (patch) | |
| tree | d53948dab970d81f07e195513804945b87a758e8 | |
| parent | 4b773b4a5448ac9bea2cc57486571588fdc14480 (diff) | |
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))__
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | bus/bus.c | 237 | ||||
| -rw-r--r-- | bus/bus.h | 52 | ||||
| -rw-r--r-- | bus/config-parser.c | 71 | ||||
| -rw-r--r-- | bus/config-parser.h | 2 | ||||
| -rw-r--r-- | bus/connection.c | 10 | ||||
| -rw-r--r-- | bus/connection.h | 12 | ||||
| -rw-r--r-- | bus/policy.c | 313 | ||||
| -rw-r--r-- | bus/policy.h | 45 | ||||
| -rw-r--r-- | dbus/dbus-internals.h | 2 | ||||
| -rw-r--r-- | doc/config-file.txt | 2 | ||||
| -rw-r--r-- | test/data/valid-config-files/entities.conf | 14 | 
12 files changed, 469 insertions, 302 deletions
@@ -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. @@ -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 @@ -30,31 +30,33 @@  #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 */ diff --git a/bus/config-parser.c b/bus/config-parser.c index 1052dc2d..780d1757 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -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> diff --git a/bus/config-parser.h b/bus/config-parser.h index 93d41003..15644ee6 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -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. diff --git a/bus/connection.c b/bus/connection.c index 2cfbeb27..21c8f1a3 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -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 diff --git a/bus/connection.h b/bus/connection.h index 6108bdfd..4962211e 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -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 */ diff --git a/bus/policy.c b/bus/policy.c index b5187715..cff2509c 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -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; diff --git a/bus/policy.h b/bus/policy.h index 680ad581..194bd001 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -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 */ diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index b0f41278..04859ef7 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -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 */ diff --git a/doc/config-file.txt b/doc/config-file.txt index 897c2380..62bb4137 100644 --- a/doc/config-file.txt +++ b/doc/config-file.txt @@ -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 index 00000000..3d3cea79 --- /dev/null +++ b/test/data/valid-config-files/entities.conf @@ -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/<bar></listen> +  <listen>tcp:port=1234</listen> +  <includedir>basic.d</includedir> +  <servicedir>/usr/&share/foo</servicedir> +  <include ignore_missing="yes">nonexistent.confn</include> +  <policy context="default"> +    <allow user="*"/> +  </policy> +</busconfig>  | 
