summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-12 18:32:11 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-12 18:32:11 +0000
commitbc983ecf15455f49e7a92d038c93e181ae2cb438 (patch)
treed53948dab970d81f07e195513804945b87a758e8
parent4b773b4a5448ac9bea2cc57486571588fdc14480 (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--ChangeLog11
-rw-r--r--bus/bus.c237
-rw-r--r--bus/bus.h52
-rw-r--r--bus/config-parser.c71
-rw-r--r--bus/config-parser.h2
-rw-r--r--bus/connection.c10
-rw-r--r--bus/connection.h12
-rw-r--r--bus/policy.c313
-rw-r--r--bus/policy.h45
-rw-r--r--dbus/dbus-internals.h2
-rw-r--r--doc/config-file.txt2
-rw-r--r--test/data/valid-config-files/entities.conf14
12 files changed, 469 insertions, 302 deletions
diff --git a/ChangeLog b/ChangeLog
index 3132df68..7808483b 100644
--- 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.
diff --git a/bus/bus.c b/bus/bus.c
index 3b2ffc0c..31b43f22 100644
--- 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
diff --git a/bus/bus.h b/bus/bus.h
index 60290c04..754fab04 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -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/&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>