From: Dmitry Rozhkov Date: Wed, 22 Nov 2017 14:49:23 +0000 (+0200) Subject: resolved: consult Polkit for privileges when manipulating DNS-SD X-Git-Tag: v236~33^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84b0f133e4a753552295a35a5fd86aeceac19e0a;p=thirdparty%2Fsystemd.git resolved: consult Polkit for privileges when manipulating DNS-SD --- diff --git a/src/resolve/meson.build b/src/resolve/meson.build index b01c46cf650..ee1acb51669 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -165,6 +165,15 @@ if conf.get('ENABLE_RESOLVE') == 1 install_data('resolv.conf', install_dir : rootlibexecdir) + + i18n.merge_file( + 'org.freedesktop.resolve1.policy', + input : 'org.freedesktop.resolve1.policy.in', + output : 'org.freedesktop.resolve1.policy', + po_dir : po_dir, + data_dirs : po_dir, + install : install_polkit, + install_dir : polkitpolicydir) endif tests += [ diff --git a/src/resolve/org.freedesktop.resolve1.policy.in b/src/resolve/org.freedesktop.resolve1.policy.in new file mode 100644 index 00000000000..da948eb0b7a --- /dev/null +++ b/src/resolve/org.freedesktop.resolve1.policy.in @@ -0,0 +1,43 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + Register a DNS-SD service + Authentication is required to register a DNS-SD service + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + + Unregister a DNS-SD service + Authentication is required to unregister a DNS-SD service + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-resolve + + + diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index bcfe434e408..70609364146 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -28,6 +28,7 @@ #include "resolved-dnssd.h" #include "resolved-dnssd-bus.h" #include "resolved-link-bus.h" +#include "user-util.h" #include "utf8.h" static int reply_query_state(DnsQuery *q) { @@ -1597,6 +1598,7 @@ static int on_bus_track(sd_bus_track *t, void *userdata) { } static int bus_method_register_service(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; _cleanup_(dnssd_service_freep) DnssdService *service = NULL; _cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL; _cleanup_free_ char *path = NULL; @@ -1607,6 +1609,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, const char *name; const char *name_template; const char *type; + uid_t euid; int r; assert(message); @@ -1615,10 +1618,28 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, if (m->mdns_support != RESOLVE_SUPPORT_YES) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled"); + r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, + "org.freedesktop.resolve1.register-service", + NULL, false, UID_INVALID, + &m->polkit_registry, error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Polkit will call us back */ + service = new0(DnssdService, 1); if (!service) return log_oom(); + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_euid(creds, &euid); + if (r < 0) + return r; + service->originator = euid; + r = sd_bus_message_read(message, "sssqqq", &name, &name_template, &type, &service->port, &service->priority, &service->weight); @@ -1783,8 +1804,8 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0), SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0), - SD_BUS_METHOD("RegisterService", "sssqqqa{say}", "o", bus_method_register_service, 0), - SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, 0), + SD_BUS_METHOD("RegisterService", "sssqqqa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END, }; diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c index 7a9f0bccbb1..e45daabd23e 100644 --- a/src/resolve/resolved-dnssd-bus.c +++ b/src/resolve/resolved-dnssd-bus.c @@ -18,10 +18,12 @@ ***/ #include "alloc-util.h" +#include "bus-util.h" #include "resolved-dnssd.h" #include "resolved-dnssd-bus.h" #include "resolved-link.h" #include "strv.h" +#include "user-util.h" int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error) { DnssdService *s = userdata; @@ -35,6 +37,15 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_ m = s->manager; + r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, + "org.freedesktop.resolve1.unregister-service", + NULL, false, s->originator, + &m->polkit_registry, error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Polkit will call us back */ + HASHMAP_FOREACH(l, m->links, i) { if (l->mdns_ipv4_scope) { r = dns_scope_announce(l->mdns_ipv4_scope, true); @@ -67,7 +78,7 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_ const sd_bus_vtable dnssd_vtable[] = { SD_BUS_VTABLE_START(0), - SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, 0), + SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_SIGNAL("Conflicted", NULL, 0), SD_BUS_VTABLE_END diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h index 4040190cf4c..6c4dd61a772 100644 --- a/src/resolve/resolved-dnssd.h +++ b/src/resolve/resolved-dnssd.h @@ -47,6 +47,7 @@ struct DnssdService { Manager *manager; bool withdrawn:1; + uid_t originator; }; DnssdService *dnssd_service_free(DnssdService *service); diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index d9647429216..5c1a6670ef0 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -146,6 +146,8 @@ struct Manager { sd_event_source *dns_stub_udp_event_source; sd_event_source *dns_stub_tcp_event_source; + + Hashmap *polkit_registry; }; /* Manager */