]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hostnamed: if polkit authentication fails for Varlink Describe() call, don't reply...
authorLennart Poettering <lennart@poettering.net>
Thu, 27 Jun 2024 08:09:45 +0000 (10:09 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 27 Jun 2024 08:43:21 +0000 (10:43 +0200)
The logic of the Describe() call was supposed to be: if we can acquire
the PK priv to get the product UUID then let's return the product UUID,
and if we cannot then return the data without it.

This didn't work however, since the polkit varlink glue would
immediately propagate the error it acquired from polkit its own client.
Let's turn this off, optionally, so that hostnamed can handle this
nicely.

src/hostname/hostnamed.c
src/shared/bus-polkit.c
src/shared/bus-polkit.h

index cda1205e2686f0d264bd8ef0ad943993dc3fffc7..a8ebf97cd26d174e0e2f2a0f466554fefd4fb053 100644 (file)
@@ -1621,11 +1621,13 @@ static int vl_method_describe(Varlink *link, sd_json_variant *parameters, Varlin
         if (r != 0)
                 return r;
 
-        r = varlink_verify_polkit_async(
+        r = varlink_verify_polkit_async_full(
                         link,
                         c->bus,
                         "org.freedesktop.hostname1.get-hardware-serial",
                         /* details= */ NULL,
+                        UID_INVALID,
+                        POLKIT_DONT_REPLY,
                         &c->polkit_registry);
         if (r == 0)
                 return 0; /* No authorization for now, but the async polkit stuff will call us again when it has it */
index aefc84a00ca4c41819236b110f635e39cf309f1f..00c55463c82fde27cc9a75b46f185584b8dc10aa 100644 (file)
@@ -786,11 +786,13 @@ int varlink_verify_polkit_async_full(
                 if (r != 0)
                         log_debug("Found matching previous polkit authentication for '%s'.", action);
                 if (r < 0) {
-                        /* Reply with a nice error */
-                        if (sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED))
-                                (void) varlink_error(link, VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL);
-                        else if (ERRNO_IS_NEG_PRIVILEGE(r))
-                                (void) varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, NULL);
+                        if (!FLAGS_SET(flags, POLKIT_DONT_REPLY)) {
+                                /* Reply with a nice error */
+                                if (sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED))
+                                        (void) varlink_error(link, VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL);
+                                else if (ERRNO_IS_NEG_PRIVILEGE(r))
+                                        (void) varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, NULL);
+                        }
 
                         return r;
                 }
index 25616a0a4501f7ff3c411688d3fcc7657a4fc05e..ba83cedbe183432e608877a59d72d55ba0564889 100644 (file)
@@ -11,6 +11,7 @@ typedef enum PolkitFLags {
         POLKIT_ALLOW_INTERACTIVE = 1 << 0, /* Allow interactive auth (typically not required, because can be derived from bus message/link automatically) */
         POLKIT_ALWAYS_QUERY      = 1 << 1, /* Query polkit even if client is privileged */
         POLKIT_DEFAULT_ALLOW     = 1 << 2, /* If polkit is not around, assume "allow" rather than the usual "deny" */
+        POLKIT_DONT_REPLY        = 1 << 3, /* Varlink: don't immediately propagate polkit error to the Varlink client */
 } PolkitFlags;
 
 int bus_test_polkit(sd_bus_message *call, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e);