mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-24 11:10:07 +01:00
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))__
This commit is contained in:
parent
4b773b4a54
commit
bc983ecf15
12 changed files with 469 additions and 302 deletions
11
ChangeLog
11
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.
|
||||
|
|
|
|||
237
bus/bus.c
237
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 */
|
||||
|
|
@ -213,27 +210,6 @@ new_connection_callback (DBusServer *server,
|
|||
/* on OOM, we won't have ref'd the connection so it will die. */
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -565,25 +541,10 @@ bus_context_new (const DBusString *config_file,
|
|||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
context->policy = bus_config_parser_steal_policy (parser);
|
||||
_dbus_assert (context->policy != NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
if (context->policy)
|
||||
{
|
||||
_dbus_hash_table_unref (context->rules_by_uid);
|
||||
context->rules_by_uid = NULL;
|
||||
bus_policy_unref (context->policy);
|
||||
context->policy = NULL;
|
||||
}
|
||||
|
||||
if (context->rules_by_gid)
|
||||
{
|
||||
_dbus_hash_table_unref (context->rules_by_gid);
|
||||
context->rules_by_gid = 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;
|
||||
return bus_policy_allow_user (context->policy, uid);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
add_list_to_policy (DBusList **list,
|
||||
BusPolicy *policy)
|
||||
BusClientPolicy*
|
||||
bus_context_create_client_policy (BusContext *context,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
BusPolicy*
|
||||
bus_context_create_connection_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
|
||||
|
|
|
|||
52
bus/bus.h
52
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 */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
313
bus/policy.c
313
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,12 +126,262 @@ 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
|
||||
bus_policy_ref (BusPolicy *policy)
|
||||
{
|
||||
_dbus_assert (policy->refcount > 0);
|
||||
|
||||
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_policy_ref (BusPolicy *policy)
|
||||
bus_client_policy_ref (BusClientPolicy *policy)
|
||||
{
|
||||
_dbus_assert (policy->refcount > 0);
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
45
bus/policy.h
45
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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
14
test/data/valid-config-files/entities.conf
Normal file
14
test/data/valid-config-files/entities.conf
Normal file
|
|
@ -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>
|
||||
Loading…
Add table
Reference in a new issue