From 67899e3e6ba358b05ac859118c964b84746151f9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 07:31:41 +0900 Subject: [PATCH 01/15] networkctl: enable interactive authentication for dbus method call Previously, e.g. 'networkctl reload' did not ask password through polkit. --- src/network/networkctl.c | 11 +++++++++++ src/network/networkctl.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 6c96a84c46..1d43bd2dee 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -95,6 +95,7 @@ bool arg_stdin = false; unsigned arg_lines = 10; char *arg_drop_in = NULL; sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; +bool arg_ask_password = true; STATIC_DESTRUCTOR_REGISTER(arg_drop_in, freep); @@ -174,6 +175,8 @@ int acquire_bus(sd_bus **ret) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + if (networkd_is_running()) { r = varlink_connect_networkd(/* ret_varlink = */ NULL); if (r < 0) @@ -2841,6 +2844,8 @@ static int link_renew(int argc, char *argv[], void *userdata) { if (r < 0) return r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = 0; for (int i = 1; i < argc; i++) { @@ -2881,6 +2886,8 @@ static int link_force_renew(int argc, char *argv[], void *userdata) { if (r < 0) return r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + for (int i = 1; i < argc; i++) { int index = rtnl_resolve_interface_or_warn(&rtnl, argv[i]); if (index < 0) @@ -2903,6 +2910,8 @@ static int verb_reload(int argc, char *argv[], void *userdata) { if (r < 0) return r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_network_mgr, "Reload", &error, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to reload network settings: %s", bus_error_message(&error, r)); @@ -2922,6 +2931,8 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) { if (r < 0) return r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + indexes = set_new(NULL); if (!indexes) return log_oom(); diff --git a/src/network/networkctl.h b/src/network/networkctl.h index d44ee8173e..f88b2d9ab5 100644 --- a/src/network/networkctl.h +++ b/src/network/networkctl.h @@ -19,6 +19,7 @@ extern bool arg_stdin; extern unsigned arg_lines; extern char *arg_drop_in; extern sd_json_format_flags_t arg_json_format_flags; +extern bool arg_ask_password; bool networkd_is_running(void); int acquire_bus(sd_bus **ret); From 21f31f23cc15c0957c1e0adec36f74ad8892c6ef Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 19 Aug 2024 11:28:22 +0900 Subject: [PATCH 02/15] networkctl: introduce --no-ask-password option --- man/networkctl.xml | 10 ++++++++++ shell-completion/bash/networkctl | 4 ++-- shell-completion/zsh/_networkctl | 1 + src/network/networkctl.c | 33 +++++++++++++++++++------------- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/man/networkctl.xml b/man/networkctl.xml index e47cf5895c..6cc6d0df1f 100644 --- a/man/networkctl.xml +++ b/man/networkctl.xml @@ -634,6 +634,16 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR) + + + + + Do not query the user for authentication for privileged operations. + + + + + diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl index 6c9daa7659..04f54e0e92 100644 --- a/shell-completion/bash/networkctl +++ b/shell-completion/bash/networkctl @@ -44,8 +44,8 @@ _networkctl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword local -A OPTS=( - [STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats -l --full - --no-reload --runtime' + [STANDALONE]='-a --all -h --help --version --no-pager --no-legend --no-ask-password + -s --stats -l --full --no-reload --runtime' [ARG]='-n --lines --json --drop-in' ) diff --git a/shell-completion/zsh/_networkctl b/shell-completion/zsh/_networkctl index ad5b91fb83..cf072c0fcb 100644 --- a/shell-completion/zsh/_networkctl +++ b/shell-completion/zsh/_networkctl @@ -52,6 +52,7 @@ _arguments \ '(-a --all)'{-a,--all}'[Show all links with status]' \ '--no-pager[Do not pipe output into a pager]' \ '--no-legend[Do not print the column headers]' \ + '--no-ask-password[Do not prompt for password]' \ '(- *)'{-h,--help}'[Show this help]' \ '(- *)--version[Show package version]' \ '--drop-in=[Use the given drop-in file name]:NAME' \ diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 1d43bd2dee..854f73045f 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -3027,6 +3027,7 @@ static int help(void) { " --version Show package version\n" " --no-pager Do not pipe output into a pager\n" " --no-legend Do not show the headers and footers\n" + " --no-ask-password Do not prompt for password\n" " -a --all Show status for all links\n" " -s --stats Show detailed link statistics\n" " -l --full Do not ellipsize output\n" @@ -3052,6 +3053,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_NO_PAGER, ARG_NO_LEGEND, + ARG_NO_ASK_PASSWORD, ARG_JSON, ARG_NO_RELOAD, ARG_DROP_IN, @@ -3060,19 +3062,20 @@ static int parse_argv(int argc, char *argv[]) { }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, - { "all", no_argument, NULL, 'a' }, - { "stats", no_argument, NULL, 's' }, - { "full", no_argument, NULL, 'l' }, - { "lines", required_argument, NULL, 'n' }, - { "json", required_argument, NULL, ARG_JSON }, - { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, - { "drop-in", required_argument, NULL, ARG_DROP_IN }, - { "runtime", no_argument, NULL, ARG_RUNTIME }, - { "stdin", no_argument, NULL, ARG_STDIN }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "all", no_argument, NULL, 'a' }, + { "stats", no_argument, NULL, 's' }, + { "full", no_argument, NULL, 'l' }, + { "lines", required_argument, NULL, 'n' }, + { "json", required_argument, NULL, ARG_JSON }, + { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, + { "drop-in", required_argument, NULL, ARG_DROP_IN }, + { "runtime", no_argument, NULL, ARG_RUNTIME }, + { "stdin", no_argument, NULL, ARG_STDIN }, {} }; @@ -3103,6 +3106,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_reload = true; break; + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + case ARG_RUNTIME: arg_runtime = true; break; From 1d7fa67789e7efd659189155ba839d4ed55693a2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 08:12:14 +0900 Subject: [PATCH 03/15] resolvectl: enable interactive authentication for dbus method call Even the server side supports polkit authentication, previously the client side did not support polkit authentication. --- src/resolve/resolvectl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index e03b724235..1f7eb9acdb 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -62,6 +62,7 @@ static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; static PagerFlags arg_pager_flags = 0; bool arg_ifindex_permissive = false; /* If true, don't generate an error if the specified interface index doesn't exist */ static const char *arg_service_family = NULL; +static bool arg_ask_password = true; typedef enum RawType { RAW_NONE, @@ -2169,6 +2170,8 @@ static int call_dns(sd_bus *bus, char **dns, const BusLocator *locator, sd_bus_e _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_message_new_method_call(bus, &req, locator, extended ? "SetLinkDNSEx" : "SetLinkDNS"); if (r < 0) return bus_log_create_error(r); @@ -2274,6 +2277,8 @@ static int call_domain(sd_bus *bus, char **domain, const BusLocator *locator, sd _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_message_new_method_call(bus, &req, locator, "SetLinkDomains"); if (r < 0) return bus_log_create_error(r); @@ -2369,6 +2374,8 @@ static int verb_default_route(int argc, char **argv, void *userdata) { if (b < 0) return log_error_errno(b, "Failed to parse boolean argument: %s", argv[2]); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "SetLinkDefaultRoute", &error, NULL, "ib", arg_ifindex, b); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -2421,6 +2428,8 @@ static int verb_llmnr(int argc, char **argv, void *userdata) { log_warning("Setting LLMNR support level \"%s\" for \"%s\", but the global support level is \"%s\".", argv[2], arg_ifname, global_llmnr_support_str); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "SetLinkLLMNR", &error, NULL, "is", arg_ifindex, argv[2]); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -2473,6 +2482,8 @@ static int verb_mdns(int argc, char **argv, void *userdata) { log_warning("Setting mDNS support level \"%s\" for \"%s\", but the global support level is \"%s\".", argv[2], arg_ifname, global_mdns_support_str); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "SetLinkMulticastDNS", &error, NULL, "is", arg_ifindex, argv[2]); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -2513,6 +2524,8 @@ static int verb_dns_over_tls(int argc, char **argv, void *userdata) { if (argc < 3) return status_ifindex(bus, arg_ifindex, NULL, STATUS_PRIVATE, NULL); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "SetLinkDNSOverTLS", &error, NULL, "is", arg_ifindex, argv[2]); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -2553,6 +2566,8 @@ static int verb_dnssec(int argc, char **argv, void *userdata) { if (argc < 3) return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNSSEC, NULL); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "SetLinkDNSSEC", &error, NULL, "is", arg_ifindex, argv[2]); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -2574,6 +2589,8 @@ static int call_nta(sd_bus *bus, char **nta, const BusLocator *locator, sd_bus_ _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL; int r; + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_message_new_method_call(bus, &req, locator, "SetLinkDNSSECNegativeTrustAnchors"); if (r < 0) return bus_log_create_error(r); @@ -2607,6 +2624,8 @@ static int verb_nta(int argc, char **argv, void *userdata) { if (argc < 3) return status_ifindex(bus, arg_ifindex, NULL, STATUS_NTA, NULL); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + /* If only argument is the empty string, then call SetLinkDNSSECNegativeTrustAnchors() * with an empty list, which will clear the list of domains for an interface. */ clear = strv_equal(argv + 2, STRV_MAKE("")); @@ -2653,6 +2672,8 @@ static int verb_revert_link(int argc, char **argv, void *userdata) { if (arg_ifindex <= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Interface argument required."); + (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); + r = bus_call_method(bus, bus_resolve_mgr, "RevertLink", &error, NULL, "i", arg_ifindex); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); @@ -4125,6 +4146,8 @@ static int run(int argc, char **argv) { if (r < 0) return log_error_errno(r, "sd_bus_open_system: %m"); + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + if (compat) return compat_main(argc, argv, bus); From 5703301ada97d43bfdf8b4f5379c6070ef96e078 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 19 Aug 2024 11:36:22 +0900 Subject: [PATCH 04/15] resolvectl: introduce --no-ask-password option --- man/resolvectl.xml | 10 ++++++++++ shell-completion/bash/resolvectl | 2 +- shell-completion/zsh/_resolvectl | 2 ++ src/resolve/resolvectl.c | 7 +++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/man/resolvectl.xml b/man/resolvectl.xml index ed656b48d7..303aa93291 100644 --- a/man/resolvectl.xml +++ b/man/resolvectl.xml @@ -495,6 +495,16 @@ + + + + + Do not query the user for authentication for privileged operations. + + + + + diff --git a/shell-completion/bash/resolvectl b/shell-completion/bash/resolvectl index 344eaad973..5f2102ccba 100644 --- a/shell-completion/bash/resolvectl +++ b/shell-completion/bash/resolvectl @@ -38,7 +38,7 @@ _resolvectl() { [STANDALONE]='-h --help --version -4 -6 --legend=no --cname=no --validate=no --synthesize=no --cache=no --relax-single-label=no --zone=no --trust-anchor=no --network=no --service-address=no - --service-txt=no --search=no --stale-data=no --no-pager' + --service-txt=no --search=no --stale-data=no --no-pager --no-ask-password' [ARG]='-t --type -c --class -i --interface -p --protocol --raw --json' ) local -A VERBS=( diff --git a/shell-completion/zsh/_resolvectl b/shell-completion/zsh/_resolvectl index 4ca469adcf..c779f73ff3 100644 --- a/shell-completion/zsh/_resolvectl +++ b/shell-completion/zsh/_resolvectl @@ -94,4 +94,6 @@ _arguments \ '--search=[Do not use search domains]:BOOL:(yes no)' \ '--raw=[Dump the answer as binary data]:RAW:(payload packet)' \ '--json=[Output as JSON]:JSON:(pretty short off)' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ '*::default: _resolvectl_commands' diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 1f7eb9acdb..a759f9af07 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -3352,6 +3352,7 @@ static int native_help(void) { " -h --help Show this help\n" " --version Show package version\n" " --no-pager Do not pipe output into a pager\n" + " --no-ask-password Do not prompt for password\n" " -4 Resolve IPv4 addresses\n" " -6 Resolve IPv6 addresses\n" " -i --interface=INTERFACE Look on interface\n" @@ -3724,6 +3725,7 @@ static int native_parse_argv(int argc, char *argv[]) { ARG_RAW, ARG_SEARCH, ARG_NO_PAGER, + ARG_NO_ASK_PASSWORD, ARG_JSON, ARG_STALE_DATA, ARG_RELAX_SINGLE_LABEL, @@ -3749,6 +3751,7 @@ static int native_parse_argv(int argc, char *argv[]) { { "raw", optional_argument, NULL, ARG_RAW }, { "search", required_argument, NULL, ARG_SEARCH }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, { "json", required_argument, NULL, ARG_JSON }, { "stale-data", required_argument, NULL, ARG_STALE_DATA }, { "relax-single-label", required_argument, NULL, ARG_RELAX_SINGLE_LABEL }, @@ -3949,6 +3952,10 @@ static int native_parse_argv(int argc, char *argv[]) { arg_pager_flags |= PAGER_DISABLE; break; + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + case ARG_JSON: r = parse_json_argument(optarg, &arg_json_format_flags); if (r <= 0) From f75ecb9f8bb4ca96375803c31818e65c4e530106 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 19 Aug 2024 11:02:08 +0900 Subject: [PATCH 05/15] resolvectl: several coding style cleanups Use RET_GATHER(), FOREACH_ARRAY(), and strv_skip(). --- src/resolve/resolvectl.c | 125 ++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 68 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index a759f9af07..f8243d8cc0 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -761,34 +761,29 @@ invalid: static int verb_query(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; - int q, r = 0; + int ret = 0, r; if (arg_type != 0) - STRV_FOREACH(p, argv + 1) { - q = resolve_record(bus, *p, arg_class, arg_type, true); - if (q < 0) - r = q; - } + STRV_FOREACH(p, strv_skip(argv, 1)) + RET_GATHER(ret, resolve_record(bus, *p, arg_class, arg_type, true)); else - STRV_FOREACH(p, argv + 1) { + STRV_FOREACH(p, strv_skip(argv, 1)) { if (startswith(*p, "dns:")) - q = resolve_rfc4501(bus, *p); + RET_GATHER(ret, resolve_rfc4501(bus, *p)); else { int family, ifindex; union in_addr_union a; - q = in_addr_ifindex_from_string_auto(*p, &family, &a, &ifindex); - if (q >= 0) - q = resolve_address(bus, family, &a, ifindex); + r = in_addr_ifindex_from_string_auto(*p, &family, &a, &ifindex); + if (r >= 0) + RET_GATHER(ret, resolve_address(bus, family, &a, ifindex)); else - q = resolve_host(bus, *p); + RET_GATHER(ret, resolve_host(bus, *p)); } - if (q < 0) - r = q; } - return r; + return ret; } static int resolve_service(sd_bus *bus, const char *name, const char *type, const char *domain) { @@ -1033,18 +1028,15 @@ static int resolve_openpgp(sd_bus *bus, const char *address) { static int verb_openpgp(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; - int q, r = 0; + int ret = 0; if (!FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); - STRV_FOREACH(p, argv + 1) { - q = resolve_openpgp(bus, *p); - if (q < 0) - r = q; - } + STRV_FOREACH(p, strv_skip(argv, 1)) + RET_GATHER(ret, resolve_openpgp(bus, *p)); - return r; + return ret; } static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) { @@ -1085,25 +1077,25 @@ static bool service_family_is_valid(const char *s) { static int verb_tlsa(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; - char **args = argv + 1; const char *family = "tcp"; - int q, r = 0; + char **args; + int ret = 0; + + assert(argc >= 2); if (!FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); if (service_family_is_valid(argv[1])) { family = argv[1]; - args++; - } + args = strv_skip(argv, 2); + } else + args = strv_skip(argv, 1); - STRV_FOREACH(p, args) { - q = resolve_tlsa(bus, family, *p); - if (q < 0) - r = q; - } + STRV_FOREACH(p, args) + RET_GATHER(ret, resolve_tlsa(bus, family, *p)); - return r; + return ret; } static int show_statistics(int argc, char **argv, void *userdata) { @@ -2071,7 +2063,7 @@ static int status_all(sd_bus *bus, StatusMode mode) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; bool empty_line = false; - int r; + int ret = 0, r; assert(bus); @@ -2129,41 +2121,34 @@ static int status_all(sd_bus *bus, StatusMode mode) { typesafe_qsort(infos, n_infos, interface_info_compare); - r = 0; - for (size_t i = 0; i < n_infos; i++) { - int q = status_ifindex(bus, infos[i].index, infos[i].name, mode, &empty_line); - if (q < 0 && r >= 0) - r = q; - } + FOREACH_ARRAY(info, infos, n_infos) + RET_GATHER(ret, status_ifindex(bus, info->index, info->name, mode, &empty_line)); - return r; + return ret; } static int verb_status(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; - int r = 0; + bool empty_line = false; + int ret = 0; - if (argc > 1) { - bool empty_line = false; + if (argc <= 1) + return status_all(bus, STATUS_ALL); - STRV_FOREACH(ifname, argv + 1) { - int ifindex, q; + STRV_FOREACH(ifname, strv_skip(argv, 1)) { + int ifindex; - ifindex = rtnl_resolve_interface(&rtnl, *ifname); - if (ifindex < 0) { - log_warning_errno(ifindex, "Failed to resolve interface \"%s\", ignoring: %m", *ifname); - continue; - } - - q = status_ifindex(bus, ifindex, NULL, STATUS_ALL, &empty_line); - if (q < 0) - r = q; + ifindex = rtnl_resolve_interface(&rtnl, *ifname); + if (ifindex < 0) { + log_warning_errno(ifindex, "Failed to resolve interface \"%s\", ignoring: %m", *ifname); + continue; } - } else - r = status_all(bus, STATUS_ALL); - return r; + RET_GATHER(ret, status_ifindex(bus, ifindex, NULL, STATUS_ALL, &empty_line)); + } + + return ret; } static int call_dns(sd_bus *bus, char **dns, const BusLocator *locator, sd_bus_error *error, bool extended) { @@ -2256,11 +2241,12 @@ static int verb_dns(int argc, char **argv, void *userdata) { if (argc < 3) return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNS, NULL); - r = call_dns(bus, argv + 2, bus_resolve_mgr, &error, true); + char **args = strv_skip(argv, 2); + r = call_dns(bus, args, bus_resolve_mgr, &error, true); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); - r = call_dns(bus, argv + 2, bus_network_mgr, &error, true); + r = call_dns(bus, args, bus_network_mgr, &error, true); } if (r < 0) { if (arg_ifindex_permissive && @@ -2336,11 +2322,12 @@ static int verb_domain(int argc, char **argv, void *userdata) { if (argc < 3) return status_ifindex(bus, arg_ifindex, NULL, STATUS_DOMAIN, NULL); - r = call_domain(bus, argv + 2, bus_resolve_mgr, &error); + char **args = strv_skip(argv, 2); + r = call_domain(bus, args, bus_resolve_mgr, &error); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); - r = call_domain(bus, argv + 2, bus_network_mgr, &error); + r = call_domain(bus, args, bus_network_mgr, &error); } if (r < 0) { if (arg_ifindex_permissive && @@ -2609,8 +2596,9 @@ static int call_nta(sd_bus *bus, char **nta, const BusLocator *locator, sd_bus_ static int verb_nta(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = ASSERT_PTR(userdata); - int r; + char **args; bool clear; + int r; if (argc >= 2) { r = ifname_mangle(argv[1]); @@ -2628,10 +2616,11 @@ static int verb_nta(int argc, char **argv, void *userdata) { /* If only argument is the empty string, then call SetLinkDNSSECNegativeTrustAnchors() * with an empty list, which will clear the list of domains for an interface. */ - clear = strv_equal(argv + 2, STRV_MAKE("")); + args = strv_skip(argv, 2); + clear = strv_equal(args, STRV_MAKE("")); if (!clear) - STRV_FOREACH(p, argv + 2) { + STRV_FOREACH(p, args) { r = dns_name_is_valid(*p); if (r < 0) return log_error_errno(r, "Failed to validate specified domain %s: %m", *p); @@ -2641,11 +2630,11 @@ static int verb_nta(int argc, char **argv, void *userdata) { *p); } - r = call_nta(bus, clear ? NULL : argv + 2, bus_resolve_mgr, &error); + r = call_nta(bus, clear ? NULL : args, bus_resolve_mgr, &error); if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) { sd_bus_error_free(&error); - r = call_nta(bus, clear ? NULL : argv + 2, bus_network_mgr, &error); + r = call_nta(bus, clear ? NULL : args, bus_network_mgr, &error); } if (r < 0) { if (arg_ifindex_permissive && @@ -4032,8 +4021,8 @@ static int translate(const char *verb, const char *single_arg, size_t num_args, *p++ = (char *) verb; if (single_arg) *p++ = (char *) single_arg; - for (size_t i = 0; i < num_args; i++) - *p++ = args[i]; + FOREACH_ARRAY(arg, args, num_args) + *p++ = *arg; optind = 0; return native_main((int) num, fake, bus); From 614a6770f98b2461577f427e562c75c80f9fe6b5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 19 Aug 2024 11:14:44 +0900 Subject: [PATCH 06/15] resolvectl: acquire DBus connection only when necessary When e.g. `resolvectl monitor` is called, it is not necessary to acquire DBus connection. --- src/resolve/resolvectl.c | 181 ++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 51 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index f8243d8cc0..9cf2a52789 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -103,6 +103,22 @@ typedef struct InterfaceInfo { const char *name; } InterfaceInfo; +static int acquire_bus(sd_bus **ret) { + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + int r; + + assert(ret); + + r = sd_bus_open_system(&bus); + if (r < 0) + return log_error_errno(r, "sd_bus_open_system: %m"); + + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + + *ret = TAKE_PTR(bus); + return 0; +} + static int interface_info_compare(const InterfaceInfo *a, const InterfaceInfo *b) { int r; @@ -760,9 +776,13 @@ invalid: } static int verb_query(int argc, char **argv, void *userdata) { - sd_bus *bus = userdata; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int ret = 0, r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (arg_type != 0) STRV_FOREACH(p, strv_skip(argv, 1)) RET_GATHER(ret, resolve_record(bus, *p, arg_class, arg_type, true)); @@ -966,7 +986,12 @@ static int resolve_service(sd_bus *bus, const char *name, const char *type, cons } static int verb_service(int argc, char **argv, void *userdata) { - sd_bus *bus = userdata; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + + r = acquire_bus(&bus); + if (r < 0) + return r; if (!FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); @@ -1027,8 +1052,12 @@ static int resolve_openpgp(sd_bus *bus, const char *address) { } static int verb_openpgp(int argc, char **argv, void *userdata) { - sd_bus *bus = userdata; - int ret = 0; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r, ret = 0; + + r = acquire_bus(&bus); + if (r < 0) + return r; if (!FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); @@ -1076,13 +1105,17 @@ static bool service_family_is_valid(const char *s) { } static int verb_tlsa(int argc, char **argv, void *userdata) { - sd_bus *bus = userdata; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; const char *family = "tcp"; char **args; - int ret = 0; + int r, ret = 0; assert(argc >= 2); + r = acquire_bus(&bus); + if (r < 0) + return r; + if (!FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); @@ -1277,10 +1310,14 @@ static int reset_statistics(int argc, char **argv, void *userdata) { } static int flush_caches(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = userdata; int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + r = bus_call_method(bus, bus_resolve_mgr, "FlushCaches", &error, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to flush caches: %s", bus_error_message(&error, r)); @@ -1289,10 +1326,14 @@ static int flush_caches(int argc, char **argv, void *userdata) { } static int reset_server_features(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = userdata; int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + r = bus_call_method(bus, bus_resolve_mgr, "ResetServerFeatures", &error, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to reset server features: %s", bus_error_message(&error, r)); @@ -2128,10 +2169,14 @@ static int status_all(sd_bus *bus, StatusMode mode) { } static int verb_status(int argc, char **argv, void *userdata) { - sd_bus *bus = userdata; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; bool empty_line = false; - int ret = 0; + int r, ret = 0; + + r = acquire_bus(&bus); + if (r < 0) + return r; if (argc <= 1) return status_all(bus, STATUS_ALL); @@ -2225,10 +2270,14 @@ static int call_dns(sd_bus *bus, char **dns, const BusLocator *locator, sd_bus_e } static int verb_dns(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2306,10 +2355,14 @@ static int call_domain(sd_bus *bus, char **domain, const BusLocator *locator, sd } static int verb_domain(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2341,10 +2394,14 @@ static int verb_domain(int argc, char **argv, void *userdata) { } static int verb_default_route(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r, b; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2381,12 +2438,16 @@ static int verb_default_route(int argc, char **argv, void *userdata) { } static int verb_llmnr(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *global_llmnr_support_str = NULL; ResolveSupport global_llmnr_support, llmnr_support; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2435,12 +2496,16 @@ static int verb_llmnr(int argc, char **argv, void *userdata) { } static int verb_mdns(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *global_mdns_support_str = NULL; ResolveSupport global_mdns_support, mdns_support; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2495,10 +2560,14 @@ static int verb_mdns(int argc, char **argv, void *userdata) { } static int verb_dns_over_tls(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2537,10 +2606,14 @@ static int verb_dns_over_tls(int argc, char **argv, void *userdata) { } static int verb_dnssec(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2594,12 +2667,16 @@ static int call_nta(sd_bus *bus, char **nta, const BusLocator *locator, sd_bus_ } static int verb_nta(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); char **args; bool clear; int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2648,10 +2725,14 @@ static int verb_nta(int argc, char **argv, void *userdata) { } static int verb_revert_link(int argc, char **argv, void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus *bus = ASSERT_PTR(userdata); int r; + r = acquire_bus(&bus); + if (r < 0) + return r; + if (argc >= 2) { r = ifname_mangle(argv[1]); if (r < 0) @@ -2681,7 +2762,12 @@ static int verb_revert_link(int argc, char **argv, void *userdata) { } static int verb_log_level(int argc, char *argv[], void *userdata) { - sd_bus *bus = ASSERT_PTR(userdata); + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + + r = acquire_bus(&bus); + if (r < 0) + return r; assert(IN_SET(argc, 1, 2)); @@ -3976,7 +4062,7 @@ static int native_parse_argv(int argc, char *argv[]) { return 1 /* work to do */; } -static int native_main(int argc, char *argv[], sd_bus *bus) { +static int native_main(int argc, char *argv[]) { static const Verb verbs[] = { { "help", VERB_ANY, VERB_ANY, 0, verb_help }, @@ -4005,10 +4091,10 @@ static int native_main(int argc, char *argv[], sd_bus *bus) { {} }; - return dispatch_verb(argc, argv, verbs, bus); + return dispatch_verb(argc, argv, verbs, /* userdata = */ NULL); } -static int translate(const char *verb, const char *single_arg, size_t num_args, char **args, sd_bus *bus) { +static int translate(const char *verb, const char *single_arg, size_t num_args, char **args) { char **fake, **p; size_t num; @@ -4025,82 +4111,82 @@ static int translate(const char *verb, const char *single_arg, size_t num_args, *p++ = *arg; optind = 0; - return native_main((int) num, fake, bus); + return native_main((int) num, fake); } -static int compat_main(int argc, char *argv[], sd_bus *bus) { +static int compat_main(int argc, char *argv[]) { int r = 0; switch (arg_mode) { case MODE_RESOLVE_HOST: case MODE_RESOLVE_RECORD: - return translate("query", NULL, argc - optind, argv + optind, bus); + return translate("query", NULL, argc - optind, argv + optind); case MODE_RESOLVE_SERVICE: - return translate("service", NULL, argc - optind, argv + optind, bus); + return translate("service", NULL, argc - optind, argv + optind); case MODE_RESOLVE_OPENPGP: - return translate("openpgp", NULL, argc - optind, argv + optind, bus); + return translate("openpgp", NULL, argc - optind, argv + optind); case MODE_RESOLVE_TLSA: - return translate("tlsa", arg_service_family, argc - optind, argv + optind, bus); + return translate("tlsa", arg_service_family, argc - optind, argv + optind); case MODE_STATISTICS: - return translate("statistics", NULL, 0, NULL, bus); + return translate("statistics", NULL, 0, NULL); case MODE_RESET_STATISTICS: - return translate("reset-statistics", NULL, 0, NULL, bus); + return translate("reset-statistics", NULL, 0, NULL); case MODE_FLUSH_CACHES: - return translate("flush-caches", NULL, 0, NULL, bus); + return translate("flush-caches", NULL, 0, NULL); case MODE_RESET_SERVER_FEATURES: - return translate("reset-server-features", NULL, 0, NULL, bus); + return translate("reset-server-features", NULL, 0, NULL); case MODE_STATUS: - return translate("status", NULL, argc - optind, argv + optind, bus); + return translate("status", NULL, argc - optind, argv + optind); case MODE_SET_LINK: assert(arg_ifname); if (arg_set_dns) { - r = translate("dns", arg_ifname, strv_length(arg_set_dns), arg_set_dns, bus); + r = translate("dns", arg_ifname, strv_length(arg_set_dns), arg_set_dns); if (r < 0) return r; } if (arg_set_domain) { - r = translate("domain", arg_ifname, strv_length(arg_set_domain), arg_set_domain, bus); + r = translate("domain", arg_ifname, strv_length(arg_set_domain), arg_set_domain); if (r < 0) return r; } if (arg_set_nta) { - r = translate("nta", arg_ifname, strv_length(arg_set_nta), arg_set_nta, bus); + r = translate("nta", arg_ifname, strv_length(arg_set_nta), arg_set_nta); if (r < 0) return r; } if (arg_set_llmnr) { - r = translate("llmnr", arg_ifname, 1, (char **) &arg_set_llmnr, bus); + r = translate("llmnr", arg_ifname, 1, (char **) &arg_set_llmnr); if (r < 0) return r; } if (arg_set_mdns) { - r = translate("mdns", arg_ifname, 1, (char **) &arg_set_mdns, bus); + r = translate("mdns", arg_ifname, 1, (char **) &arg_set_mdns); if (r < 0) return r; } if (arg_set_dns_over_tls) { - r = translate("dnsovertls", arg_ifname, 1, (char **) &arg_set_dns_over_tls, bus); + r = translate("dnsovertls", arg_ifname, 1, (char **) &arg_set_dns_over_tls); if (r < 0) return r; } if (arg_set_dnssec) { - r = translate("dnssec", arg_ifname, 1, (char **) &arg_set_dnssec, bus); + r = translate("dnssec", arg_ifname, 1, (char **) &arg_set_dnssec); if (r < 0) return r; } @@ -4110,7 +4196,7 @@ static int compat_main(int argc, char *argv[], sd_bus *bus) { case MODE_REVERT_LINK: assert(arg_ifname); - return translate("revert", arg_ifname, 0, NULL, bus); + return translate("revert", arg_ifname, 0, NULL); case _MODE_INVALID: assert_not_reached(); @@ -4120,7 +4206,6 @@ static int compat_main(int argc, char *argv[], sd_bus *bus) { } static int run(int argc, char **argv) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; bool compat = false; int r; @@ -4138,16 +4223,10 @@ static int run(int argc, char **argv) { if (r <= 0) return r; - r = sd_bus_open_system(&bus); - if (r < 0) - return log_error_errno(r, "sd_bus_open_system: %m"); - - (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); - if (compat) - return compat_main(argc, argv, bus); + return compat_main(argc, argv); - return native_main(argc, argv, bus); + return native_main(argc, argv); } DEFINE_MAIN_FUNCTION(run); From 302cc03cc87ec8cb5667984baa2fd5456fac5dca Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 09:25:52 +0900 Subject: [PATCH 07/15] sd-varlink: allow to dispatch method again on pending-method-more state Otherwise, polkit authentication does not work for methods that require the MORE flag. --- src/libsystemd/sd-varlink/sd-varlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index 7639f72f89..1369dfbb77 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -1514,7 +1514,7 @@ _public_ int sd_varlink_dispatch_again(sd_varlink *v) { if (v->state == VARLINK_DISCONNECTED) return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (v->state != VARLINK_PENDING_METHOD) + if (!IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection has no pending method."); varlink_set_state(v, VARLINK_IDLE_SERVER); From cf01bbb7a45fb1eec28cd0a813bd68fde413410f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 09:27:46 +0900 Subject: [PATCH 08/15] resolve: support polkit authentication for io.systemd.Resolve.Monitor Then, non-privilege user can call e.g. 'resolvectl monitor' with authentication. --- src/resolve/org.freedesktop.resolve1.policy | 55 +++++++++++++++++++ src/resolve/resolvectl.c | 39 +++++++++++-- src/resolve/resolved-varlink.c | 54 ++++++++++++++---- .../varlink-io.systemd.Resolve.Monitor.c | 8 ++- 4 files changed, 138 insertions(+), 18 deletions(-) diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy index 502b975647..0470cb70c1 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 9cf2a52789..1b9fab3de3 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 f2fbf7a523..3c6d70ae1e 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 36681f5ea0..8c9fb51469 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, From 470cea62daa1d024613b99ffe827e7564e0752d5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 18:06:50 +0900 Subject: [PATCH 09/15] resolve: inherit server userdata No functional change, just refactoring. --- src/resolve/resolved-varlink.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index 3c6d70ae1e..fe0482dffb 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -1241,7 +1241,7 @@ static int verify_polkit(sd_varlink *link, sd_json_variant *parameters, const ch }; int r; - Manager *m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(ASSERT_PTR(link)))); + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); assert(action); @@ -1258,13 +1258,9 @@ static int verify_polkit(sd_varlink *link, sd_json_variant *parameters, const ch } static int vl_method_subscribe_query_results(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { - Manager *m; + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); int r; - assert(link); - - m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); - /* if the client didn't set the more flag, it is using us incorrectly */ if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)) return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL); @@ -1291,7 +1287,7 @@ static int vl_method_subscribe_query_results(sd_varlink *link, sd_json_variant * static int vl_method_dump_cache(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *list = NULL; - Manager *m; + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); int r; assert(link); @@ -1300,8 +1296,6 @@ static int vl_method_dump_cache(sd_varlink *link, sd_json_variant *parameters, s if (r <= 0) return r; - m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); - LIST_FOREACH(scopes, s, m->dns_scopes) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL; @@ -1339,18 +1333,14 @@ static int dns_server_dump_state_to_json_list(DnsServer *server, sd_json_variant static int vl_method_dump_server_state(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *list = NULL; - Manager *m; - int r; + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); Link *l; - - assert(link); + int r; 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))); - LIST_FOREACH(servers, server, m->dns_servers) { r = dns_server_dump_state_to_json_list(server, &list); if (r < 0) @@ -1381,7 +1371,7 @@ static int vl_method_dump_server_state(sd_varlink *link, sd_json_variant *parame static int vl_method_dump_statistics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL; - Manager *m; + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); int r; assert(link); @@ -1390,8 +1380,6 @@ static int vl_method_dump_statistics(sd_varlink *link, sd_json_variant *paramete if (r <= 0) return r; - m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); - r = dns_manager_dump_statistics_json(m, &j); if (r < 0) return r; @@ -1400,17 +1388,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; + Manager *m = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link))); int r; - assert(link); - 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))); - dns_manager_reset_statistics(m); return sd_varlink_replyb(link, SD_JSON_BUILD_EMPTY_OBJECT); @@ -1425,7 +1409,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_ACCOUNT_UID); + r = sd_varlink_server_new(&server, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA); if (r < 0) return log_error_errno(r, "Failed to allocate varlink server object: %m"); From 69e7d2efdfd5b8f8593db73d007e4cdd8c6f1e2c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 19:30:44 +0900 Subject: [PATCH 10/15] timedatectl: enable interactive authentication for DBus methods --- src/timedate/timedatectl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index f9ca15cc81..b430973976 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -1041,6 +1041,8 @@ static int run(int argc, char *argv[]) { if (r < 0) return bus_log_connect_error(r, arg_transport); + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + return timedatectl_main(bus, argc, argv); } From f3cf6167efd12a59bb8204ee28f9f991e6b70877 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 19:33:41 +0900 Subject: [PATCH 11/15] tree-wide: voidify polkit_agent_open_if_enabled() --- src/hostname/hostnamectl.c | 2 +- src/import/importctl.c | 4 ++-- src/locale/localectl.c | 6 +++--- src/login/loginctl.c | 18 +++++++++--------- src/machine/machinectl.c | 28 ++++++++++++++-------------- src/mount/mount-tool.c | 6 +++--- src/run/run.c | 6 +++--- src/systemctl/systemctl-util.c | 2 +- src/timedate/timedatectl.c | 12 ++++++------ 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 157ac769ca..1f98c975fe 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -524,7 +524,7 @@ static int set_simple_string_internal(sd_bus *bus, sd_bus_error *error, const ch _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (!error) error = &e; diff --git a/src/import/importctl.c b/src/import/importctl.c index 30566a1917..27c26a70e8 100644 --- a/src/import/importctl.c +++ b/src/import/importctl.c @@ -179,7 +179,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) { assert(bus); assert(m); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_event_default(&event); if (r < 0) @@ -867,7 +867,7 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 1; i < argc; i++) { uint32_t id; diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 4549359716..9c0c2172aa 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -187,7 +187,7 @@ static int set_locale(int argc, char **argv, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_message_new_method_call(bus, &m, bus_locale, "SetLocale"); if (r < 0) @@ -229,7 +229,7 @@ static int set_vconsole_keymap(int argc, char **argv, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); map = argv[1]; toggle_map = argc > 2 ? argv[2] : ""; @@ -268,7 +268,7 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); layout = argv[1]; model = argc > 2 ? argv[2] : ""; diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 7ca07c4efe..bfe22cd4bb 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1197,7 +1197,7 @@ static int activate(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (argc < 2) { r = sd_bus_call_method( @@ -1240,7 +1240,7 @@ static int kill_session(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (!arg_kill_whom) arg_kill_whom = "all"; @@ -1268,7 +1268,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); b = streq(argv[0], "enable-linger"); @@ -1314,7 +1314,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 1; i < argc; i++) { uid_t uid; @@ -1344,7 +1344,7 @@ static int kill_user(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (!arg_kill_whom) arg_kill_whom = "all"; @@ -1382,7 +1382,7 @@ static int attach(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 2; i < argc; i++) { @@ -1406,7 +1406,7 @@ static int flush_devices(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method(bus, bus_login_mgr, "FlushDevices", &error, NULL, "b", true); if (r < 0) @@ -1422,7 +1422,7 @@ static int lock_sessions(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method( bus, @@ -1443,7 +1443,7 @@ static int terminate_seat(int argc, char *argv[], void *userdata) { assert(argv); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 1; i < argc; i++) { diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index d79282f03f..43b3964a47 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1044,7 +1044,7 @@ static int kill_machine(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (!arg_kill_whom) arg_kill_whom = "all"; @@ -1089,7 +1089,7 @@ static int terminate_machine(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 1; i < argc; i++) { r = bus_call_method(bus, bus_machine_mgr, "TerminateMachine", &error, NULL, "s", argv[i]); @@ -1116,7 +1116,7 @@ static int copy_files(int argc, char *argv[], void *userdata) { bool copy_from; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); copy_from = streq(argv[0], "copy-from"); dest = argv[3] ?: argv[2]; @@ -1167,7 +1167,7 @@ static int bind_mount(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method( bus, @@ -1316,7 +1316,7 @@ static int login_machine(int argc, char *argv[], void *userdata) { return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Login only supported on local machines."); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_event_default(&event); if (r < 0) @@ -1376,7 +1376,7 @@ static int shell_machine(int argc, char *argv[], void *userdata) { } } - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_event_default(&event); if (r < 0) @@ -1595,7 +1595,7 @@ static int remove_image(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (int i = 1; i < argc; i++) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1623,7 +1623,7 @@ static int rename_image(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method( bus, @@ -1644,7 +1644,7 @@ static int clone_image(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_message_new_method_call(bus, &m, bus_machine_mgr, "CloneImage"); if (r < 0) @@ -1675,7 +1675,7 @@ static int read_only_image(int argc, char *argv[], void *userdata) { argv[2]); } - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method(bus, bus_machine_mgr, "MarkImageReadOnly", &error, NULL, "sb", argv[1], b); if (r < 0) @@ -1726,7 +1726,7 @@ static int start_machine(int argc, char *argv[], void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); ask_password_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_wait_for_jobs_new(bus, &w); @@ -1784,7 +1784,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) { int r; bool enable; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); enable = streq(argv[0], "enable"); method = enable ? "EnableUnitFiles" : "DisableUnitFiles"; @@ -1878,7 +1878,7 @@ static int set_limit(int argc, char *argv[], void *userdata) { uint64_t limit; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); if (STR_IN_SET(argv[argc-1], "-", "none", "infinity")) limit = UINT64_MAX; @@ -1911,7 +1911,7 @@ static int clean_images(int argc, char *argv[], void *userdata) { unsigned c = 0; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_message_new_method_call(bus, &m, bus_machine_mgr, "CleanPool"); if (r < 0) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index d43db8ffd1..fb9e3b3a14 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -665,7 +665,7 @@ static int start_transient_mount( if (r < 0) return bus_log_create_error(r); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) @@ -774,7 +774,7 @@ static int start_transient_automount( if (r < 0) return bus_log_create_error(r); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) @@ -932,7 +932,7 @@ static int stop_mount( if (r < 0) return bus_log_create_error(r); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { diff --git a/src/run/run.c b/src/run/run.c index 2db60e6bb8..30fccfb47e 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1823,7 +1823,7 @@ static int start_transient_service(sd_bus *bus) { return r; slave = safe_close(slave); - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_with_hint(bus, m, "service", &reply); if (r < 0) @@ -2037,7 +2037,7 @@ static int start_transient_scope(sd_bus *bus) { return r; } - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); for (;;) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2352,7 +2352,7 @@ static int start_transient_trigger(sd_bus *bus, const char *suffix) { if (r < 0) return r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_with_hint(bus, m, suffix + 1, &reply); if (r < 0) diff --git a/src/systemctl/systemctl-util.c b/src/systemctl/systemctl-util.c index a3101911cd..f00b2d0022 100644 --- a/src/systemctl/systemctl-util.c +++ b/src/systemctl/systemctl-util.c @@ -86,7 +86,7 @@ void polkit_agent_open_maybe(void) { if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM) return; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); } int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) { diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index b430973976..ac5576a98b 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -218,7 +218,7 @@ static int set_time(int argc, char **argv, void *userdata) { usec_t t; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = parse_timestamp(argv[1], &t); if (r < 0) @@ -242,7 +242,7 @@ static int set_timezone(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; int r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method(bus, bus_timedate, "SetTimezone", &error, NULL, "sb", argv[1], arg_ask_password); if (r < 0) @@ -256,7 +256,7 @@ static int set_local_rtc(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; int r, b; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); b = parse_boolean(argv[1]); if (b < 0) @@ -288,7 +288,7 @@ static int set_ntp(int argc, char **argv, void *userdata) { sd_bus *bus = userdata; int b, r; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); b = parse_boolean(argv[1]); if (b < 0) @@ -821,7 +821,7 @@ static int verb_ntp_servers(int argc, char **argv, void *userdata) { if (ifindex < 0) return ifindex; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_message_new_method_call(bus, &req, bus_network_mgr, "SetLinkNTP"); if (r < 0) @@ -851,7 +851,7 @@ static int verb_revert(int argc, char **argv, void *userdata) { if (ifindex < 0) return ifindex; - polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); r = bus_call_method(bus, bus_network_mgr, "RevertLinkNTP", &error, NULL, "i", ifindex); if (r < 0) From 335608593c9a49a0a31cfa2410afc177e90880a8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 19:34:09 +0900 Subject: [PATCH 12/15] timedatectl: drop unnecessary temporal variables Also drop unnecessary spaces. --- src/timedate/timedatectl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index ac5576a98b..1a1371030a 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -213,7 +213,6 @@ static int show_properties(int argc, char **argv, void *userdata) { static int set_time(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - bool relative = false, interactive = arg_ask_password; sd_bus *bus = userdata; usec_t t; int r; @@ -230,7 +229,7 @@ static int set_time(int argc, char **argv, void *userdata) { "SetTime", &error, NULL, - "xbb", (int64_t) t, relative, interactive); + "xbb", (int64_t) t, false, arg_ask_password); if (r < 0) return log_error_errno(r, "Failed to set time: %s", bus_error_message(&error, r)); @@ -297,7 +296,7 @@ static int set_ntp(int argc, char **argv, void *userdata) { r = bus_message_new_method_call(bus, &m, bus_timedate, "SetNTP"); if (r < 0) return bus_log_create_error(r); - + r = sd_bus_message_append(m, "bb", b, arg_ask_password); if (r < 0) return bus_log_create_error(r); From 04834552edbe807ede4c54f1764dd7fefb884f24 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 19:58:45 +0900 Subject: [PATCH 13/15] mount: use sd_bus_set_allow_interactive_authorization() --- src/mount/mount-tool.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index fb9e3b3a14..278890dd69 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -638,10 +638,6 @@ static int start_transient_mount( if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and mode */ r = sd_bus_message_append(m, "ss", mount_unit, "fail"); if (r < 0) @@ -719,10 +715,6 @@ static int start_transient_automount( if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and mode */ r = sd_bus_message_append(m, "ss", automount_unit, "fail"); if (r < 0) @@ -923,10 +915,6 @@ static int stop_mount( if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and mode */ r = sd_bus_message_append(m, "ss", mount_unit, "fail"); if (r < 0) @@ -1527,6 +1515,8 @@ static int run(int argc, char* argv[]) { if (r < 0) return bus_log_connect_error(r, arg_transport); + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + if (arg_action == ACTION_UMOUNT) return action_umount(bus, argc, argv); From 1b8a74678c7259ad370c4871221272eb11147253 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 19:59:30 +0900 Subject: [PATCH 14/15] run: use sd_bus_set_allow_interactive_authorization() --- src/run/run.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/run/run.c b/src/run/run.c index 30fccfb47e..f2f94c5dfd 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1562,10 +1562,6 @@ static int make_transient_service_unit( if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and mode */ r = sd_bus_message_append(m, "ss", service, "fail"); if (r < 0) @@ -2047,10 +2043,6 @@ static int start_transient_scope(sd_bus *bus) { if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and Mode */ r = sd_bus_message_append(m, "ss", scope, "fail"); if (r < 0) @@ -2219,10 +2211,6 @@ static int make_transient_trigger_unit( if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); - if (r < 0) - return bus_log_create_error(r); - /* Name and Mode */ r = sd_bus_message_append(m, "ss", trigger, "fail"); if (r < 0) @@ -2453,6 +2441,8 @@ static int run(int argc, char* argv[]) { if (r < 0) return bus_log_connect_error(r, arg_transport); + (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + if (arg_scope) return start_transient_scope(bus); if (arg_path_property) From cc3e48b3c1c5d878ce7ea78eb4f3b6fa2a685450 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 20:00:25 +0900 Subject: [PATCH 15/15] run: also enable interactive authentication on opening pty --- src/run/run.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/run/run.c b/src/run/run.c index f2f94c5dfd..fb800758b3 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1730,6 +1730,8 @@ static int start_transient_service(sd_bus *bus) { assert(bus); + (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + if (arg_stdio == ARG_STDIO_PTY) { if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_CAPSULE)) { @@ -1765,6 +1767,8 @@ static int start_transient_service(sd_bus *bus) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); + (void) sd_bus_set_allow_interactive_authorization(system_bus, arg_ask_password); + r = bus_call_method(system_bus, bus_machine_mgr, "OpenMachinePTY", @@ -1819,8 +1823,6 @@ static int start_transient_service(sd_bus *bus) { return r; slave = safe_close(slave); - (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); - r = bus_call_with_hint(bus, m, "service", &reply); if (r < 0) return r;