Commit cfa261b4 authored by Havoc Pennington's avatar Havoc Pennington

2003-04-01 Havoc Pennington <hp@redhat.com>

	* bus/config-parser.c, bus/bus.c: implement <servicedir> and
	<includedir> (at least mostly)

	* dbus/dbus-sysdeps.c (_dbus_change_identity): set the group ID
	first, then the user ID
parent 44ed9332
2003-04-01 Havoc Pennington <hp@redhat.com>
* bus/config-parser.c, bus/bus.c: implement <servicedir> and
<includedir> (at least mostly)
* dbus/dbus-sysdeps.c (_dbus_change_identity): set the group ID
first, then the user ID
2003-04-01 Havoc Pennington <hp@pobox.com> 2003-04-01 Havoc Pennington <hp@pobox.com>
* dbus/dbus-server.c (dbus_server_set_auth_mechanisms): new * dbus/dbus-server.c (dbus_server_set_auth_mechanisms): new
......
...@@ -316,12 +316,12 @@ load_directory (BusActivation *activation, ...@@ -316,12 +316,12 @@ load_directory (BusActivation *activation,
BusActivation* BusActivation*
bus_activation_new (BusContext *context, bus_activation_new (BusContext *context,
const DBusString *address, const DBusString *address,
const char **directories, DBusList **directories,
DBusError *error) DBusError *error)
{ {
int i;
BusActivation *activation; BusActivation *activation;
DBusList *link;
_DBUS_ASSERT_ERROR_IS_CLEAR (error); _DBUS_ASSERT_ERROR_IS_CLEAR (error);
activation = dbus_new0 (BusActivation, 1); activation = dbus_new0 (BusActivation, 1);
...@@ -358,12 +358,12 @@ bus_activation_new (BusContext *context, ...@@ -358,12 +358,12 @@ bus_activation_new (BusContext *context,
} }
/* Load service files */ /* Load service files */
i = 0; link = _dbus_list_get_first_link (directories);
while (directories[i] != NULL) while (link != NULL)
{ {
if (!load_directory (activation, directories[i], error)) if (!load_directory (activation, link->data, error))
goto failed; goto failed;
++i; link = _dbus_list_get_next_link (directories, link);
} }
return activation; return activation;
......
...@@ -25,11 +25,12 @@ ...@@ -25,11 +25,12 @@
#define BUS_ACTIVATION_H #define BUS_ACTIVATION_H
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-list.h>
#include "bus.h" #include "bus.h"
BusActivation* bus_activation_new (BusContext *context, BusActivation* bus_activation_new (BusContext *context,
const DBusString *address, const DBusString *address,
const char **paths, DBusList **directories,
DBusError *error); DBusError *error);
void bus_activation_ref (BusActivation *activation); void bus_activation_ref (BusActivation *activation);
void bus_activation_unref (BusActivation *activation); void bus_activation_unref (BusActivation *activation);
......
...@@ -187,7 +187,6 @@ bus_context_new (const DBusString *config_file, ...@@ -187,7 +187,6 @@ bus_context_new (const DBusString *config_file,
DBusList **addresses; DBusList **addresses;
BusConfigParser *parser; BusConfigParser *parser;
DBusString full_address; DBusString full_address;
const char *service_dirs[] = { NULL, NULL };
const char *user; const char *user;
char **auth_mechanisms; char **auth_mechanisms;
DBusList **auth_mechanisms_list; DBusList **auth_mechanisms_list;
...@@ -336,7 +335,8 @@ bus_context_new (const DBusString *config_file, ...@@ -336,7 +335,8 @@ bus_context_new (const DBusString *config_file,
/* Create activation subsystem */ /* Create activation subsystem */
context->activation = bus_activation_new (context, &full_address, context->activation = bus_activation_new (context, &full_address,
service_dirs, error); bus_config_parser_get_service_dirs (parser),
error);
if (context->activation == NULL) if (context->activation == NULL)
{ {
_DBUS_ASSERT_ERROR_IS_SET (error); _DBUS_ASSERT_ERROR_IS_SET (error);
......
...@@ -38,7 +38,9 @@ typedef enum ...@@ -38,7 +38,9 @@ typedef enum
ELEMENT_LIMIT, ELEMENT_LIMIT,
ELEMENT_ALLOW, ELEMENT_ALLOW,
ELEMENT_DENY, ELEMENT_DENY,
ELEMENT_FORK ELEMENT_FORK,
ELEMENT_SERVICEDIR,
ELEMENT_INCLUDEDIR
} ElementType; } ElementType;
typedef struct typedef struct
...@@ -87,6 +89,8 @@ struct BusConfigParser ...@@ -87,6 +89,8 @@ struct BusConfigParser
DBusList *listen_on; /**< List of addresses to listen to */ DBusList *listen_on; /**< List of addresses to listen to */
DBusList *mechanisms; /**< Auth mechanisms */ DBusList *mechanisms; /**< Auth mechanisms */
DBusList *service_dirs; /**< Directories to look for services in */
unsigned int fork : 1; /**< TRUE to fork into daemon mode */ unsigned int fork : 1; /**< TRUE to fork into daemon mode */
}; };
...@@ -118,6 +122,10 @@ element_type_to_name (ElementType type) ...@@ -118,6 +122,10 @@ element_type_to_name (ElementType type)
return "deny"; return "deny";
case ELEMENT_FORK: case ELEMENT_FORK:
return "fork"; return "fork";
case ELEMENT_SERVICEDIR:
return "servicedir";
case ELEMENT_INCLUDEDIR:
return "includedir";
} }
_dbus_assert_not_reached ("bad element type"); _dbus_assert_not_reached ("bad element type");
...@@ -210,6 +218,9 @@ merge_included (BusConfigParser *parser, ...@@ -210,6 +218,9 @@ merge_included (BusConfigParser *parser,
while ((link = _dbus_list_pop_first_link (&included->mechanisms))) while ((link = _dbus_list_pop_first_link (&included->mechanisms)))
_dbus_list_append_link (&parser->mechanisms, link); _dbus_list_append_link (&parser->mechanisms, link);
while ((link = _dbus_list_pop_first_link (&included->service_dirs)))
_dbus_list_append_link (&parser->service_dirs, link);
return TRUE; return TRUE;
} }
...@@ -256,6 +267,12 @@ bus_config_parser_unref (BusConfigParser *parser) ...@@ -256,6 +267,12 @@ bus_config_parser_unref (BusConfigParser *parser)
_dbus_list_clear (&parser->listen_on); _dbus_list_clear (&parser->listen_on);
_dbus_list_foreach (&parser->service_dirs,
(DBusForeachFunction) dbus_free,
NULL);
_dbus_list_clear (&parser->service_dirs);
dbus_free (parser); dbus_free (parser);
} }
} }
...@@ -461,6 +478,32 @@ start_busconfig_child (BusConfigParser *parser, ...@@ -461,6 +478,32 @@ start_busconfig_child (BusConfigParser *parser,
return FALSE; return FALSE;
} }
return TRUE;
}
else if (strcmp (element_name, "includedir") == 0)
{
if (!check_no_attributes (parser, "includedir", attribute_names, attribute_values, error))
return FALSE;
if (push_element (parser, ELEMENT_INCLUDEDIR) == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
return TRUE;
}
else if (strcmp (element_name, "servicedir") == 0)
{
if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error))
return FALSE;
if (push_element (parser, ELEMENT_SERVICEDIR) == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
return TRUE; return TRUE;
} }
else if (strcmp (element_name, "include") == 0) else if (strcmp (element_name, "include") == 0)
...@@ -681,6 +724,8 @@ bus_config_parser_end_element (BusConfigParser *parser, ...@@ -681,6 +724,8 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_USER: case ELEMENT_USER:
case ELEMENT_LISTEN: case ELEMENT_LISTEN:
case ELEMENT_AUTH: case ELEMENT_AUTH:
case ELEMENT_SERVICEDIR:
case ELEMENT_INCLUDEDIR:
if (!e->had_content) if (!e->had_content)
{ {
dbus_set_error (error, DBUS_ERROR_FAILED, dbus_set_error (error, DBUS_ERROR_FAILED,
...@@ -714,6 +759,112 @@ all_whitespace (const DBusString *str) ...@@ -714,6 +759,112 @@ all_whitespace (const DBusString *str)
return i == _dbus_string_get_length (str); return i == _dbus_string_get_length (str);
} }
static dbus_bool_t
include_file (BusConfigParser *parser,
const DBusString *filename,
dbus_bool_t ignore_missing,
DBusError *error)
{
/* FIXME good test case for this would load each config file in the
* test suite both alone, and as an include, and check
* that the result is the same
*/
BusConfigParser *included;
DBusError tmp_error;
dbus_error_init (&tmp_error);
included = bus_config_load (filename, &tmp_error);
if (included == NULL)
{
_DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_FILE_NOT_FOUND) &&
ignore_missing)
{
dbus_error_free (&tmp_error);
return TRUE;
}
else
{
dbus_move_error (&tmp_error, error);
return FALSE;
}
}
else
{
_DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
if (!merge_included (parser, included, error))
{
bus_config_parser_unref (included);
return FALSE;
}
bus_config_parser_unref (included);
return TRUE;
}
}
static dbus_bool_t
include_dir (BusConfigParser *parser,
const DBusString *dirname,
DBusError *error)
{
DBusString filename;
dbus_bool_t retval;
DBusError tmp_error;
DBusDirIter *dir;
if (!_dbus_string_init (&filename))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
retval = FALSE;
dir = _dbus_directory_open (dirname, error);
/* FIXME this is just so the tests pass for now, it needs to come out
* once I implement make-dirname-relative-to-currently-parsed-files-dir
*/
if (dir == NULL)
{
if (error)
dbus_error_free (error);
_dbus_string_free (&filename);
return TRUE;
}
if (dir == NULL)
goto failed;
while (_dbus_directory_get_next_file (dir, &filename, &tmp_error))
{
if (_dbus_string_ends_with_c_str (&filename, ".conf"))
{
if (!include_file (parser, &filename, TRUE, error))
goto failed;
}
}
if (dbus_error_is_set (&tmp_error))
{
dbus_move_error (&tmp_error, error);
goto failed;
}
retval = TRUE;
failed:
_dbus_string_free (&filename);
if (dir)
_dbus_directory_close (dir);
return retval;
}
dbus_bool_t dbus_bool_t
bus_config_parser_content (BusConfigParser *parser, bus_config_parser_content (BusConfigParser *parser,
const DBusString *content, const DBusString *content,
...@@ -770,45 +921,23 @@ bus_config_parser_content (BusConfigParser *parser, ...@@ -770,45 +921,23 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_INCLUDE: case ELEMENT_INCLUDE:
{ {
/* FIXME good test case for this would load each config file in the
* test suite both alone, and as an include, and check
* that the result is the same
*/
BusConfigParser *included;
DBusError tmp_error;
e->had_content = TRUE; e->had_content = TRUE;
dbus_error_init (&tmp_error);
included = bus_config_load (content, &tmp_error);
if (included == NULL)
{
_DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_FILE_NOT_FOUND) &&
e->d.include.ignore_missing)
{
dbus_error_free (&tmp_error);
return TRUE;
}
else
{
dbus_move_error (&tmp_error, error);
return FALSE;
}
}
else
{
_DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
if (!merge_included (parser, included, error)) if (!include_file (parser, content,
return FALSE; e->d.include.ignore_missing, error))
return FALSE;
bus_config_parser_unref (included);
return TRUE;
}
} }
break; break;
case ELEMENT_INCLUDEDIR:
{
e->had_content = TRUE;
if (!include_dir (parser, content, error))
return FALSE;
}
break;
case ELEMENT_USER: case ELEMENT_USER:
{ {
char *s; char *s;
...@@ -858,6 +987,24 @@ bus_config_parser_content (BusConfigParser *parser, ...@@ -858,6 +987,24 @@ bus_config_parser_content (BusConfigParser *parser,
} }
} }
break; break;
case ELEMENT_SERVICEDIR:
{
char *s;
e->had_content = TRUE;
if (!_dbus_string_copy_data (content, &s))
goto nomem;
if (!_dbus_list_append (&parser->service_dirs,
s))
{
dbus_free (s);
goto nomem;
}
}
break;
} }
_DBUS_ASSERT_ERROR_IS_CLEAR (error); _DBUS_ASSERT_ERROR_IS_CLEAR (error);
...@@ -911,6 +1058,12 @@ bus_config_parser_get_mechanisms (BusConfigParser *parser) ...@@ -911,6 +1058,12 @@ bus_config_parser_get_mechanisms (BusConfigParser *parser)
return &parser->mechanisms; return &parser->mechanisms;
} }
DBusList**
bus_config_parser_get_service_dirs (BusConfigParser *parser)
{
return &parser->service_dirs;
}
dbus_bool_t dbus_bool_t
bus_config_parser_get_fork (BusConfigParser *parser) bus_config_parser_get_fork (BusConfigParser *parser)
{ {
......
...@@ -55,10 +55,11 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser, ...@@ -55,10 +55,11 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser,
DBusError *error); DBusError *error);
/* Functions for extracting the parse results */ /* Functions for extracting the parse results */
const char* bus_config_parser_get_user (BusConfigParser *parser); const char* bus_config_parser_get_user (BusConfigParser *parser);
DBusList** bus_config_parser_get_addresses (BusConfigParser *parser); DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser); DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser);
dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser); dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser);
DBusList** bus_config_parser_get_service_dirs (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.
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
* file in the user's homedir. However they are transient (only used * file in the user's homedir. However they are transient (only used
* by a single server instance for a fixed period of time, then * by a single server instance for a fixed period of time, then
* discarded). Also, the keys are not sent over the wire. * discarded). Also, the keys are not sent over the wire.
*
* @todo there's a memory leak on some codepath in here, I saw it once
* when running make check - probably some specific initial cookies
* present in the cookie file, then depending on what we do with them.
*/ */
/** /**
......
...@@ -3185,18 +3185,21 @@ _dbus_change_identity (unsigned long uid, ...@@ -3185,18 +3185,21 @@ _dbus_change_identity (unsigned long uid,
unsigned long gid, unsigned long gid,
DBusError *error) DBusError *error)
{ {
if (setuid (uid) < 0) /* Set GID first, or the setuid may remove our permission
* to change the GID
*/
if (setgid (gid) < 0)
{ {
dbus_set_error (error, _dbus_error_from_errno (errno), dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to set UID to %lu: %s", uid, "Failed to set GID to %lu: %s", gid,
_dbus_strerror (errno)); _dbus_strerror (errno));
return FALSE; return FALSE;
} }
if (setgid (gid) < 0) if (setuid (uid) < 0)
{ {
dbus_set_error (error, _dbus_error_from_errno (errno), dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to set GID to %lu: %s", gid, "Failed to set UID to %lu: %s", uid,
_dbus_strerror (errno)); _dbus_strerror (errno));
return FALSE; return FALSE;
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<user>mybususer</user> <user>mybususer</user>
<listen>unix:path=/foo/bar</listen> <listen>unix:path=/foo/bar</listen>
<listen>tcp:port=1234</listen> <listen>tcp:port=1234</listen>
<includedir>basic.d</includedir>
<servicedir>/usr/share/foo</servicedir>
<include ignore_missing="yes">nonexistent.conf</include> <include ignore_missing="yes">nonexistent.conf</include>
<policy context="default"> <policy context="default">
<allow user="*"/> <allow user="*"/>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment