From: Lennart Poettering Date: Mon, 18 Aug 2014 15:44:17 +0000 (+0200) Subject: bus-util: simplify bus_verify_polkit_async() a bit X-Git-Tag: v216~63 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=f38857914ab5c9cc55aac05795e1886963a5fd04 bus-util: simplify bus_verify_polkit_async() a bit First, let's drop the "bus" argument, we can determine it from the message anyway. Secondly, determine the right callback/userdata pair automatically from what is currently is being dispatched. This should simplify things a lot for us, since it makes it unnecessary to pass pointers through the original handlers through all functions when we process messages, which might require authentication. --- diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index c7f738a62..d31fef7ab 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -426,7 +426,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s if (streq_ptr(name, c->data[PROP_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, error, method_set_hostname, c); + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -468,7 +468,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, error, method_set_static_hostname, c); + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -533,10 +533,10 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop * same time as the static one, use the same policy action for * both... */ - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : - "org.freedesktop.hostname1.set-machine-info", interactive, error, cb, c); + "org.freedesktop.hostname1.set-machine-info", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index 65f1d17c9..44facc6ef 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -184,8 +184,7 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) { } int bus_verify_polkit( - sd_bus *bus, - sd_bus_message *m, + sd_bus_message *call, int capability, const char *action, bool interactive, @@ -194,28 +193,26 @@ int bus_verify_polkit( int r; - assert(bus); - assert(m); + assert(call); assert(action); - r = sd_bus_query_sender_privilege(m, capability); + r = sd_bus_query_sender_privilege(call, capability); if (r < 0) return r; - if (r > 0) + else if (r > 0) return 1; - #ifdef ENABLE_POLKIT else { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; int authorized = false, challenge = false; const char *sender; - sender = sd_bus_message_get_sender(m); + sender = sd_bus_message_get_sender(call); if (!sender) return -EBADMSG; r = sd_bus_call_method( - bus, + call->bus, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", "org.freedesktop.PolicyKit1.Authority", @@ -316,30 +313,29 @@ finish: #endif int bus_verify_polkit_async( - sd_bus *bus, - Hashmap **registry, - sd_bus_message *m, + sd_bus_message *call, int capability, const char *action, bool interactive, - sd_bus_error *error, - sd_bus_message_handler_t callback, - void *userdata) { + Hashmap **registry, + sd_bus_error *error) { #ifdef ENABLE_POLKIT _cleanup_bus_message_unref_ sd_bus_message *pk = NULL; + _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL; AsyncPolkitQuery *q; const char *sender; + sd_bus_message_handler_t callback; + void *userdata; #endif int r; - assert(bus); - assert(registry); - assert(m); + assert(call); assert(action); + assert(registry); #ifdef ENABLE_POLKIT - q = hashmap_get(*registry, m); + q = hashmap_get(*registry, call); if (q) { int authorized, challenge; @@ -376,14 +372,23 @@ int bus_verify_polkit_async( } #endif - r = sd_bus_query_sender_privilege(m, capability); + r = sd_bus_query_sender_privilege(call, capability); if (r < 0) return r; - if (r > 0) + else if (r > 0) return 1; #ifdef ENABLE_POLKIT - sender = sd_bus_message_get_sender(m); + if (sd_bus_get_current_message(call->bus) != call) + return -EINVAL; + + callback = sd_bus_get_current_handler(call->bus); + if (!callback) + return -EINVAL; + + userdata = sd_bus_get_current_userdata(call->bus); + + sender = sd_bus_message_get_sender(call); if (!sender) return -EBADMSG; @@ -392,7 +397,7 @@ int bus_verify_polkit_async( return r; r = sd_bus_message_new_method_call( - bus, + call->bus, &pk, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", @@ -416,11 +421,11 @@ int bus_verify_polkit_async( if (!q) return -ENOMEM; - q->request = sd_bus_message_ref(m); + q->request = sd_bus_message_ref(call); q->callback = callback; q->userdata = userdata; - r = hashmap_put(*registry, m, q); + r = hashmap_put(*registry, call, q); if (r < 0) { async_polkit_query_free(q); return r; @@ -428,7 +433,7 @@ int bus_verify_polkit_async( q->registry = *registry; - r = sd_bus_call_async(bus, &q->slot, pk, async_polkit_callback, q, 0); + r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0); if (r < 0) { async_polkit_query_free(q); return r; diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h index 1ac46875b..faf177580 100644 --- a/src/libsystemd/sd-bus/bus-util.h +++ b/src/libsystemd/sd-bus/bus-util.h @@ -62,9 +62,9 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error); int bus_check_peercred(sd_bus *c); -int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e); +int bus_verify_polkit(sd_bus_message *call, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e); -int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, int capability, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata); +int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, Hashmap **registry, sd_bus_error *error); void bus_verify_polkit_async_registry_free(Hashmap *registry); int bus_open_system_systemd(sd_bus **_bus); diff --git a/src/locale/localed.c b/src/locale/localed.c index 5c0bc2c84..508a00079 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -877,9 +877,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_ } if (modified) { - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, - "org.freedesktop.locale1.set-locale", interactive, - error, method_set_locale, c); + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -955,9 +953,7 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle)))) return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data"); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, - "org.freedesktop.locale1.set-keyboard", - interactive, error, method_set_vc_keyboard, c); + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1027,9 +1023,7 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat (options && !string_is_safe(options))) return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data"); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, - "org.freedesktop.locale1.set-keyboard", - interactive, error, method_set_x11_keyboard, c); + r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index bcfcba2d0..acef5119b 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1029,14 +1029,13 @@ static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *us if (!pw) return errno ? -errno : -ENOENT; - r = bus_verify_polkit_async(bus, - &m->polkit_registry, - message, - CAP_SYS_ADMIN, - "org.freedesktop.login1.set-user-linger", - interactive, - error, - method_set_user_linger, m); + r = bus_verify_polkit_async( + message, + CAP_SYS_ADMIN, + "org.freedesktop.login1.set-user-linger", + interactive, + &m->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -1202,14 +1201,13 @@ static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *user if (!seat_name_is_valid(seat)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat); - r = bus_verify_polkit_async(bus, - &m->polkit_registry, - message, - CAP_SYS_ADMIN, - "org.freedesktop.login1.attach-device", - interactive, - error, - method_attach_device, m); + r = bus_verify_polkit_async( + message, + CAP_SYS_ADMIN, + "org.freedesktop.login1.attach-device", + interactive, + &m->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -1234,14 +1232,13 @@ static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *user if (r < 0) return r; - r = bus_verify_polkit_async(bus, - &m->polkit_registry, - message, - CAP_SYS_ADMIN, - "org.freedesktop.login1.flush-devices", - interactive, - error, - method_flush_devices, m); + r = bus_verify_polkit_async( + message, + CAP_SYS_ADMIN, + "org.freedesktop.login1.flush-devices", + interactive, + &m->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -1535,8 +1532,7 @@ static int method_do_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { - r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT, - action_multiple_sessions, interactive, error, method, m); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1544,8 +1540,7 @@ static int method_do_shutdown_or_sleep( } if (blocked) { - r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT, - action_ignore_inhibit, interactive, error, method, m); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1553,8 +1548,7 @@ static int method_do_shutdown_or_sleep( } if (!multiple_sessions && !blocked) { - r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT, - action, interactive, error, method, m); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1691,7 +1685,7 @@ static int method_can_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { - r = bus_verify_polkit(m->bus, message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error); if (r < 0) return r; @@ -1704,7 +1698,7 @@ static int method_can_shutdown_or_sleep( } if (blocked) { - r = bus_verify_polkit(m->bus, message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error); if (r < 0) return r; @@ -1720,7 +1714,7 @@ static int method_can_shutdown_or_sleep( /* If neither inhibit nor multiple sessions * apply then just check the normal policy */ - r = bus_verify_polkit(m->bus, message, CAP_SYS_BOOT, action, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error); if (r < 0) return r; @@ -1840,7 +1834,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, if (m->action_what & w) return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running"); - r = bus_verify_polkit_async(bus, &m->polkit_registry, message, CAP_SYS_BOOT, + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : @@ -1848,7 +1842,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : "org.freedesktop.login1.inhibit-handle-lid-switch", - false, error, method_inhibit, m); + false, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 16036953f..fa3f947ea 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -395,7 +395,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s if (streq_ptr(z, c->zone)) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, error, method_set_timezone, c); + r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -456,7 +456,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata, if (lrtc == c->local_rtc) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, error, method_set_local_rtc, c); + r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -561,7 +561,7 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu } else timespec_store(&ts, (usec_t) utc); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, error, method_set_time, c); + r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -601,7 +601,7 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus if ((bool)ntp == c->use_ntp) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, error, method_set_ntp, c); + r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, &c->polkit_registry, error); if (r < 0) return r; if (r == 0)