From: Lennart Poettering Date: Thu, 27 Jun 2024 08:09:45 +0000 (+0200) Subject: hostnamed: if polkit authentication fails for Varlink Describe() call, don't reply... X-Git-Tag: v257-rc1~1036^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6464e80d65fd5bfd9e6206ee305f0da9c88c096;p=thirdparty%2Fsystemd.git hostnamed: if polkit authentication fails for Varlink Describe() call, don't reply to client with an error 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. --- diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index cda1205e268..a8ebf97cd26 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -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 */ diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c index aefc84a00ca..00c55463c82 100644 --- a/src/shared/bus-polkit.c +++ b/src/shared/bus-polkit.c @@ -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; } diff --git a/src/shared/bus-polkit.h b/src/shared/bus-polkit.h index 25616a0a450..ba83cedbe18 100644 --- a/src/shared/bus-polkit.h +++ b/src/shared/bus-polkit.h @@ -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);