diff options
author | Tom Gundersen <teg@jklm.no> | 2013-08-12 00:35:49 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2013-10-18 00:55:24 +0200 |
commit | 0c842e0ac0293ca395724fa3aefcc2e65390c8b7 (patch) | |
tree | 1ebfcdbb39c009839c5af51028c3c8e3a5a3e988 /src/libsystemd-bus | |
parent | 7e9cf16c20cd1bca2ba6afb072ef84090cbf5283 (diff) |
fsck: port to sd-bus
Diffstat (limited to 'src/libsystemd-bus')
-rw-r--r-- | src/libsystemd-bus/bus-util.c | 74 | ||||
-rw-r--r-- | src/libsystemd-bus/bus-util.h | 2 |
2 files changed, 76 insertions, 0 deletions
diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c index b77ae91681..0046b486cf 100644 --- a/src/libsystemd-bus/bus-util.c +++ b/src/libsystemd-bus/bus-util.c @@ -19,6 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <sys/socket.h> + #include "sd-event.h" #include "sd-bus.h" @@ -376,3 +378,75 @@ void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) { hashmap_free(registry); #endif } + +static int bus_check_peercred(sd_bus *c) { + int fd; + struct ucred ucred; + socklen_t l; + + assert(c); + + fd = sd_bus_get_fd(c); + + assert(fd >= 0); + + l = sizeof(struct ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) { + log_error("SO_PEERCRED failed: %m"); + return -errno; + } + + if (l != sizeof(struct ucred)) { + log_error("SO_PEERCRED returned wrong size."); + return -E2BIG; + } + + if (ucred.uid != 0 && ucred.uid != geteuid()) + return -EPERM; + + return 1; +} + +int bus_connect_system(sd_bus **_bus) { + sd_bus *bus = NULL; + int r; + bool private = true; + + assert(_bus); + + if (geteuid() == 0) { + /* If we are root, then let's talk directly to the + * system instance, instead of going via the bus */ + + r = sd_bus_new(&bus); + if (r < 0) + return r; + + r = sd_bus_set_address(bus, "unix:path=/run/systemd/private"); + if (r < 0) + return r; + + r = sd_bus_start(bus); + if (r < 0) + return r; + + } else { + r = sd_bus_open_system(&bus); + if (r < 0) + return r; + + private = false; + } + + if (private) { + r = bus_check_peercred(bus); + if (r < 0) { + sd_bus_unref(bus); + + return -EACCES; + } + } + + *_bus = bus; + return 0; +} diff --git a/src/libsystemd-bus/bus-util.h b/src/libsystemd-bus/bus-util.h index 354183f690..9b270c8212 100644 --- a/src/libsystemd-bus/bus-util.h +++ b/src/libsystemd-bus/bus-util.h @@ -37,6 +37,8 @@ int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, const char *action, bool i int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata); void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry); +int bus_connect_system(sd_bus **_bus); + DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref); |