summaryrefslogtreecommitdiffstats
path: root/bus/config-parser.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2004-07-30 05:59:34 +0000
committerHavoc Pennington <hp@redhat.com>2004-07-30 05:59:34 +0000
commit1e9b185b0c274ef0d684b1e43418388225321e72 (patch)
tree66bb08beb9ea1b4250953294134e2c995f8adf34 /bus/config-parser.c
parent4076d31c71bee332c4a697597a93345b45850b33 (diff)
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
Diffstat (limited to 'bus/config-parser.c')
-rw-r--r--bus/config-parser.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/bus/config-parser.c b/bus/config-parser.c
index faa5b55b..29fade16 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -24,6 +24,7 @@
#include "test.h"
#include "utils.h"
#include "policy.h"
+#include "selinux.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-internals.h>
#include <string.h>
@@ -44,7 +45,9 @@ typedef enum
ELEMENT_PIDFILE,
ELEMENT_SERVICEDIR,
ELEMENT_INCLUDEDIR,
- ELEMENT_TYPE
+ ELEMENT_TYPE,
+ ELEMENT_SELINUX,
+ ELEMENT_ASSOCIATE
} ElementType;
typedef enum
@@ -117,6 +120,8 @@ struct BusConfigParser
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 is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */
@@ -157,6 +162,10 @@ element_type_to_name (ElementType type)
return "includedir";
case ELEMENT_TYPE:
return "type";
+ case ELEMENT_SELINUX:
+ return "selinux";
+ case ELEMENT_ASSOCIATE:
+ return "associate";
}
_dbus_assert_not_reached ("bad element type");
@@ -235,6 +244,7 @@ merge_included (BusConfigParser *parser,
DBusError *error)
{
DBusList *link;
+ DBusHashTable *table;
if (!bus_policy_merge (parser->policy,
included->policy))
@@ -242,6 +252,17 @@ merge_included (BusConfigParser *parser,
BUS_SET_OOM (error);
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)
{
@@ -317,12 +338,17 @@ bus_config_parser_new (const DBusString *basedir,
}
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)
bus_policy_unref (parser->policy);
_dbus_string_free (&parser->basedir);
+
+ if (parser->service_sid_table == NULL)
+ _dbus_hash_table_unref (parser->service_sid_table);
+
dbus_free (parser);
return NULL;
}
@@ -428,6 +454,9 @@ bus_config_parser_unref (BusConfigParser *parser)
if (parser->policy)
bus_policy_unref (parser->policy);
+ if (parser->service_sid_table)
+ _dbus_hash_table_unref (parser->service_sid_table);
+
dbus_free (parser);
}
}
@@ -658,7 +687,7 @@ start_busconfig_child (BusConfigParser *parser,
BUS_SET_OOM (error);
return FALSE;
}
-
+
return TRUE;
}
else if (strcmp (element_name, "includedir") == 0)
@@ -843,6 +872,22 @@ start_busconfig_child (BusConfigParser *parser,
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;
+ }
else
{
dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -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
bus_config_parser_start_element (BusConfigParser *parser,
const char *element_name,
@@ -1440,6 +1537,12 @@ bus_config_parser_start_element (BusConfigParser *parser,
attribute_names, attribute_values,
error);
}
+ else if (t == ELEMENT_SELINUX)
+ {
+ return start_selinux_child (parser, element_name,
+ attribute_names, attribute_values,
+ error);
+ }
else
{
dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -1635,6 +1738,8 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_ALLOW:
case ELEMENT_DENY:
case ELEMENT_FORK:
+ case ELEMENT_SELINUX:
+ case ELEMENT_ASSOCIATE:
break;
}
@@ -1867,6 +1972,8 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_ALLOW:
case ELEMENT_DENY:
case ELEMENT_FORK:
+ case ELEMENT_SELINUX:
+ case ELEMENT_ASSOCIATE:
if (all_whitespace (content))
return TRUE;
else
@@ -2160,6 +2267,20 @@ bus_config_parser_get_limits (BusConfigParser *parser,
*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
#include <stdio.h>
@@ -2494,6 +2615,8 @@ config_parsers_equal (const BusConfigParser *a,
/* FIXME: compare policy */
+ /* FIXME: compare service selinux ID table */
+
if (! limits_equal (&a->limits, &b->limits))
return FALSE;