X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fsd-bus.c;h=8f97a582d77513617a1bb6019e8c7c988ce539ae;hb=412c18f10c9df3f0a02358d8c0e707ed2e5fa186;hp=5aa8eacebb61095203c40c986bb3d49fed9744f7;hpb=705a415f684f8e9ee19983e5859de00bbb1477cb;p=elogind.git diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5aa8eaceb..8f97a582d 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -274,24 +274,50 @@ _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) { } _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) { + uint64_t new_flags; assert_return(bus, -EINVAL); - assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b); + new_flags = bus->attach_flags; + SET_FLAG(new_flags, KDBUS_ATTACH_TIMESTAMP, b); + + if (bus->attach_flags == new_flags) + return 0; + + bus->attach_flags = new_flags; + if (bus->state != BUS_UNSET && bus->is_kernel) + bus_kernel_realize_attach_flags(bus); + return 0; } -_public_ int sd_bus_negotiate_creds(sd_bus *bus, uint64_t mask) { +_public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) { + uint64_t new_flags; + assert_return(bus, -EINVAL); assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL); - assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); + if (b) + bus->creds_mask |= mask; + else + bus->creds_mask &= ~mask; + /* The well knowns we need unconditionally, so that matches can work */ - bus->creds_mask = mask | SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; + bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; - return kdbus_translate_attach_flags(bus->creds_mask, &bus->attach_flags); + /* Make sure we don't lose the timestamp flag */ + new_flags = (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) | attach_flags_to_kdbus(bus->creds_mask); + if (bus->attach_flags == new_flags) + return 0; + + bus->attach_flags = new_flags; + if (bus->state != BUS_UNSET && bus->is_kernel) + bus_kernel_realize_attach_flags(bus); + + return 0; } _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { @@ -1070,7 +1096,8 @@ _public_ int sd_bus_open(sd_bus **ret) { /* We don't know whether the bus is trusted or not, so better * be safe, and authenticate everything */ b->trusted = false; - b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS; + b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS; + b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS; r = sd_bus_start(b); if (r < 0) @@ -1116,6 +1143,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) { * need the caller's UID and capability set for that. */ b->trusted = false; b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS; + b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS; r = sd_bus_start(b); if (r < 0) @@ -2477,6 +2505,15 @@ null_message: return r; } +static void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) { + assert(bus); + assert(m); + + m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local"; + m->creds.well_known_names_local = true; + m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask; +} + static int process_closing(sd_bus *bus, sd_bus_message **ret) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; struct reply_callback *c; @@ -2545,7 +2582,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { if (r < 0) return r; - m->sender = "org.freedesktop.DBus.Local"; + bus_message_set_sender_local(bus, m); r = bus_seal_synthetic_message(bus, m); if (r < 0)