diff options
author | Colin Walters <walters@verbum.org> | 2010-01-28 17:09:15 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-01-28 17:09:15 -0500 |
commit | 7a4cd46284dd634c165b5c4eb23606b7c0ff4ade (patch) | |
tree | bf0390d7c05896f538e8c6739108bb3d681f8ef7 /bus | |
parent | 1e82db47431fb19b78f8943c17d63227156e2432 (diff) | |
parent | b93476ce07acce83ff3b396616bb8a0eaf719916 (diff) | |
download | dbus-7a4cd46284dd634c165b5c4eb23606b7c0ff4ade.tar.gz |
Merge branch 'my-dbus-1.2'
Conflicts:
bus/Makefile.am
dbus/dbus-sysdeps-util-unix.c
dbus/dbus-transport.c
test/test-service.c
Diffstat (limited to 'bus')
-rw-r--r-- | bus/Makefile.am | 12 | ||||
-rw-r--r-- | bus/activation.c | 104 | ||||
-rw-r--r-- | bus/activation.h | 4 | ||||
-rw-r--r-- | bus/bus.c | 23 | ||||
-rw-r--r-- | bus/selinux.c | 118 | ||||
-rw-r--r-- | bus/selinux.h | 2 |
6 files changed, 203 insertions, 60 deletions
diff --git a/bus/Makefile.am b/bus/Makefile.am index b1ee36c8..72233f10 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -103,8 +103,8 @@ dbus_daemon_launch_helper_SOURCES= \ $(LAUNCH_HELPER_SOURCES) dbus_daemon_launch_helper_LDADD= \ - $(DBUS_LAUNCHER_LIBS) \ - $(top_builddir)/dbus/libdbus-convenience.la + $(top_builddir)/dbus/libdbus-convenience.la \ + $(DBUS_LAUNCHER_LIBS) dbus_daemon_launch_helper_LDFLAGS=@R_DYNAMIC_LDFLAG@ @SECTION_LDFLAGS@ @@ -115,8 +115,8 @@ dbus_daemon_launch_helper_test_SOURCES= \ $(LAUNCH_HELPER_SOURCES) dbus_daemon_launch_helper_test_LDADD= \ - $(DBUS_LAUNCHER_LIBS) \ - $(top_builddir)/dbus/libdbus-convenience.la + $(top_builddir)/dbus/libdbus-convenience.la \ + $(DBUS_LAUNCHER_LIBS) dbus_daemon_launch_helper_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ @SECTION_LDFLAGS@ dbus_daemon_launch_helper_test_CPPFLAGS= \ @@ -129,8 +129,8 @@ bus_test_launch_helper_SOURCES= \ $(LAUNCH_HELPER_SOURCES) bus_test_launch_helper_LDADD= \ - $(DBUS_LAUNCHER_LIBS) \ - $(top_builddir)/dbus/libdbus-convenience.la + $(top_builddir)/dbus/libdbus-convenience.la \ + $(DBUS_LAUNCHER_LIBS) bus_test_launch_helper_LDFLAGS=@R_DYNAMIC_LDFLAG@ @SECTION_LDFLAGS@ bus_test_launch_helper_CPPFLAGS= \ diff --git a/bus/activation.c b/bus/activation.c index 00caac27..0a28df16 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -735,74 +735,56 @@ out: return retval; } -BusActivation* -bus_activation_new (BusContext *context, - const DBusString *address, - DBusList **directories, - DBusError *error) +dbus_bool_t +bus_activation_reload (BusActivation *activation, + const DBusString *address, + DBusList **directories, + DBusError *error) { - BusActivation *activation; DBusList *link; char *dir; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - activation = dbus_new0 (BusActivation, 1); - if (activation == NULL) - { - BUS_SET_OOM (error); - return NULL; - } - - activation->refcount = 1; - activation->context = context; - activation->n_pending_activations = 0; - + + if (activation->server_address != NULL) + dbus_free (activation->server_address); if (!_dbus_string_copy_data (address, &activation->server_address)) { BUS_SET_OOM (error); goto failed; } - + + if (activation->entries != NULL) + _dbus_hash_table_unref (activation->entries); activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_activation_entry_unref); if (activation->entries == NULL) - { - BUS_SET_OOM (error); - goto failed; - } - - activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, - (DBusFreeFunction)bus_pending_activation_unref); - - if (activation->pending_activations == NULL) { BUS_SET_OOM (error); goto failed; } + if (activation->directories != NULL) + _dbus_hash_table_unref (activation->directories); activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_service_directory_unref); - - if (activation->directories == NULL) + + if (activation->directories == NULL) { BUS_SET_OOM (error); goto failed; } - - /* Load service files */ + link = _dbus_list_get_first_link (directories); while (link != NULL) { BusServiceDirectory *s_dir; - + dir = _dbus_strdup ((const char *) link->data); if (!dir) { BUS_SET_OOM (error); goto failed; } - + s_dir = dbus_new0 (BusServiceDirectory, 1); if (!s_dir) { @@ -813,7 +795,7 @@ bus_activation_new (BusContext *context, s_dir->refcount = 1; s_dir->dir_c = dir; - + s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_activation_entry_unref); @@ -833,8 +815,8 @@ bus_activation_new (BusContext *context, /* only fail on OOM, it is ok if we can't read the directory */ if (!update_directory (activation, s_dir, error)) - { - if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY)) + { + if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY)) goto failed; else dbus_error_free (error); @@ -843,10 +825,52 @@ bus_activation_new (BusContext *context, link = _dbus_list_get_next_link (directories, link); } + return TRUE; + failed: + return FALSE; +} + +BusActivation* +bus_activation_new (BusContext *context, + const DBusString *address, + DBusList **directories, + DBusError *error) +{ + BusActivation *activation; + DBusList *link; + char *dir; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + activation = dbus_new0 (BusActivation, 1); + if (activation == NULL) + { + BUS_SET_OOM (error); + return NULL; + } + + activation->refcount = 1; + activation->context = context; + activation->n_pending_activations = 0; + + if (!bus_activation_reload (activation, address, directories, error)) + goto failed; + + /* Initialize this hash table once, we don't want to lose pending + * activations on reload. */ + activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, + (DBusFreeFunction)bus_pending_activation_unref); + + if (activation->pending_activations == NULL) + { + BUS_SET_OOM (error); + goto failed; + } + activation->environment = _dbus_hash_table_new (DBUS_HASH_STRING, (DBusFreeFunction) dbus_free, (DBusFreeFunction) dbus_free); - + if (activation->environment == NULL) { BUS_SET_OOM (error); diff --git a/bus/activation.h b/bus/activation.h index 2dff812a..03bfed28 100644 --- a/bus/activation.h +++ b/bus/activation.h @@ -32,6 +32,10 @@ BusActivation* bus_activation_new (BusContext *context, const DBusString *address, DBusList **directories, DBusError *error); +dbus_bool_t bus_activation_reload (BusActivation *activation, + const DBusString *address, + DBusList **directories, + DBusError *error); BusActivation* bus_activation_ref (BusActivation *activation); void bus_activation_unref (BusActivation *activation); @@ -444,6 +444,8 @@ process_config_every_time (BusContext *context, /* get our limits and timeout lengths */ bus_config_parser_get_limits (parser, &context->limits); + if (context->policy) + bus_policy_unref (context->policy); context->policy = bus_config_parser_steal_policy (parser); _dbus_assert (context->policy != NULL); @@ -507,21 +509,24 @@ process_config_every_time (BusContext *context, dbus_free(context->servicehelper); context->servicehelper = s; } - + /* Create activation subsystem */ - new_activation = bus_activation_new (context, &full_address, - dirs, error); - if (new_activation == NULL) + if (context->activation) + { + if (!bus_activation_reload (context->activation, &full_address, dirs, error)) + goto failed; + } + else + { + context->activation = bus_activation_new (context, &full_address, dirs, error); + } + + if (context->activation == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } - if (is_reload) - bus_activation_unref (context->activation); - - context->activation = new_activation; - /* Drop existing conf-dir watches (if applicable) */ if (is_reload) diff --git a/bus/selinux.c b/bus/selinux.c index df9a00b1..456723ac 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -22,6 +22,7 @@ */ #include <dbus/dbus-internals.h> #include <dbus/dbus-string.h> +#include <dbus/dbus-userdb.h> #include "selinux.h" #include "services.h" #include "policy.h" @@ -44,7 +45,9 @@ #include <signal.h> #include <stdarg.h> #include <stdio.h> +#include <grp.h> #ifdef HAVE_LIBAUDIT +#include <cap-ng.h> #include <libaudit.h> #endif /* HAVE_LIBAUDIT */ #endif /* HAVE_SELINUX */ @@ -143,13 +146,17 @@ log_callback (const char *fmt, ...) #ifdef HAVE_LIBAUDIT if (audit_fd >= 0) { - char buf[PATH_MAX*2]; + capng_get_caps_process(); + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_AUDIT_WRITE)) + { + char buf[PATH_MAX*2]; - /* FIXME: need to change this to show real user */ - vsnprintf(buf, sizeof(buf), fmt, ap); - audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, + /* FIXME: need to change this to show real user */ + vsnprintf(buf, sizeof(buf), fmt, ap); + audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, getuid()); - return; + return; + } } #endif /* HAVE_LIBAUDIT */ @@ -1010,3 +1017,104 @@ bus_selinux_shutdown (void) #endif /* HAVE_SELINUX */ } +/** + * Changes the user and group the bus is running as. + * + * @param user the user to become + * @param error return location for errors + * @returns #FALSE on failure + */ +dbus_bool_t +_dbus_change_to_daemon_user (const char *user, + DBusError *error) +{ + dbus_uid_t uid; + dbus_gid_t gid; + DBusString u; + + _dbus_string_init_const (&u, user); + + if (!_dbus_get_user_id_and_primary_group (&u, &uid, &gid)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "User '%s' does not appear to exist?", + user); + return FALSE; + } + +#ifdef HAVE_LIBAUDIT + /* If we were root */ + if (_dbus_geteuid () == 0) + { + int rc; + + capng_clear (CAPNG_SELECT_BOTH); + capng_update (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_AUDIT_WRITE); + rc = capng_change_id (uid, gid, 0); + if (rc) + { + switch (rc) { + default: + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to drop capabilities: %s\n", + _dbus_strerror (errno)); + break; + case -4: + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to set GID to %lu: %s", gid, + _dbus_strerror (errno)); + break; + case -5: + _dbus_warn ("Failed to drop supplementary groups: %s\n", + _dbus_strerror (errno)); + break; + case -6: + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to set UID to %lu: %s", uid, + _dbus_strerror (errno)); + break; + case -7: + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to unset keep-capabilities: %s\n", + _dbus_strerror (errno)); + break; + } + return FALSE; + } + } +#else + /* setgroups() only works if we are a privileged process, + * so we don't return error on failure; the only possible + * failure is that we don't have perms to do it. + * + * not sure this is right, maybe if setuid() + * is going to work then setgroups() should also work. + */ + if (setgroups (0, NULL) < 0) + _dbus_warn ("Failed to drop supplementary groups: %s\n", + _dbus_strerror (errno)); + + /* 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), + "Failed to set GID to %lu: %s", gid, + _dbus_strerror (errno)); + 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; + } +#endif /* !HAVE_LIBAUDIT */ + + return TRUE; +} + diff --git a/bus/selinux.h b/bus/selinux.h index 3bab36de..f208fbeb 100644 --- a/bus/selinux.h +++ b/bus/selinux.h @@ -68,5 +68,7 @@ BusSELinuxID* bus_selinux_init_connection_id (DBusConnection *connection, void bus_selinux_audit_init(void); +dbus_bool_t _dbus_change_to_daemon_user (const char *user, + DBusError *error); #endif /* BUS_SELINUX_H */ |