Commit 1e9b185b authored by Havoc Pennington's avatar Havoc Pennington

2004-07-24 Havoc Pennington <hp@redhat.com>

	SELinux support from Matthew Rickard <mjricka@epoch.ncsc.mil>

	* bus/selinux.c, bus/selinux.h: new file encapsulating selinux
	functionality

	* configure.in: add --enable-selinux

	* bus/policy.c (bus_policy_merge): add FIXME to a comment

	* bus/main.c (main): initialize and shut down selinux

	* bus/connection.c: store SELinux ID on each connection, to avoid
	repeated getting of the string context and converting it into
	an ID

	* bus/bus.c (bus_context_get_policy): new accessor, though it
	isn't used
	(bus_context_check_security_policy): check whether the security
	context of sender connection can send to the security context of
	recipient connection

	* bus/config-parser.c: add parsing for <selinux> and <associate>

	* dbus/dbus-transport.c (_dbus_transport_get_unix_fd): to
	implement dbus_connection_get_unix_fd()

	* dbus/dbus-connection.c (dbus_connection_get_unix_fd): new
	function, used by the selinux stuff
parent 4076d31c
2004-07-24 Havoc Pennington <hp@redhat.com>
SELinux support from Matthew Rickard <mjricka@epoch.ncsc.mil>
* bus/selinux.c, bus/selinux.h: new file encapsulating selinux
functionality
* configure.in: add --enable-selinux
* bus/policy.c (bus_policy_merge): add FIXME to a comment
* bus/main.c (main): initialize and shut down selinux
* bus/connection.c: store SELinux ID on each connection, to avoid
repeated getting of the string context and converting it into
an ID
* bus/bus.c (bus_context_get_policy): new accessor, though it
isn't used
(bus_context_check_security_policy): check whether the security
context of sender connection can send to the security context of
recipient connection
* bus/config-parser.c: add parsing for <selinux> and <associate>
* dbus/dbus-transport.c (_dbus_transport_get_unix_fd): to
implement dbus_connection_get_unix_fd()
* dbus/dbus-connection.c (dbus_connection_get_unix_fd): new
function, used by the selinux stuff
2004-07-29 Olivier Andrieu <oliv__a@users.sourceforge.net> 2004-07-29 Olivier Andrieu <oliv__a@users.sourceforge.net>
* bus/config-loader-libxml.c: complete the implementation of * bus/config-loader-libxml.c: complete the implementation of
......
...@@ -10,7 +10,7 @@ EFENCE= ...@@ -10,7 +10,7 @@ EFENCE=
CONFIG_IN_FILES= \ CONFIG_IN_FILES= \
session.conf.in \ session.conf.in \
system.conf.in system.conf.in
config_DATA= \ config_DATA= \
session.conf \ session.conf \
...@@ -44,6 +44,8 @@ BUS_SOURCES= \ ...@@ -44,6 +44,8 @@ BUS_SOURCES= \
expirelist.h \ expirelist.h \
policy.c \ policy.c \
policy.h \ policy.h \
selinux.h \
selinux.c \
services.c \ services.c \
services.h \ services.h \
signals.c \ signals.c \
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "policy.h" #include "policy.h"
#include "config-parser.h" #include "config-parser.h"
#include "signals.h" #include "signals.h"
#include "selinux.h"
#include <dbus/dbus-list.h> #include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h> #include <dbus/dbus-hash.h>
#include <dbus/dbus-internals.h> #include <dbus/dbus-internals.h>
...@@ -403,6 +404,7 @@ process_config_every_time (BusContext *context, ...@@ -403,6 +404,7 @@ process_config_every_time (BusContext *context,
{ {
DBusString full_address; DBusString full_address;
DBusList *link; DBusList *link;
DBusHashTable *service_sid_table;
dbus_bool_t retval; dbus_bool_t retval;
...@@ -480,6 +482,11 @@ process_config_every_time (BusContext *context, ...@@ -480,6 +482,11 @@ process_config_every_time (BusContext *context,
goto failed; goto failed;
} }
service_sid_table = bus_config_parser_steal_service_sid_table (parser);
bus_registry_set_service_sid_table (context->registry,
service_sid_table);
_dbus_hash_table_unref (service_sid_table);
_DBUS_ASSERT_ERROR_IS_CLEAR (error); _DBUS_ASSERT_ERROR_IS_CLEAR (error);
retval = TRUE; retval = TRUE;
...@@ -569,6 +576,13 @@ bus_context_new (const DBusString *config_file, ...@@ -569,6 +576,13 @@ bus_context_new (const DBusString *config_file,
goto failed; goto failed;
} }
context->registry = bus_registry_new (context);
if (context->registry == NULL)
{
BUS_SET_OOM (error);
goto failed;
}
if (!load_config (context, FALSE, error)) if (!load_config (context, FALSE, error))
{ {
_DBUS_ASSERT_ERROR_IS_SET (error); _DBUS_ASSERT_ERROR_IS_SET (error);
...@@ -637,13 +651,6 @@ bus_context_new (const DBusString *config_file, ...@@ -637,13 +651,6 @@ bus_context_new (const DBusString *config_file,
goto failed; goto failed;
} }
context->registry = bus_registry_new (context);
if (context->registry == NULL)
{
BUS_SET_OOM (error);
goto failed;
}
context->matchmaker = bus_matchmaker_new (); context->matchmaker = bus_matchmaker_new ();
if (context->matchmaker == NULL) if (context->matchmaker == NULL)
{ {
...@@ -958,6 +965,12 @@ bus_context_allow_user (BusContext *context, ...@@ -958,6 +965,12 @@ bus_context_allow_user (BusContext *context,
uid); uid);
} }
BusPolicy *
bus_context_get_policy (BusContext *context)
{
return context->policy;
}
BusClientPolicy* BusClientPolicy*
bus_context_create_client_policy (BusContext *context, bus_context_create_client_policy (BusContext *context,
DBusConnection *connection, DBusConnection *connection,
...@@ -1088,6 +1101,28 @@ bus_context_check_security_policy (BusContext *context, ...@@ -1088,6 +1101,28 @@ bus_context_check_security_policy (BusContext *context,
if (sender != NULL) if (sender != NULL)
{ {
/* First verify the SELinux access controls. If allowed then
* go on with the standard checks.
*/
if (!bus_selinux_allows_send (sender, proposed_recipient))
{
const char *dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"An SELinux policy prevents this sender "
"from sending this message to this recipient "
"(rejected message had interface \"%s\" "
"member \"%s\" error name \"%s\" destination \"%s\")",
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) : "(unset)",
dbus_message_get_member (message) ?
dbus_message_get_member (message) : "(unset)",
dbus_message_get_error_name (message) ?
dbus_message_get_error_name (message) : "(unset)",
dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
_dbus_verbose ("SELinux security check denying send to service\n");
return FALSE;
}
if (bus_connection_is_active (sender)) if (bus_connection_is_active (sender))
{ {
sender_policy = bus_connection_get_policy (sender); sender_policy = bus_connection_get_policy (sender);
......
...@@ -38,6 +38,7 @@ typedef struct BusPolicy BusPolicy; ...@@ -38,6 +38,7 @@ typedef struct BusPolicy BusPolicy;
typedef struct BusClientPolicy BusClientPolicy; typedef struct BusClientPolicy BusClientPolicy;
typedef struct BusPolicyRule BusPolicyRule; typedef struct BusPolicyRule BusPolicyRule;
typedef struct BusRegistry BusRegistry; typedef struct BusRegistry BusRegistry;
typedef struct BusSELinuxID BusSELinuxID;
typedef struct BusService BusService; typedef struct BusService BusService;
typedef struct BusTransaction BusTransaction; typedef struct BusTransaction BusTransaction;
typedef struct BusMatchmaker BusMatchmaker; typedef struct BusMatchmaker BusMatchmaker;
...@@ -78,8 +79,11 @@ BusActivation* bus_context_get_activation (BusContext ...@@ -78,8 +79,11 @@ BusActivation* bus_context_get_activation (BusContext
BusMatchmaker* bus_context_get_matchmaker (BusContext *context); BusMatchmaker* bus_context_get_matchmaker (BusContext *context);
DBusLoop* bus_context_get_loop (BusContext *context); DBusLoop* bus_context_get_loop (BusContext *context);
DBusUserDatabase* bus_context_get_user_database (BusContext *context); DBusUserDatabase* bus_context_get_user_database (BusContext *context);
dbus_bool_t bus_context_allow_user (BusContext *context, dbus_bool_t bus_context_allow_user (BusContext *context,
unsigned long uid); unsigned long uid);
BusPolicy* bus_context_get_policy (BusContext *context);
BusClientPolicy* bus_context_create_client_policy (BusContext *context, BusClientPolicy* bus_context_create_client_policy (BusContext *context,
DBusConnection *connection, DBusConnection *connection,
DBusError *error); DBusError *error);
...@@ -101,5 +105,4 @@ dbus_bool_t bus_context_check_security_policy (BusContext ...@@ -101,5 +105,4 @@ dbus_bool_t bus_context_check_security_policy (BusContext
DBusMessage *message, DBusMessage *message,
DBusError *error); DBusError *error);
#endif /* BUS_BUS_H */ #endif /* BUS_BUS_H */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "test.h" #include "test.h"
#include "utils.h" #include "utils.h"
#include "policy.h" #include "policy.h"
#include "selinux.h"
#include <dbus/dbus-list.h> #include <dbus/dbus-list.h>
#include <dbus/dbus-internals.h> #include <dbus/dbus-internals.h>
#include <string.h> #include <string.h>
...@@ -44,7 +45,9 @@ typedef enum ...@@ -44,7 +45,9 @@ typedef enum
ELEMENT_PIDFILE, ELEMENT_PIDFILE,
ELEMENT_SERVICEDIR, ELEMENT_SERVICEDIR,
ELEMENT_INCLUDEDIR, ELEMENT_INCLUDEDIR,
ELEMENT_TYPE ELEMENT_TYPE,
ELEMENT_SELINUX,
ELEMENT_ASSOCIATE
} ElementType; } ElementType;
typedef enum typedef enum
...@@ -117,6 +120,8 @@ struct BusConfigParser ...@@ -117,6 +120,8 @@ struct BusConfigParser
DBusList *included_files; /**< Included files stack */ DBusList *included_files; /**< Included files stack */
DBusHashTable *service_sid_table; /**< Map service names to SELinux contexts */
unsigned int fork : 1; /**< TRUE to fork into daemon mode */ unsigned int fork : 1; /**< TRUE to fork into daemon mode */
unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */ unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */
...@@ -157,6 +162,10 @@ element_type_to_name (ElementType type) ...@@ -157,6 +162,10 @@ element_type_to_name (ElementType type)
return "includedir"; return "includedir";
case ELEMENT_TYPE: case ELEMENT_TYPE:
return "type"; return "type";
case ELEMENT_SELINUX:
return "selinux";
case ELEMENT_ASSOCIATE:
return "associate";
} }
_dbus_assert_not_reached ("bad element type"); _dbus_assert_not_reached ("bad element type");
...@@ -235,6 +244,7 @@ merge_included (BusConfigParser *parser, ...@@ -235,6 +244,7 @@ merge_included (BusConfigParser *parser,
DBusError *error) DBusError *error)
{ {
DBusList *link; DBusList *link;
DBusHashTable *table;
if (!bus_policy_merge (parser->policy, if (!bus_policy_merge (parser->policy,
included->policy)) included->policy))
...@@ -242,6 +252,17 @@ merge_included (BusConfigParser *parser, ...@@ -242,6 +252,17 @@ merge_included (BusConfigParser *parser,
BUS_SET_OOM (error); BUS_SET_OOM (error);
return FALSE; return FALSE;
} }
table = bus_selinux_id_table_union (parser->service_sid_table,
included->service_sid_table);
if (table == NULL)
{
BUS_SET_OOM (error);
return FALSE;
}
_dbus_hash_table_unref (parser->service_sid_table);
parser->service_sid_table = table;
if (included->user != NULL) if (included->user != NULL)
{ {
...@@ -317,12 +338,17 @@ bus_config_parser_new (const DBusString *basedir, ...@@ -317,12 +338,17 @@ bus_config_parser_new (const DBusString *basedir,
} }
if (((parser->policy = bus_policy_new ()) == NULL) || if (((parser->policy = bus_policy_new ()) == NULL) ||
!_dbus_string_copy (basedir, 0, &parser->basedir, 0)) !_dbus_string_copy (basedir, 0, &parser->basedir, 0) ||
((parser->service_sid_table = bus_selinux_id_table_new ()) == NULL))
{ {
if (parser->policy) if (parser->policy)
bus_policy_unref (parser->policy); bus_policy_unref (parser->policy);
_dbus_string_free (&parser->basedir); _dbus_string_free (&parser->basedir);
if (parser->service_sid_table == NULL)
_dbus_hash_table_unref (parser->service_sid_table);
dbus_free (parser); dbus_free (parser);
return NULL; return NULL;
} }
...@@ -428,6 +454,9 @@ bus_config_parser_unref (BusConfigParser *parser) ...@@ -428,6 +454,9 @@ bus_config_parser_unref (BusConfigParser *parser)
if (parser->policy) if (parser->policy)
bus_policy_unref (parser->policy); bus_policy_unref (parser->policy);
if (parser->service_sid_table)
_dbus_hash_table_unref (parser->service_sid_table);
dbus_free (parser); dbus_free (parser);
} }
} }
...@@ -658,7 +687,7 @@ start_busconfig_child (BusConfigParser *parser, ...@@ -658,7 +687,7 @@ start_busconfig_child (BusConfigParser *parser,
BUS_SET_OOM (error); BUS_SET_OOM (error);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
else if (strcmp (element_name, "includedir") == 0) else if (strcmp (element_name, "includedir") == 0)
...@@ -841,6 +870,22 @@ start_busconfig_child (BusConfigParser *parser, ...@@ -841,6 +870,22 @@ start_busconfig_child (BusConfigParser *parser,
return FALSE; return FALSE;
} }
return TRUE;
}
else if (strcmp (element_name, "selinux") == 0)
{
Element *e;
const char *name;
if (!check_no_attributes (parser, "selinux", attribute_names, attribute_values, error))
return FALSE;
if (push_element (parser, ELEMENT_SELINUX) == NULL)
{
BUS_SET_OOM (error);
return FALSE;
}
return TRUE; return TRUE;
} }
else else
...@@ -1390,6 +1435,58 @@ start_policy_child (BusConfigParser *parser, ...@@ -1390,6 +1435,58 @@ start_policy_child (BusConfigParser *parser,
} }
} }
static dbus_bool_t
start_selinux_child (BusConfigParser *parser,
const char *element_name,
const char **attribute_names,
const char **attribute_values,
DBusError *error)
{
if (strcmp (element_name, "associate") == 0)
{
const char *own;
const char *context;
if (!locate_attributes (parser, "associate",
attribute_names,
attribute_values,
error,
"own", &own,
"context", &context,
NULL))
return FALSE;
if (push_element (parser, ELEMENT_ASSOCIATE) == NULL)
{
BUS_SET_OOM (error);
return FALSE;
}
if (own == NULL || context == NULL)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Element <associate> must have attributes own=\"<servicename>\" and context=\"<selinux context>\"");
return FALSE;
}
if (!bus_selinux_id_table_insert (parser->service_sid_table,
own, context))
{
BUS_SET_OOM (error);
return FALSE;
}
return TRUE;
}
else
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Element <%s> not allowed inside <%s> in configuration file",
element_name, "selinux");
return FALSE;
}
}
dbus_bool_t dbus_bool_t
bus_config_parser_start_element (BusConfigParser *parser, bus_config_parser_start_element (BusConfigParser *parser,
const char *element_name, const char *element_name,
...@@ -1440,6 +1537,12 @@ bus_config_parser_start_element (BusConfigParser *parser, ...@@ -1440,6 +1537,12 @@ bus_config_parser_start_element (BusConfigParser *parser,
attribute_names, attribute_values, attribute_names, attribute_values,
error); error);
} }
else if (t == ELEMENT_SELINUX)
{
return start_selinux_child (parser, element_name,
attribute_names, attribute_values,
error);
}
else else
{ {
dbus_set_error (error, DBUS_ERROR_FAILED, dbus_set_error (error, DBUS_ERROR_FAILED,
...@@ -1635,6 +1738,8 @@ bus_config_parser_end_element (BusConfigParser *parser, ...@@ -1635,6 +1738,8 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_ALLOW: case ELEMENT_ALLOW:
case ELEMENT_DENY: case ELEMENT_DENY:
case ELEMENT_FORK: case ELEMENT_FORK:
case ELEMENT_SELINUX:
case ELEMENT_ASSOCIATE:
break; break;
} }
...@@ -1867,6 +1972,8 @@ bus_config_parser_content (BusConfigParser *parser, ...@@ -1867,6 +1972,8 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_ALLOW: case ELEMENT_ALLOW:
case ELEMENT_DENY: case ELEMENT_DENY:
case ELEMENT_FORK: case ELEMENT_FORK:
case ELEMENT_SELINUX:
case ELEMENT_ASSOCIATE:
if (all_whitespace (content)) if (all_whitespace (content))
return TRUE; return TRUE;
else else
...@@ -2160,6 +2267,20 @@ bus_config_parser_get_limits (BusConfigParser *parser, ...@@ -2160,6 +2267,20 @@ bus_config_parser_get_limits (BusConfigParser *parser,
*limits = parser->limits; *limits = parser->limits;
} }
DBusHashTable*
bus_config_parser_steal_service_sid_table (BusConfigParser *parser)
{
DBusHashTable *table;
_dbus_assert (parser->service_sid_table != NULL); /* can only steal once */
table = parser->service_sid_table;
parser->service_sid_table = NULL;
return table;
}
#ifdef DBUS_BUILD_TESTS #ifdef DBUS_BUILD_TESTS
#include <stdio.h> #include <stdio.h>
...@@ -2494,6 +2615,8 @@ config_parsers_equal (const BusConfigParser *a, ...@@ -2494,6 +2615,8 @@ config_parsers_equal (const BusConfigParser *a,
/* FIXME: compare policy */ /* FIXME: compare policy */
/* FIXME: compare service selinux ID table */
if (! limits_equal (&a->limits, &b->limits)) if (! limits_equal (&a->limits, &b->limits))
return FALSE; return FALSE;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-string.h> #include <dbus/dbus-string.h>
#include <dbus/dbus-list.h> #include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include "bus.h" #include "bus.h"
/* Whatever XML library we're using just pushes data into this API */ /* Whatever XML library we're using just pushes data into this API */
...@@ -70,6 +71,8 @@ BusPolicy* bus_config_parser_steal_policy (BusConfigParser *parser); ...@@ -70,6 +71,8 @@ BusPolicy* bus_config_parser_steal_policy (BusConfigParser *parser);
void bus_config_parser_get_limits (BusConfigParser *parser, void bus_config_parser_get_limits (BusConfigParser *parser,
BusLimits *limits); BusLimits *limits);
DBusHashTable* bus_config_parser_steal_service_sid_table (BusConfigParser *parser);
/* Loader functions (backended off one of the XML parsers). Returns a /* Loader functions (backended off one of the XML parsers). Returns a
* finished ConfigParser. * finished ConfigParser.
*/ */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "utils.h" #include "utils.h"
#include "signals.h" #include "signals.h"
#include "expirelist.h" #include "expirelist.h"
#include "selinux.h"
#include <dbus/dbus-list.h> #include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h> #include <dbus/dbus-hash.h>
#include <dbus/dbus-timeout.h> #include <dbus/dbus-timeout.h>
...@@ -75,6 +76,8 @@ typedef struct ...@@ -75,6 +76,8 @@ typedef struct
DBusPreallocatedSend *oom_preallocated; DBusPreallocatedSend *oom_preallocated;
BusClientPolicy *policy; BusClientPolicy *policy;
BusSELinuxID *selinux_id;
long connection_tv_sec; /**< Time when we connected (seconds component) */ long connection_tv_sec; /**< Time when we connected (seconds component) */
long connection_tv_usec; /**< Time when we connected (microsec component) */ long connection_tv_usec; /**< Time when we connected (microsec component) */
int stamp; /**< connections->stamp last time we were traversed */ int stamp; /**< connections->stamp last time we were traversed */
...@@ -401,6 +404,9 @@ free_connection_data (void *data) ...@@ -401,6 +404,9 @@ free_connection_data (void *data)
if (d->policy) if (d->policy)
bus_client_policy_unref (d->policy); bus_client_policy_unref (d->policy);
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
dbus_free (d->name); dbus_free (d->name);
...@@ -539,6 +545,7 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -539,6 +545,7 @@ bus_connections_setup_connection (BusConnections *connections,
{ {
BusConnectionData *d; BusConnectionData *d;
dbus_bool_t retval; dbus_bool_t retval;
DBusError error;
d = dbus_new0 (BusConnectionData, 1); d = dbus_new0 (BusConnectionData, 1);
...@@ -562,6 +569,20 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -562,6 +569,20 @@ bus_connections_setup_connection (BusConnections *connections,
} }
retval = FALSE; retval = FALSE;
dbus_error_init (&error);
d->selinux_id = bus_selinux_init_connection_id (connection,
&error);
if (dbus_error_is_set (&error))
{
/* This is a bit bogus because we pretend all errors
* are OOM; this is done because we know that in bus.c
* an OOM error disconnects the connection, which is
* the same thing we want on any other error.
*/
dbus_error_free (&error);
goto out;
}
if (!dbus_connection_set_watch_functions (connection, if (!dbus_connection_set_watch_functions (connection,
add_connection_watch, add_connection_watch,
...@@ -639,7 +660,11 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -639,7 +660,11 @@ bus_connections_setup_connection (BusConnections *connections,
out: out:
if (!retval) if (!retval)
{ {
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
d->selinux_id = NULL;
if (!dbus_connection_set_watch_functions (connection, if (!dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL, NULL, NULL, NULL,
connection, connection,
...@@ -1008,6 +1033,18 @@ bus_connection_get_matchmaker (DBusConnection *connection) ...@@ -1008,6 +1033,18 @@ bus_connection_get_matchmaker (DBusConnection *connection)
return bus_context_get_matchmaker (d->connections->context); return bus_context_get_matchmaker (d->connections->context);
} }
BusSELinuxID*
bus_connection_get_selinux_id (DBusConnection *connection)
{
BusConnectionData *d;
d = BUS_CONNECTION_DATA (connection);
_dbus_assert (d != NULL);
return d->selinux_id;
}
/** /**
* Checks whether the connection is registered with the message bus. * Checks whether the connection is registered with the message bus.
* *
......
/* -*- mode: C; c-file-style: "gnu" -*- */ /* -*- mode: C; c-file-style: "gnu" -*- */
/* connection.h Client connections /* connection.h Client connections
* *
* Copyright (C) 2003 Red Hat, Inc. * Copyright (C) 2003, 2004 Red Hat, Inc.
* *
* Licensed under the Academic Free License version 2.0 * Licensed under the Academic Free License version 2.0
* *
...@@ -50,6 +50,7 @@ BusConnections* bus_connection_get_connections (DBusConnection ...@@ -50,6 +50,7 @@ BusConnections* bus_connection_get_connections (DBusConnection
BusRegistry* bus_connection_get_registry (DBusConnection *connection); BusRegistry* bus_connection_get_registry (DBusConnection *connection);
BusActivation* bus_connection_get_activation (DBusConnection *connection); BusActivation* bus_connection_get_activation (DBusConnection *connection);
BusMatchmaker* bus_connection_get_matchmaker (DBusConnection *connection); BusMatchmaker* bus_connection_get_matchmaker (DBusConnection *connection);
BusSELinuxID* bus_connection_get_selinux_id (DBusConnection *connection);
dbus_bool_t bus_connections_check_limits (BusConnections *connections, dbus_bool_t bus_connections_check_limits (BusConnections *connections,
DBusConnection *requesting_completion, DBusConnection *requesting_completion,
DBusError *error); DBusError *error);
......
...@@ -463,6 +463,110 @@ received" are evaluated separately. ...@@ -463,6 +463,110 @@ received" are evaluated separately.
Be careful with send_interface/receive_interface, because the Be careful with send_interface/receive_interface, because the
interface field in messages is optional. interface field in messages is optional.
.TP
.I "<selinux>"
.PP
The <selinux> element contains settings related to Security Enhanced Linux.
More details below.
.TP
.I "<associate>"
.PP
An <associate> element appears below an <selinux> element and
creates a mapping. Right now only one kind of association is possible:
.nf
<associate own="org.freedesktop.Foobar" context="foo_t"/>
.fi
.PP
This means that if a connection asks to own the service
"org.freedesktop.Foobar" then the source context will be the context
of the connection and the target context will be "foo_t" - see the
short discussion of SELinux below.
.PP
Note, the context here is the target context when acquiring a service,
NOT the context of the connection owning the service.
.PP
There's currently no way to set a default for owning any service, if
we add this syntax it will look like:
.nf
<associate own="*" context="foo_t"/>
.fi
If you find a reason this is useful, let the developers know.
Right now the default will be the security context of the bus itself.