diff --git a/src/broker/broker.c b/src/broker/broker.c index 7a56fa74..c2f527a0 100644 --- a/src/broker/broker.c +++ b/src/broker/broker.c @@ -24,6 +24,10 @@ #include "util/sockopt.h" #include "util/user.h" +static int broker_propagate_sighup(Broker *broker) { + return controller_dbus_send_sighup(&broker->controller); +} + static int broker_dispatch_signals(DispatchFile *file) { Broker *broker = c_container_of(file, Broker, signals_file); struct signalfd_siginfo si; @@ -37,6 +41,10 @@ static int broker_dispatch_signals(DispatchFile *file) { c_assert(l == sizeof(si)); + if (si.ssi_signo == SIGHUP) { + broker_propagate_sighup(broker); + } + return DISPATCH_E_EXIT; } @@ -134,6 +142,7 @@ int broker_new(Broker **brokerp, const char *machine_id, int log_fd, int control sigemptyset(&sigmask); sigaddset(&sigmask, SIGTERM); sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGHUP); broker->signals_fd = signalfd(-1, &sigmask, SFD_CLOEXEC | SFD_NONBLOCK); if (broker->signals_fd < 0) @@ -210,6 +219,7 @@ int broker_run(Broker *broker) { sigemptyset(&signew); sigaddset(&signew, SIGTERM); sigaddset(&signew, SIGINT); + sigaddset(&signew, SIGHUP); sigprocmask(SIG_BLOCK, &signew, &sigold); diff --git a/src/broker/controller-dbus.c b/src/broker/controller-dbus.c index 68be2bc4..e70c695c 100644 --- a/src/broker/controller-dbus.c +++ b/src/broker/controller-dbus.c @@ -789,3 +789,47 @@ int controller_dbus_send_reload(Controller *controller, User *user, uint32_t ser return 0; } + +/** + * controller_dbus_send_reload() - Will send a sighup up the chain to reload configs. + */ +int controller_dbus_send_sighup(Controller *controller) { + static const CDVarType type[] = { + C_DVAR_T_INIT( + CONTROLLER_T_MESSAGE( + C_DVAR_T_TUPLE0 + ) + ) + }; + _c_cleanup_(c_dvar_deinit) CDVar var = C_DVAR_INIT; + _c_cleanup_(message_unrefp) Message *message = NULL; + _c_cleanup_(c_freep) void *data = NULL; + size_t n_data; + int r; + + c_dvar_begin_write(&var, (__BYTE_ORDER == __BIG_ENDIAN), type, 1); + c_dvar_write(&var, "((yyyyuu[(y)(y)(y)])())", + c_dvar_is_big_endian(&var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_SIGNAL, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, 1, 0, (uint32_t)-1, + DBUS_MESSAGE_FIELD_PATH, c_dvar_type_o, "/org/bus1/DBus/Broker", + DBUS_MESSAGE_FIELD_INTERFACE, c_dvar_type_s, "org.bus1.DBus.Broker", + DBUS_MESSAGE_FIELD_MEMBER, c_dvar_type_s, "Sighup"); + + r = c_dvar_end_write(&var, &data, &n_data); + if (r) + return error_origin(r); + + r = message_new_outgoing(&message, data, n_data); + if (r) + return error_fold(r); + data = NULL; + + r = connection_queue(&controller->connection, NULL, message); + if (r) { + if (r == CONNECTION_E_QUOTA) + return CONTROLLER_E_QUOTA; + + return error_fold(r); + } + + return 0; +} diff --git a/src/broker/controller.h b/src/broker/controller.h index c3d18f01..e8a31b61 100644 --- a/src/broker/controller.h +++ b/src/broker/controller.h @@ -161,6 +161,7 @@ int controller_dbus_dispatch(Controller *controller, Message *message); int controller_dbus_send_activation(Controller *controller, const char *path, uint64_t serial); int controller_dbus_send_reload(Controller *controller, User *user, uint32_t serial); int controller_dbus_send_environment(Controller *controller, const char * const *env, size_t n_env); +int controller_dbus_send_sighup(Controller *controller); C_DEFINE_CLEANUP(Controller *, controller_deinit); diff --git a/src/util/selinux.c b/src/util/selinux.c index a72cc0a8..a5e21a82 100644 --- a/src/util/selinux.c +++ b/src/util/selinux.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "util/audit.h" #include "util/error.h" @@ -340,6 +341,15 @@ static int bus_selinux_log(int type, const char *fmt, ...) { return 0; } +/** + * On a policy reload we need to reparse the SELinux configuration file, since + * this could have changed. The call back is registered in the broker, but + * we need to reload the configuration in the launcher. + */ +static int policy_reload_callback(int seqno) { + return raise(SIGHUP); +} + /** * bus_selinux_init_global() - initialize the global SELinux context * @@ -386,6 +396,7 @@ int bus_selinux_init_global(void) { } selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback)bus_selinux_log); + selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback)policy_reload_callback); /* XXX: set audit callback to get more metadata in the audit log? */