summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2015-04-20 15:19:26 +0200
committerSven Eden <yamakuzure@gmx.net>2017-03-14 08:07:01 +0100
commitb9db6972db2353eb26744c46e30e7f6d1d56e037 (patch)
tree77132fac5a1ecd0425aae71b92a9052637ca9ffb /src/login
parentb87df1e2ab57146e68e95964a3618b6ebf5ae3f9 (diff)
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.
Diffstat (limited to 'src/login')
-rw-r--r--src/login/logind-dbus.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 374e59837..f638fe097 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1590,49 +1590,25 @@ int bus_manager_shutdown_or_sleep_now_or_later(
return r;
}
-static int method_do_shutdown_or_sleep(
+static int verify_shutdown_creds(
Manager *m,
sd_bus_message *message,
- const char *unit_name,
InhibitWhat w,
+ bool interactive,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
- const char *sleep_verb,
- sd_bus_message_handler_t method,
sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
bool multiple_sessions, blocked;
- int interactive, r;
uid_t uid;
+ int r;
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);
- assert(method);
-
- r = sd_bus_message_read(message, "b", &interactive);
- if (r < 0)
- return r;
-
- /* Don't allow multiple jobs being executed at the same time */
- if (m->action_what)
- return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
-
- if (sleep_verb) {
- r = can_sleep(sleep_verb);
- if (r < 0)
- return r;
-
- if (r == 0)
- 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)
@@ -1649,7 +1625,7 @@ static int method_do_shutdown_or_sleep(
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
- if (multiple_sessions) {
+ 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;
@@ -1657,7 +1633,7 @@ static int method_do_shutdown_or_sleep(
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
- if (blocked) {
+ 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;
@@ -1665,7 +1641,7 @@ static int method_do_shutdown_or_sleep(
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
- if (!multiple_sessions && !blocked) {
+ 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;
@@ -1673,6 +1649,50 @@ static int method_do_shutdown_or_sleep(
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,
+ const char *unit_name,
+ InhibitWhat w,
+ const char *action,
+ const char *action_multiple_sessions,
+ const char *action_ignore_inhibit,
+ const char *sleep_verb,
+ sd_bus_error *error) {
+
+ int interactive, r;
+
+ assert(m);
+ assert(message);
+ assert(unit_name);
+ assert(w >= 0);
+ assert(w <= _INHIBIT_WHAT_MAX);
+
+ r = sd_bus_message_read(message, "b", &interactive);
+ if (r < 0)
+ return r;
+
+ /* Don't allow multiple jobs being executed at the same time */
+ if (m->action_what)
+ return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
+
+ if (sleep_verb) {
+ r = can_sleep(sleep_verb);
+ if (r < 0)
+ return r;
+
+ if (r == 0)
+ return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
+ }
+
+ r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
+ action_ignore_inhibit, error);
+ if (r != 0)
+ return r;
+
r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
if (r < 0)
return r;
@@ -1691,7 +1711,6 @@ static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata,
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
NULL,
- method_poweroff,
error);
}
@@ -1706,7 +1725,6 @@ static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, s
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
NULL,
- method_reboot,
error);
}
@@ -1721,7 +1739,6 @@ static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata,
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
"suspend",
- method_suspend,
error);
}
@@ -1736,7 +1753,6 @@ static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hibernate",
- method_hibernate,
error);
}
@@ -1751,7 +1767,6 @@ static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userd
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hybrid-sleep",
- method_hybrid_sleep,
error);
}