1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
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
= ASSERT_PTR(userdata
);
23 r
= bus_verify_polkit_async_full(
25 "org.freedesktop.resolve1.unregister-service",
27 /* interactive= */ false,
28 /* good_user= */ s
->originator
,
34 return 1; /* Polkit will call us back */
36 HASHMAP_FOREACH(l
, m
->links
) {
37 if (l
->mdns_ipv4_scope
) {
38 r
= dns_scope_announce(l
->mdns_ipv4_scope
, true);
40 log_warning_errno(r
, "Failed to send goodbye messages in IPv4 scope: %m");
42 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, s
->ptr_rr
);
43 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, s
->srv_rr
);
44 LIST_FOREACH(items
, txt_data
, s
->txt_data_items
)
45 dns_zone_remove_rr(&l
->mdns_ipv4_scope
->zone
, txt_data
->rr
);
48 if (l
->mdns_ipv6_scope
) {
49 r
= dns_scope_announce(l
->mdns_ipv6_scope
, true);
51 log_warning_errno(r
, "Failed to send goodbye messages in IPv6 scope: %m");
53 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, s
->ptr_rr
);
54 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, s
->srv_rr
);
55 LIST_FOREACH(items
, txt_data
, s
->txt_data_items
)
56 dns_zone_remove_rr(&l
->mdns_ipv6_scope
->zone
, txt_data
->rr
);
60 dnssd_service_free(s
);
62 manager_refresh_rrs(m
);
64 return sd_bus_reply_method_return(message
, NULL
);
67 static int dnssd_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
68 _cleanup_free_
char *name
= NULL
;
69 Manager
*m
= ASSERT_PTR(userdata
);
70 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
= ASSERT_PTR(userdata
);
93 DnssdService
*service
;
101 l
= new0(char*, hashmap_size(m
->dnssd_services
) + 1);
105 HASHMAP_FOREACH(service
, m
->dnssd_services
) {
108 r
= sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service
->name
, &p
);
116 *nodes
= TAKE_PTR(l
);
121 static const sd_bus_vtable dnssd_vtable
[] = {
122 SD_BUS_VTABLE_START(0),
124 SD_BUS_METHOD("Unregister", NULL
, NULL
, bus_dnssd_method_unregister
, SD_BUS_VTABLE_UNPRIVILEGED
),
125 SD_BUS_SIGNAL("Conflicted", NULL
, 0),
130 const BusObjectImplementation dnssd_object
= {
131 "/org/freedesktop/resolve1/dnssd",
132 "org.freedesktop.resolve1.DnssdService",
133 .fallback_vtables
= BUS_FALLBACK_VTABLES({dnssd_vtable
, dnssd_object_find
}),
134 .node_enumerator
= dnssd_node_enumerator
,