]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: factor out polkit checks
authorDaniel Mack <daniel@zonque.org>
Mon, 20 Apr 2015 13:19:26 +0000 (15:19 +0200)
committerDaniel Mack <daniel@zonque.org>
Fri, 24 Apr 2015 15:48:12 +0000 (17:48 +0200)
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.

src/login/logind-dbus.c

index e8a92db6917af865732d9c5efa0ae4759c4634b1..f638fe0970d2bb4704f820d6096cfb20d777e5bb 100644 (file)
@@ -1590,47 +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_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);
-
-        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)
@@ -1647,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;
@@ -1655,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;
@@ -1663,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;
@@ -1671,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;