diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy index 502b9756474..0470cb70c1e 100644 --- a/src/resolve/org.freedesktop.resolve1.policy +++ b/src/resolve/org.freedesktop.resolve1.policy @@ -139,4 +139,59 @@ unix-user:systemd-resolve + + Subscribe query results + Authentication is required to subscribe query results. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + + Dump cache + Authentication is required to dump cache. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + + Dump server state + Authentication is required to dump server state. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + + Dump statistics + Authentication is required to dump statistics. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + + Reset statistics + Authentication is required to reset statistics. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 9cf2a527891..1b9fab3de3c 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -1137,11 +1137,17 @@ static int show_statistics(int argc, char **argv, void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = sd_varlink_connect_address(&vl, "/run/systemd/resolve/io.systemd.Resolve.Monitor"); if (r < 0) return log_error_errno(r, "Failed to connect to query monitoring service /run/systemd/resolve/io.systemd.Resolve.Monitor: %m"); - r = varlink_call_and_log(vl, "io.systemd.Resolve.Monitor.DumpStatistics", /* parameters= */ NULL, &reply); + r = varlink_callbo_and_log( + vl, + "io.systemd.Resolve.Monitor.DumpStatistics", + &reply, + SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)); if (r < 0) return r; @@ -1295,11 +1301,17 @@ static int reset_statistics(int argc, char **argv, void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = sd_varlink_connect_address(&vl, "/run/systemd/resolve/io.systemd.Resolve.Monitor"); if (r < 0) return log_error_errno(r, "Failed to connect to query monitoring service /run/systemd/resolve/io.systemd.Resolve.Monitor: %m"); - r = varlink_call_and_log(vl, "io.systemd.Resolve.Monitor.ResetStatistics", /* parameters= */ NULL, &reply); + r = varlink_callbo_and_log( + vl, + "io.systemd.Resolve.Monitor.ResetStatistics", + &reply, + SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)); if (r < 0) return r; @@ -2941,6 +2953,8 @@ static int verb_monitor(int argc, char *argv[], void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r, c; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = sd_event_default(&event); if (r < 0) return log_error_errno(r, "Failed to get event loop: %m"); @@ -2965,7 +2979,10 @@ static int verb_monitor(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to bind reply callback to varlink connection: %m"); - r = sd_varlink_observe(vl, "io.systemd.Resolve.Monitor.SubscribeQueryResults", NULL); + r = sd_varlink_observebo( + vl, + "io.systemd.Resolve.Monitor.SubscribeQueryResults", + SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)); if (r < 0) return log_error_errno(r, "Failed to issue SubscribeQueryResults() varlink call: %m"); @@ -3099,11 +3116,17 @@ static int verb_show_cache(int argc, char *argv[], void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = sd_varlink_connect_address(&vl, "/run/systemd/resolve/io.systemd.Resolve.Monitor"); if (r < 0) return log_error_errno(r, "Failed to connect to query monitoring service /run/systemd/resolve/io.systemd.Resolve.Monitor: %m"); - r = varlink_call_and_log(vl, "io.systemd.Resolve.Monitor.DumpCache", /* parameters= */ NULL, &reply); + r = varlink_callbo_and_log( + vl, + "io.systemd.Resolve.Monitor.DumpCache", + &reply, + SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)); if (r < 0) return r; @@ -3273,11 +3296,17 @@ static int verb_show_server_state(int argc, char *argv[], void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = sd_varlink_connect_address(&vl, "/run/systemd/resolve/io.systemd.Resolve.Monitor"); if (r < 0) return log_error_errno(r, "Failed to connect to query monitoring service /run/systemd/resolve/io.systemd.Resolve.Monitor: %m"); - r = varlink_call_and_log(vl, "io.systemd.Resolve.Monitor.DumpServerState", /* parameters= */ NULL, &reply); + r = varlink_callbo_and_log( + vl, + "io.systemd.Resolve.Monitor.DumpServerState", + &reply, + SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)); if (r < 0) return r; diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index f2fbf7a5232..3c6d70ae1ef 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "bus-polkit.h" #include "glyph-util.h" #include "in-addr-util.h" #include "json-util.h" @@ -1233,6 +1234,29 @@ static int vl_method_resolve_record(sd_varlink *link, sd_json_variant *parameter return 1; } +static int verify_polkit(sd_varlink *link, sd_json_variant *parameters, const char *action) { + static const sd_json_dispatch_field dispatch_table[] = { + VARLINK_DISPATCH_POLKIT_FIELD, + {} + }; + + int r; + Manager *m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(ASSERT_PTR(link)))); + + assert(action); + + r = sd_varlink_dispatch(link, parameters, dispatch_table, /* userdata = */ NULL); + if (r != 0) + return r; + + return varlink_verify_polkit_async( + link, + m->bus, + action, + /* details= */ NULL, + &m->polkit_registry); +} + static int vl_method_subscribe_query_results(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { Manager *m; int r; @@ -1245,8 +1269,9 @@ static int vl_method_subscribe_query_results(sd_varlink *link, sd_json_variant * if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)) return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL); - if (sd_json_variant_elements(parameters) > 0) - return sd_varlink_error_invalid_parameter(link, parameters); + r = verify_polkit(link, parameters, "org.freedesktop.resolve1.subscribe-query-results"); + if (r <= 0) + return r; /* Send a ready message to the connecting client, to indicate that we are now listinening, and all * queries issued after the point the client sees this will also be reported to the client. */ @@ -1271,8 +1296,9 @@ static int vl_method_dump_cache(sd_varlink *link, sd_json_variant *parameters, s assert(link); - if (sd_json_variant_elements(parameters) > 0) - return sd_varlink_error_invalid_parameter(link, parameters); + r = verify_polkit(link, parameters, "org.freedesktop.resolve1.dump-cache"); + if (r <= 0) + return r; m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); @@ -1319,8 +1345,9 @@ static int vl_method_dump_server_state(sd_varlink *link, sd_json_variant *parame assert(link); - if (sd_json_variant_elements(parameters) > 0) - return sd_varlink_error_invalid_parameter(link, parameters); + r = verify_polkit(link, parameters, "org.freedesktop.resolve1.dump-server-state"); + if (r <= 0) + return r; m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); @@ -1359,8 +1386,9 @@ static int vl_method_dump_statistics(sd_varlink *link, sd_json_variant *paramete assert(link); - if (sd_json_variant_elements(parameters) > 0) - return sd_varlink_error_invalid_parameter(link, parameters); + r = verify_polkit(link, parameters, "org.freedesktop.resolve1.dump-statistics"); + if (r <= 0) + return r; m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); @@ -1373,11 +1401,13 @@ static int vl_method_dump_statistics(sd_varlink *link, sd_json_variant *paramete static int vl_method_reset_statistics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { Manager *m; + int r; assert(link); - if (sd_json_variant_elements(parameters) > 0) - return sd_varlink_error_invalid_parameter(link, parameters); + r = verify_polkit(link, parameters, "org.freedesktop.resolve1.reset-statistics"); + if (r <= 0) + return r; m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); @@ -1395,7 +1425,7 @@ static int varlink_monitor_server_init(Manager *m) { if (m->varlink_monitor_server) return 0; - r = sd_varlink_server_new(&server, SD_VARLINK_SERVER_ROOT_ONLY); + r = sd_varlink_server_new(&server, SD_VARLINK_SERVER_ACCOUNT_UID); if (r < 0) return log_error_errno(r, "Failed to allocate varlink server object: %m"); @@ -1419,7 +1449,7 @@ static int varlink_monitor_server_init(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to register varlink disconnect handler: %m"); - r = sd_varlink_server_listen_address(server, "/run/systemd/resolve/io.systemd.Resolve.Monitor", 0600); + r = sd_varlink_server_listen_address(server, "/run/systemd/resolve/io.systemd.Resolve.Monitor", 0666); if (r < 0) return log_error_errno(r, "Failed to bind to varlink socket: %m"); diff --git a/src/shared/varlink-io.systemd.Resolve.Monitor.c b/src/shared/varlink-io.systemd.Resolve.Monitor.c index 36681f5ea03..8c9fb514697 100644 --- a/src/shared/varlink-io.systemd.Resolve.Monitor.c +++ b/src/shared/varlink-io.systemd.Resolve.Monitor.c @@ -19,6 +19,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( static SD_VARLINK_DEFINE_METHOD( SubscribeQueryResults, + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), /* First reply */ SD_VARLINK_DEFINE_OUTPUT(ready, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), /* Subsequent replies */ @@ -49,6 +50,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( static SD_VARLINK_DEFINE_METHOD( DumpCache, + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ScopeCache, SD_VARLINK_ARRAY)); static SD_VARLINK_DEFINE_STRUCT_TYPE( @@ -72,6 +74,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( static SD_VARLINK_DEFINE_METHOD( DumpServerState, + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ServerState, SD_VARLINK_ARRAY)); static SD_VARLINK_DEFINE_STRUCT_TYPE( @@ -98,11 +101,14 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( static SD_VARLINK_DEFINE_METHOD( DumpStatistics, + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(transactions, TransactionStatistics, 0), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(cache, CacheStatistics, 0), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dnssec, DnssecStatistics, 0)); -static SD_VARLINK_DEFINE_METHOD(ResetStatistics); +static SD_VARLINK_DEFINE_METHOD( + ResetStatistics, + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); SD_VARLINK_DEFINE_INTERFACE( io_systemd_Resolve_Monitor,