]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-bus.c
treewide: yet more log_*_errno + return simplifications
[thirdparty/systemd.git] / src / resolve / resolved-bus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "bus-errors.h"
23 #include "bus-util.h"
24
25 #include "resolved-dns-domain.h"
26 #include "resolved-bus.h"
27 #include "resolved-def.h"
28
29 static int reply_query_state(DnsQuery *q) {
30 _cleanup_free_ char *ip = NULL;
31 const char *name;
32 int r;
33
34 if (q->request_hostname)
35 name = q->request_hostname;
36 else {
37 r = in_addr_to_string(q->request_family, &q->request_address, &ip);
38 if (r < 0)
39 return r;
40
41 name = ip;
42 }
43
44 switch (q->state) {
45
46 case DNS_TRANSACTION_NO_SERVERS:
47 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
48
49 case DNS_TRANSACTION_TIMEOUT:
50 return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
51
52 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
53 return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
54
55 case DNS_TRANSACTION_INVALID_REPLY:
56 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
57
58 case DNS_TRANSACTION_RESOURCES:
59 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
60
61 case DNS_TRANSACTION_ABORTED:
62 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
63
64 case DNS_TRANSACTION_FAILURE: {
65 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
66
67 if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
68 sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
69 else {
70 const char *rc, *n;
71 char p[3]; /* the rcode is 4 bits long */
72
73 rc = dns_rcode_to_string(q->answer_rcode);
74 if (!rc) {
75 sprintf(p, "%i", q->answer_rcode);
76 rc = p;
77 }
78
79 n = strappenda(_BUS_ERROR_DNS, rc);
80 sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
81 }
82
83 return sd_bus_reply_method_error(q->request, &error);
84 }
85
86 case DNS_TRANSACTION_NULL:
87 case DNS_TRANSACTION_PENDING:
88 case DNS_TRANSACTION_SUCCESS:
89 default:
90 assert_not_reached("Impossible state");
91 }
92 }
93
94 static int append_address(sd_bus_message *reply, DnsResourceRecord *rr) {
95 int r;
96
97 assert(reply);
98 assert(rr);
99
100 r = sd_bus_message_open_container(reply, 'r', "iay");
101 if (r < 0)
102 return r;
103
104 if (rr->key->type == DNS_TYPE_A) {
105 r = sd_bus_message_append(reply, "i", AF_INET);
106 if (r < 0)
107 return r;
108
109 r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
110
111 } else if (rr->key->type == DNS_TYPE_AAAA) {
112 r = sd_bus_message_append(reply, "i", AF_INET6);
113 if (r < 0)
114 return r;
115
116 r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
117 } else
118 return -EAFNOSUPPORT;
119
120 if (r < 0)
121 return r;
122
123 r = sd_bus_message_close_container(reply);
124 if (r < 0)
125 return r;
126
127 return 0;
128 }
129
130 static void bus_method_resolve_hostname_complete(DnsQuery *q) {
131 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL;
132 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
133 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
134 unsigned added = 0, i;
135 int r;
136
137 assert(q);
138
139 if (q->state != DNS_TRANSACTION_SUCCESS) {
140 r = reply_query_state(q);
141 goto finish;
142 }
143
144 r = sd_bus_message_new_method_return(q->request, &reply);
145 if (r < 0)
146 goto finish;
147
148 r = sd_bus_message_append(reply, "i", q->answer_ifindex);
149 if (r < 0)
150 goto finish;
151
152 r = sd_bus_message_open_container(reply, 'a', "(iay)");
153 if (r < 0)
154 goto finish;
155
156 if (q->answer) {
157 answer = dns_answer_ref(q->answer);
158
159 for (i = 0; i < answer->n_rrs; i++) {
160 r = dns_question_matches_rr(q->question, answer->rrs[i]);
161 if (r < 0)
162 goto finish;
163 if (r == 0) {
164 /* Hmm, if this is not an address record,
165 maybe it's a cname? If so, remember this */
166 r = dns_question_matches_cname(q->question, answer->rrs[i]);
167 if (r < 0)
168 goto finish;
169 if (r > 0)
170 cname = dns_resource_record_ref(answer->rrs[i]);
171
172 continue;
173 }
174
175 r = append_address(reply, answer->rrs[i]);
176 if (r < 0)
177 goto finish;
178
179 if (!canonical)
180 canonical = dns_resource_record_ref(answer->rrs[i]);
181
182 added ++;
183 }
184 }
185
186 if (added <= 0) {
187 if (!cname) {
188 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname);
189 goto finish;
190 }
191
192 /* This has a cname? Then update the query with the
193 * new cname. */
194 r = dns_query_cname_redirect(q, cname->cname.name);
195 if (r < 0) {
196 if (r == -ELOOP)
197 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
198 else
199 r = sd_bus_reply_method_errno(q->request, -r, NULL);
200
201 goto finish;
202 }
203
204 /* Before we restart the query, let's see if any of
205 * the RRs we already got already answers our query */
206 for (i = 0; i < answer->n_rrs; i++) {
207 r = dns_question_matches_rr(q->question, answer->rrs[i]);
208 if (r < 0)
209 goto finish;
210 if (r == 0)
211 continue;
212
213 r = append_address(reply, answer->rrs[i]);
214 if (r < 0)
215 goto finish;
216
217 if (!canonical)
218 canonical = dns_resource_record_ref(answer->rrs[i]);
219
220 added++;
221 }
222
223 /* If we didn't find anything, then let's restart the
224 * query, this time with the cname */
225 if (added <= 0) {
226 r = dns_query_go(q);
227 if (r == -ESRCH) {
228 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
229 goto finish;
230 }
231 if (r < 0) {
232 r = sd_bus_reply_method_errno(q->request, -r, NULL);
233 goto finish;
234 }
235
236 return;
237 }
238 }
239
240 r = sd_bus_message_close_container(reply);
241 if (r < 0)
242 goto finish;
243
244 /* Return the precise spelling and uppercasing reported by the server */
245 assert(canonical);
246 r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
247 if (r < 0)
248 goto finish;
249
250 r = sd_bus_send(q->manager->bus, reply, NULL);
251
252 finish:
253 if (r < 0) {
254 log_error_errno(r, "Failed to send hostname reply: %m");
255 sd_bus_reply_method_errno(q->request, -r, NULL);
256 }
257
258 dns_query_free(q);
259 }
260
261 static int check_ifindex_flags(int ifindex, uint64_t *flags, sd_bus_error *error) {
262 assert(flags);
263
264 if (ifindex < 0)
265 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
266
267 if (*flags & ~SD_RESOLVED_FLAGS_ALL)
268 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
269
270 if (*flags == 0)
271 *flags = SD_RESOLVED_FLAGS_DEFAULT;
272
273 return 0;
274 }
275
276 static int bus_method_resolve_hostname(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
277 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
278 Manager *m = userdata;
279 const char *hostname;
280 int family, ifindex;
281 uint64_t flags;
282 DnsQuery *q;
283 int r;
284
285 assert(bus);
286 assert(message);
287 assert(m);
288
289 r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
290 if (r < 0)
291 return r;
292
293 if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
294 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
295
296 r = dns_name_normalize(hostname, NULL);
297 if (r < 0)
298 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
299
300 r = check_ifindex_flags(ifindex, &flags, error);
301 if (r < 0)
302 return r;
303
304 question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
305 if (!question)
306 return -ENOMEM;
307
308 if (family != AF_INET6) {
309 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
310
311 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, hostname);
312 if (!key)
313 return -ENOMEM;
314
315 r = dns_question_add(question, key);
316 if (r < 0)
317 return r;
318 }
319
320 if (family != AF_INET) {
321 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
322
323 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, hostname);
324 if (!key)
325 return -ENOMEM;
326
327 r = dns_question_add(question, key);
328 if (r < 0)
329 return r;
330 }
331
332 r = dns_query_new(m, &q, question, ifindex, flags);
333 if (r < 0)
334 return r;
335
336 q->request = sd_bus_message_ref(message);
337 q->request_family = family;
338 q->request_hostname = hostname;
339 q->complete = bus_method_resolve_hostname_complete;
340
341 r = dns_query_bus_track(q, bus, message);
342 if (r < 0)
343 return r;
344
345 r = dns_query_go(q);
346 if (r < 0) {
347 dns_query_free(q);
348
349 if (r == -ESRCH)
350 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
351
352 return r;
353 }
354
355 return 1;
356 }
357
358 static void bus_method_resolve_address_complete(DnsQuery *q) {
359 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
360 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
361 unsigned added = 0, i;
362 int r;
363
364 assert(q);
365
366 if (q->state != DNS_TRANSACTION_SUCCESS) {
367 r = reply_query_state(q);
368 goto finish;
369 }
370
371 r = sd_bus_message_new_method_return(q->request, &reply);
372 if (r < 0)
373 goto finish;
374
375 r = sd_bus_message_append(reply, "i", q->answer_ifindex);
376 if (r < 0)
377 goto finish;
378
379 r = sd_bus_message_open_container(reply, 'a', "s");
380 if (r < 0)
381 goto finish;
382
383 if (q->answer) {
384 answer = dns_answer_ref(q->answer);
385
386 for (i = 0; i < answer->n_rrs; i++) {
387 r = dns_question_matches_rr(q->question, answer->rrs[i]);
388 if (r < 0)
389 goto finish;
390 if (r == 0)
391 continue;
392
393 r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name);
394 if (r < 0)
395 goto finish;
396
397 added ++;
398 }
399 }
400
401 if (added <= 0) {
402 _cleanup_free_ char *ip = NULL;
403
404 in_addr_to_string(q->request_family, &q->request_address, &ip);
405
406 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
407 goto finish;
408 }
409
410 r = sd_bus_message_close_container(reply);
411 if (r < 0)
412 goto finish;
413
414 r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
415 if (r < 0)
416 goto finish;
417
418 r = sd_bus_send(q->manager->bus, reply, NULL);
419
420 finish:
421 if (r < 0) {
422 log_error_errno(r, "Failed to send address reply: %m");
423 sd_bus_reply_method_errno(q->request, -r, NULL);
424 }
425
426 dns_query_free(q);
427 }
428
429 static int bus_method_resolve_address(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
430 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
431 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
432 _cleanup_free_ char *reverse = NULL;
433 Manager *m = userdata;
434 int family, ifindex;
435 uint64_t flags;
436 const void *d;
437 DnsQuery *q;
438 size_t sz;
439 int r;
440
441 assert(bus);
442 assert(message);
443 assert(m);
444
445 r = sd_bus_message_read(message, "ii", &ifindex, &family);
446 if (r < 0)
447 return r;
448
449 if (!IN_SET(family, AF_INET, AF_INET6))
450 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
451
452 r = sd_bus_message_read_array(message, 'y', &d, &sz);
453 if (r < 0)
454 return r;
455
456 if (sz != FAMILY_ADDRESS_SIZE(family))
457 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
458
459 r = sd_bus_message_read(message, "t", &flags);
460 if (r < 0)
461 return r;
462
463 r = check_ifindex_flags(ifindex, &flags, error);
464 if (r < 0)
465 return r;
466
467 r = dns_name_reverse(family, d, &reverse);
468 if (r < 0)
469 return r;
470
471 question = dns_question_new(1);
472 if (!question)
473 return -ENOMEM;
474
475 key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse);
476 if (!key)
477 return -ENOMEM;
478
479 reverse = NULL;
480
481 r = dns_question_add(question, key);
482 if (r < 0)
483 return r;
484
485 r = dns_query_new(m, &q, question, ifindex, flags);
486 if (r < 0)
487 return r;
488
489 q->request = sd_bus_message_ref(message);
490 q->request_family = family;
491 memcpy(&q->request_address, d, sz);
492 q->complete = bus_method_resolve_address_complete;
493
494 r = dns_query_bus_track(q, bus, message);
495 if (r < 0)
496 return r;
497
498 r = dns_query_go(q);
499 if (r < 0) {
500 dns_query_free(q);
501
502 if (r == -ESRCH)
503 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
504
505 return r;
506 }
507
508 return 1;
509 }
510
511 static void bus_method_resolve_record_complete(DnsQuery *q) {
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
513 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
514 unsigned added = 0, i;
515 int r;
516
517 assert(q);
518
519 if (q->state != DNS_TRANSACTION_SUCCESS) {
520 r = reply_query_state(q);
521 goto finish;
522 }
523
524 r = sd_bus_message_new_method_return(q->request, &reply);
525 if (r < 0)
526 goto finish;
527
528 r = sd_bus_message_append(reply, "i", q->answer_ifindex);
529 if (r < 0)
530 goto finish;
531
532 r = sd_bus_message_open_container(reply, 'a', "(qqay)");
533 if (r < 0)
534 goto finish;
535
536 if (q->answer) {
537 answer = dns_answer_ref(q->answer);
538
539 for (i = 0; i < answer->n_rrs; i++) {
540 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
541 size_t start;
542
543 r = dns_question_matches_rr(q->question, answer->rrs[i]);
544 if (r < 0)
545 goto finish;
546 if (r == 0)
547 continue;
548
549 r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
550 if (r < 0)
551 goto finish;
552
553 r = dns_packet_append_rr(p, answer->rrs[i], &start);
554 if (r < 0)
555 goto finish;
556
557 r = sd_bus_message_open_container(reply, 'r', "qqay");
558 if (r < 0)
559 goto finish;
560
561 r = sd_bus_message_append(reply, "qq", answer->rrs[i]->key->class, answer->rrs[i]->key->type);
562 if (r < 0)
563 goto finish;
564
565 r = sd_bus_message_append_array(reply, 'y', DNS_PACKET_DATA(p) + start, p->size - start);
566 if (r < 0)
567 goto finish;
568
569 r = sd_bus_message_close_container(reply);
570 if (r < 0)
571 goto finish;
572
573 added ++;
574 }
575 }
576
577 if (added <= 0) {
578 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", q->request_hostname);
579 goto finish;
580 }
581
582 r = sd_bus_message_close_container(reply);
583 if (r < 0)
584 goto finish;
585
586 r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
587 if (r < 0)
588 goto finish;
589
590 r = sd_bus_send(q->manager->bus, reply, NULL);
591
592 finish:
593 if (r < 0) {
594 log_error_errno(r, "Failed to send record reply: %m");
595 sd_bus_reply_method_errno(q->request, -r, NULL);
596 }
597
598 dns_query_free(q);
599 }
600
601 static int bus_method_resolve_record(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
602 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
603 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
604 Manager *m = userdata;
605 uint16_t class, type;
606 const char *name;
607 int r, ifindex;
608 uint64_t flags;
609 DnsQuery *q;
610
611 assert(bus);
612 assert(message);
613 assert(m);
614
615 r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
616 if (r < 0)
617 return r;
618
619 r = dns_name_normalize(name, NULL);
620 if (r < 0)
621 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
622
623 r = check_ifindex_flags(ifindex, &flags, error);
624 if (r < 0)
625 return r;
626
627 question = dns_question_new(1);
628 if (!question)
629 return -ENOMEM;
630
631 key = dns_resource_key_new(class, type, name);
632 if (!key)
633 return -ENOMEM;
634
635 r = dns_question_add(question, key);
636 if (r < 0)
637 return r;
638
639 r = dns_query_new(m, &q, question, ifindex, flags);
640 if (r < 0)
641 return r;
642
643 q->request = sd_bus_message_ref(message);
644 q->request_hostname = name;
645 q->complete = bus_method_resolve_record_complete;
646
647 r = dns_query_bus_track(q, bus, message);
648 if (r < 0)
649 return r;
650
651 r = dns_query_go(q);
652 if (r < 0) {
653 dns_query_free(q);
654
655 if (r == -ESRCH)
656 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
657
658 return r;
659 }
660
661 return 1;
662 }
663
664 static const sd_bus_vtable resolve_vtable[] = {
665 SD_BUS_VTABLE_START(0),
666 SD_BUS_METHOD("ResolveHostname", "isit", "ia(iay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
667 SD_BUS_METHOD("ResolveAddress", "iiayt", "iast", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
668 SD_BUS_METHOD("ResolveRecord", "isqqt", "ia(qqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
669 SD_BUS_VTABLE_END,
670 };
671
672 static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
673 Manager *m = userdata;
674
675 assert(s);
676 assert(m);
677
678 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
679
680 manager_connect_bus(m);
681 return 0;
682 }
683
684 static int match_prepare_for_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
685 Manager *m = userdata;
686 int b, r;
687
688 assert(bus);
689 assert(bus);
690
691 r = sd_bus_message_read(message, "b", &b);
692 if (r < 0) {
693 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
694 return 0;
695 }
696
697 if (b)
698 return 0;
699
700 log_debug("Coming back from suspend, verifying all RRs...");
701
702 manager_verify_all(m);
703 return 0;
704 }
705
706 int manager_connect_bus(Manager *m) {
707 int r;
708
709 assert(m);
710
711 if (m->bus)
712 return 0;
713
714 r = sd_bus_default_system(&m->bus);
715 if (r < 0) {
716 /* We failed to connect? Yuck, we must be in early
717 * boot. Let's try in 5s again. As soon as we have
718 * kdbus we can stop doing this... */
719
720 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
721
722 r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
723 if (r < 0)
724 return log_error_errno(r, "Failed to install bus reconnect time event: %m");
725
726 return 0;
727 }
728
729 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
730 if (r < 0)
731 return log_error_errno(r, "Failed to register object: %m");
732
733 r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
734 if (r < 0)
735 return log_error_errno(r, "Failed to register name: %m");
736
737 r = sd_bus_attach_event(m->bus, m->event, 0);
738 if (r < 0)
739 return log_error_errno(r, "Failed to attach bus to event loop: %m");
740
741 r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
742 "type='signal',"
743 "sender='org.freedesktop.login1',"
744 "interface='org.freedesktop.login1.Manager',"
745 "member='PrepareForSleep',"
746 "path='/org/freedesktop/login1'",
747 match_prepare_for_sleep,
748 m);
749 if (r < 0)
750 log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
751
752 return 0;
753 }