logind: factor out polkit checks

Factor out the code to ask polkit for authorization from
method_do_shutdown_or_sleep() into an own function called
verify_shutdown_creds().

This is needed in order to also use the same checks when shutdown
operations are scheduled. For that, it's also necessary to allow
NULL values for that action{,_multiple_sessions,_ignore_inhibit)
arguments, which will suppress the call if no action string is
passed.
This commit is contained in:
Daniel Mack
2015-04-24 17:48:12 +02:00
parent 905f0a39ae
commit b7aa9589e0
+65 -43
View File
@@ -1590,6 +1590,68 @@ int bus_manager_shutdown_or_sleep_now_or_later(
return r;
}
static int verify_shutdown_creds(
Manager *m,
sd_bus_message *message,
InhibitWhat w,
bool interactive,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
bool multiple_sessions, blocked;
uid_t uid;
int r;
assert(m);
assert(message);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_euid(creds, &uid);
if (r < 0)
return r;
r = have_multiple_sessions(m, uid);
if (r < 0)
return r;
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions && action_multiple_sessions) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
if (blocked && action_ignore_inhibit) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
if (!multiple_sessions && !blocked && action) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
return 0;
}
static int method_do_shutdown_or_sleep(
Manager *m,
sd_bus_message *message,
@@ -1601,19 +1663,13 @@ static int method_do_shutdown_or_sleep(
const char *sleep_verb,
sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
bool multiple_sessions, blocked;
int interactive, r;
uid_t uid;
assert(m);
assert(message);
assert(unit_name);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
assert(action);
assert(action_multiple_sessions);
assert(action_ignore_inhibit);
r = sd_bus_message_read(message, "b", &interactive);
if (r < 0)
@@ -1632,45 +1688,11 @@ static int method_do_shutdown_or_sleep(
return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
}
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
action_ignore_inhibit, error);
if (r != 0)
return r;
r = sd_bus_creds_get_euid(creds, &uid);
if (r < 0)
return r;
r = have_multiple_sessions(m, uid);
if (r < 0)
return r;
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
if (blocked) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
if (!multiple_sessions && !blocked) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
if (r < 0)
return r;