1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "bus-polkit.h"
5 #include "missing_capability.h"
6 #include "resolved-dnssd-bus.h"
7 #include "resolved-dnssd.h"
8 #include "resolved-link.h"
9 #include "resolved-manager.h"
11 #include "user-util.h"
13 int bus_dnssd_method_unregister(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
14 DnssdService
*s
= userdata
;
15 DnssdTxtData
*txt_data
;
26 r
= bus_verify_polkit_async(message
, CAP_SYS_ADMIN
,
27 "org.freedesktop.resolve1.unregister-service",
28 NULL
, false, s
->originator
,
29 &m
->polkit_registry
, error
);
33 return 1; /* Polkit will call us back */
35 HASHMAP_FOREACH(l
, m
->links
, i
) {
36 if (l
->mdns_ipv4_scope
) {
37 r
= dns_scope_announce(l
->mdns_ipv4_scope
, true);
39 log_warning_errno(r
, "Failed to send goodbye messages in IPv4 scope: %m");
41 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, s
->ptr_rr
);
42 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, s
->srv_rr
);
43 LIST_FOREACH(items
, txt_data
, s
->txt_data_items
)
44 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, txt_data
->rr
);
47 if (l
->mdns_ipv6_scope
) {
48 r
= dns_scope_announce(l
->mdns_ipv6_scope
, true);
50 log_warning_errno(r
, "Failed to send goodbye messages in IPv6 scope: %m");
52 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, s
->ptr_rr
);
53 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, s
->srv_rr
);
54 LIST_FOREACH(items
, txt_data
, s
->txt_data_items
)
55 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, txt_data
->rr
);
59 dnssd_service_free(s
);
61 manager_refresh_rrs(m
);
63 return sd_bus_reply_method_return(message
, NULL
);
66 static int dnssd_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
67 _cleanup_free_
char *name
= NULL
;
68 Manager
*m
= userdata
;
69 DnssdService
*service
;
78 r
= sd_bus_path_decode(path
, "/org/freedesktop/resolve1/dnssd", &name
);
82 service
= hashmap_get(m
->dnssd_services
, name
);
90 static int dnssd_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
91 _cleanup_strv_free_
char **l
= NULL
;
92 Manager
*m
= userdata
;
93 DnssdService
*service
;
103 l
= new0(char*, hashmap_size(m
->dnssd_services
) + 1);
107 HASHMAP_FOREACH(service
, m
->dnssd_services
, i
) {
110 r
= sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service
->name
, &p
);
118 *nodes
= TAKE_PTR(l
);
123 static const sd_bus_vtable dnssd_vtable
[] = {
124 SD_BUS_VTABLE_START(0),
126 SD_BUS_METHOD("Unregister", NULL
, NULL
, bus_dnssd_method_unregister
, SD_BUS_VTABLE_UNPRIVILEGED
),
127 SD_BUS_SIGNAL("Conflicted", NULL
, 0),
132 const BusObjectImplementation dnssd_object
= {
133 "/org/freedesktop/resolve1/dnssd",
134 "org.freedesktop.resolve1.DnssdService",
135 .fallback_vtables
= BUS_FALLBACK_VTABLES({dnssd_vtable
, dnssd_object_find
}),
136 .node_enumerator
= dnssd_node_enumerator
,