mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-24 15:50:10 +01:00
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
This commit is contained in:
parent
44ed933284
commit
cfa261b49d
9 changed files with 229 additions and 57 deletions
|
|
@ -1,3 +1,11 @@
|
|||
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>
|
||||
|
||||
* dbus/dbus-server.c (dbus_server_set_auth_mechanisms): new
|
||||
|
|
|
|||
|
|
@ -316,12 +316,12 @@ load_directory (BusActivation *activation,
|
|||
BusActivation*
|
||||
bus_activation_new (BusContext *context,
|
||||
const DBusString *address,
|
||||
const char **directories,
|
||||
DBusList **directories,
|
||||
DBusError *error)
|
||||
{
|
||||
int i;
|
||||
BusActivation *activation;
|
||||
|
||||
DBusList *link;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
activation = dbus_new0 (BusActivation, 1);
|
||||
|
|
@ -358,12 +358,12 @@ bus_activation_new (BusContext *context,
|
|||
}
|
||||
|
||||
/* Load service files */
|
||||
i = 0;
|
||||
while (directories[i] != NULL)
|
||||
link = _dbus_list_get_first_link (directories);
|
||||
while (link != NULL)
|
||||
{
|
||||
if (!load_directory (activation, directories[i], error))
|
||||
if (!load_directory (activation, link->data, error))
|
||||
goto failed;
|
||||
++i;
|
||||
link = _dbus_list_get_next_link (directories, link);
|
||||
}
|
||||
|
||||
return activation;
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@
|
|||
#define BUS_ACTIVATION_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-list.h>
|
||||
#include "bus.h"
|
||||
|
||||
BusActivation* bus_activation_new (BusContext *context,
|
||||
const DBusString *address,
|
||||
const char **paths,
|
||||
DBusList **directories,
|
||||
DBusError *error);
|
||||
void bus_activation_ref (BusActivation *activation);
|
||||
void bus_activation_unref (BusActivation *activation);
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ bus_context_new (const DBusString *config_file,
|
|||
DBusList **addresses;
|
||||
BusConfigParser *parser;
|
||||
DBusString full_address;
|
||||
const char *service_dirs[] = { NULL, NULL };
|
||||
const char *user;
|
||||
char **auth_mechanisms;
|
||||
DBusList **auth_mechanisms_list;
|
||||
|
|
@ -336,7 +335,8 @@ bus_context_new (const DBusString *config_file,
|
|||
/* Create activation subsystem */
|
||||
|
||||
context->activation = bus_activation_new (context, &full_address,
|
||||
service_dirs, error);
|
||||
bus_config_parser_get_service_dirs (parser),
|
||||
error);
|
||||
if (context->activation == NULL)
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ typedef enum
|
|||
ELEMENT_LIMIT,
|
||||
ELEMENT_ALLOW,
|
||||
ELEMENT_DENY,
|
||||
ELEMENT_FORK
|
||||
ELEMENT_FORK,
|
||||
ELEMENT_SERVICEDIR,
|
||||
ELEMENT_INCLUDEDIR
|
||||
} ElementType;
|
||||
|
||||
typedef struct
|
||||
|
|
@ -87,6 +89,8 @@ struct BusConfigParser
|
|||
DBusList *listen_on; /**< List of addresses to listen to */
|
||||
|
||||
DBusList *mechanisms; /**< Auth mechanisms */
|
||||
|
||||
DBusList *service_dirs; /**< Directories to look for services in */
|
||||
|
||||
unsigned int fork : 1; /**< TRUE to fork into daemon mode */
|
||||
};
|
||||
|
|
@ -118,6 +122,10 @@ element_type_to_name (ElementType type)
|
|||
return "deny";
|
||||
case ELEMENT_FORK:
|
||||
return "fork";
|
||||
case ELEMENT_SERVICEDIR:
|
||||
return "servicedir";
|
||||
case ELEMENT_INCLUDEDIR:
|
||||
return "includedir";
|
||||
}
|
||||
|
||||
_dbus_assert_not_reached ("bad element type");
|
||||
|
|
@ -210,6 +218,9 @@ merge_included (BusConfigParser *parser,
|
|||
|
||||
while ((link = _dbus_list_pop_first_link (&included->mechanisms)))
|
||||
_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;
|
||||
}
|
||||
|
|
@ -256,6 +267,12 @@ bus_config_parser_unref (BusConfigParser *parser)
|
|||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
|
@ -461,6 +478,32 @@ start_busconfig_child (BusConfigParser *parser,
|
|||
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;
|
||||
}
|
||||
else if (strcmp (element_name, "include") == 0)
|
||||
|
|
@ -681,6 +724,8 @@ bus_config_parser_end_element (BusConfigParser *parser,
|
|||
case ELEMENT_USER:
|
||||
case ELEMENT_LISTEN:
|
||||
case ELEMENT_AUTH:
|
||||
case ELEMENT_SERVICEDIR:
|
||||
case ELEMENT_INCLUDEDIR:
|
||||
if (!e->had_content)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
|
|
@ -714,6 +759,112 @@ all_whitespace (const DBusString *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
|
||||
bus_config_parser_content (BusConfigParser *parser,
|
||||
const DBusString *content,
|
||||
|
|
@ -770,45 +921,23 @@ bus_config_parser_content (BusConfigParser *parser,
|
|||
|
||||
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;
|
||||
|
||||
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))
|
||||
return FALSE;
|
||||
|
||||
bus_config_parser_unref (included);
|
||||
return TRUE;
|
||||
}
|
||||
if (!include_file (parser, content,
|
||||
e->d.include.ignore_missing, error))
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ELEMENT_INCLUDEDIR:
|
||||
{
|
||||
e->had_content = TRUE;
|
||||
|
||||
if (!include_dir (parser, content, error))
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ELEMENT_USER:
|
||||
{
|
||||
char *s;
|
||||
|
|
@ -858,6 +987,24 @@ bus_config_parser_content (BusConfigParser *parser,
|
|||
}
|
||||
}
|
||||
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);
|
||||
|
|
@ -911,6 +1058,12 @@ bus_config_parser_get_mechanisms (BusConfigParser *parser)
|
|||
return &parser->mechanisms;
|
||||
}
|
||||
|
||||
DBusList**
|
||||
bus_config_parser_get_service_dirs (BusConfigParser *parser)
|
||||
{
|
||||
return &parser->service_dirs;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_config_parser_get_fork (BusConfigParser *parser)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser,
|
|||
DBusError *error);
|
||||
|
||||
/* Functions for extracting the parse results */
|
||||
const char* bus_config_parser_get_user (BusConfigParser *parser);
|
||||
DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
|
||||
DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser);
|
||||
dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser);
|
||||
const char* bus_config_parser_get_user (BusConfigParser *parser);
|
||||
DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
|
||||
DBusList** bus_config_parser_get_mechanisms (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
|
||||
* finished ConfigParser.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
* file in the user's homedir. However they are transient (only used
|
||||
* by a single server instance for a fixed period of time, then
|
||||
* 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,14 +3185,9 @@ _dbus_change_identity (unsigned long uid,
|
|||
unsigned long gid,
|
||||
DBusError *error)
|
||||
{
|
||||
if (setuid (uid) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to set UID to %lu: %s", uid,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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),
|
||||
|
|
@ -3201,6 +3196,14 @@ _dbus_change_identity (unsigned long uid,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (setuid (uid) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to set UID to %lu: %s", uid,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
<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.conf</include>
|
||||
<policy context="default">
|
||||
<allow user="*"/>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue