]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-bus.c
Merge pull request #6 from xnox/drop-name
[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-common-errors.h"
23 #include "bus-util.h"
24
25 #include "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 = strjoina(_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 // what about the cache?
224
225 /* If we didn't find anything, then let's restart the
226 * query, this time with the cname */
227 if (added <= 0) {
228 r = dns_query_go(q);
229 if (r == -ESRCH) {
230 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
231 goto finish;
232 }
233 if (r < 0) {
234 r = sd_bus_reply_method_errno(q->request, -r, NULL);
235 goto finish;
236 }
237
238 return;
239 }
240 }
241
242 r = sd_bus_message_close_container(reply);
243 if (r < 0)
244 goto finish;
245
246 /* Return the precise spelling and uppercasing reported by the server */
247 assert(canonical);
248 r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
249 if (r < 0)
250 goto finish;
251
252 r = sd_bus_send(q->manager->bus, reply, NULL);
253
254 finish:
255 if (r < 0) {
256 log_error_errno(r, "Failed to send hostname reply: %m");
257 sd_bus_reply_method_errno(q->request, -r, NULL);
258 }
259
260 dns_query_free(q);
261 }
262
263 static int check_ifindex_flags(int ifindex, uint64_t *flags, sd_bus_error *error) {
264 assert(flags);
265
266 if (ifindex < 0)
267 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
268
269 if (*flags & ~SD_RESOLVED_FLAGS_ALL)
270 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
271
272 if (*flags == 0)
273 *flags = SD_RESOLVED_FLAGS_DEFAULT;
274
275 return 0;
276 }
277
278 static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
279 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
280 Manager *m = userdata;
281 const char *hostname;
282 int family, ifindex;
283 uint64_t flags;
284 DnsQuery *q;
285 int r;
286
287 assert(message);
288 assert(m);
289
290 r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
291 if (r < 0)
292 return r;
293
294 if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
295 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
296
297 r = dns_name_normalize(hostname, NULL);
298 if (r < 0)
299 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
300
301 r = check_ifindex_flags(ifindex, &flags, error);
302 if (r < 0)
303 return r;
304
305 question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
306 if (!question)
307 return -ENOMEM;
308
309 if (family != AF_INET6) {
310 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
311
312 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, hostname);
313 if (!key)
314 return -ENOMEM;
315
316 r = dns_question_add(question, key);
317 if (r < 0)
318 return r;
319 }
320
321 if (family != AF_INET) {
322 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
323
324 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, hostname);
325 if (!key)
326 return -ENOMEM;
327
328 r = dns_question_add(question, key);
329 if (r < 0)
330 return r;
331 }
332
333 r = dns_query_new(m, &q, question, ifindex, flags);
334 if (r < 0)
335 return r;
336
337 q->request = sd_bus_message_ref(message);
338 q->request_family = family;
339 q->request_hostname = hostname;
340 q->complete = bus_method_resolve_hostname_complete;
341
342 r = dns_query_bus_track(q, message);
343 if (r < 0)
344 return r;
345
346 r = dns_query_go(q);
347 if (r < 0) {
348 dns_query_free(q);
349
350 if (r == -ESRCH)
351 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
352
353 return r;
354 }
355
356 return 1;
357 }
358
359 static void bus_method_resolve_address_complete(DnsQuery *q) {
360 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
361 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
362 unsigned added = 0, i;
363 int r;
364
365 assert(q);
366
367 if (q->state != DNS_TRANSACTION_SUCCESS) {
368 r = reply_query_state(q);
369 goto finish;
370 }
371
372 r = sd_bus_message_new_method_return(q->request, &reply);
373 if (r < 0)
374 goto finish;
375
376 r = sd_bus_message_append(reply, "i", q->answer_ifindex);
377 if (r < 0)
378 goto finish;
379
380 r = sd_bus_message_open_container(reply, 'a', "s");
381 if (r < 0)
382 goto finish;
383
384 if (q->answer) {
385 answer = dns_answer_ref(q->answer);
386
387 for (i = 0; i < answer->n_rrs; i++) {
388 r = dns_question_matches_rr(q->question, answer->rrs[i]);
389 if (r < 0)
390 goto finish;
391 if (r == 0)
392 continue;
393
394 r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name);
395 if (r < 0)
396 goto finish;
397
398 added ++;
399 }
400 }
401
402 if (added == 0) {
403 _cleanup_free_ char *ip = NULL;
404
405 in_addr_to_string(q->request_family, &q->request_address, &ip);
406
407 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
408 goto finish;
409 }
410
411 r = sd_bus_message_close_container(reply);
412 if (r < 0)
413 goto finish;
414
415 r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
416 if (r < 0)
417 goto finish;
418
419 r = sd_bus_send(q->manager->bus, reply, NULL);
420
421 finish:
422 if (r < 0) {
423 log_error_errno(r, "Failed to send address reply: %m");
424 sd_bus_reply_method_errno(q->request, -r, NULL);
425 }
426
427 dns_query_free(q);
428 }
429
430 static int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
431 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
432 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
433 _cleanup_free_ char *reverse = NULL;
434 Manager *m = userdata;
435 int family, ifindex;
436 uint64_t flags;
437 const void *d;
438 DnsQuery *q;
439 size_t sz;
440 int r;
441
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, 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_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(message);
612 assert(m);
613
614 r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
615 if (r < 0)
616 return r;
617
618 r = dns_name_normalize(name, NULL);
619 if (r < 0)
620 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
621
622 r = check_ifindex_flags(ifindex, &flags, error);
623 if (r < 0)
624 return r;
625
626 question = dns_question_new(1);
627 if (!question)
628 return -ENOMEM;
629
630 key = dns_resource_key_new(class, type, name);
631 if (!key)
632 return -ENOMEM;
633
634 r = dns_question_add(question, key);
635 if (r < 0)
636 return r;
637
638 r = dns_query_new(m, &q, question, ifindex, flags);
639 if (r < 0)
640 return r;
641
642 q->request = sd_bus_message_ref(message);
643 q->request_hostname = name;
644 q->complete = bus_method_resolve_record_complete;
645
646 r = dns_query_bus_track(q, message);
647 if (r < 0)
648 return r;
649
650 r = dns_query_go(q);
651 if (r < 0) {
652 dns_query_free(q);
653
654 if (r == -ESRCH)
655 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
656
657 return r;
658 }
659
660 return 1;
661 }
662
663 static const sd_bus_vtable resolve_vtable[] = {
664 SD_BUS_VTABLE_START(0),
665 SD_BUS_METHOD("ResolveHostname", "isit", "ia(iay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
666 SD_BUS_METHOD("ResolveAddress", "iiayt", "iast", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
667 SD_BUS_METHOD("ResolveRecord", "isqqt", "ia(qqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
668 SD_BUS_VTABLE_END,
669 };
670
671 static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
672 Manager *m = userdata;
673
674 assert(s);
675 assert(m);
676
677 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
678
679 manager_connect_bus(m);
680 return 0;
681 }
682
683 static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
684 Manager *m = userdata;
685 int b, r;
686
687 assert(message);
688 assert(m);
689
690 r = sd_bus_message_read(message, "b", &b);
691 if (r < 0) {
692 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
693 return 0;
694 }
695
696 if (b)
697 return 0;
698
699 log_debug("Coming back from suspend, verifying all RRs...");
700
701 manager_verify_all(m);
702 return 0;
703 }
704
705 int manager_connect_bus(Manager *m) {
706 int r;
707
708 assert(m);
709
710 if (m->bus)
711 return 0;
712
713 r = sd_bus_default_system(&m->bus);
714 if (r < 0) {
715 /* We failed to connect? Yuck, we must be in early
716 * boot. Let's try in 5s again. As soon as we have
717 * kdbus we can stop doing this... */
718
719 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
720
721 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);
722 if (r < 0)
723 return log_error_errno(r, "Failed to install bus reconnect time event: %m");
724
725 return 0;
726 }
727
728 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
729 if (r < 0)
730 return log_error_errno(r, "Failed to register object: %m");
731
732 r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
733 if (r < 0)
734 return log_error_errno(r, "Failed to register name: %m");
735
736 r = sd_bus_attach_event(m->bus, m->event, 0);
737 if (r < 0)
738 return log_error_errno(r, "Failed to attach bus to event loop: %m");
739
740 r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
741 "type='signal',"
742 "sender='org.freedesktop.login1',"
743 "interface='org.freedesktop.login1.Manager',"
744 "member='PrepareForSleep',"
745 "path='/org/freedesktop/login1'",
746 match_prepare_for_sleep,
747 m);
748 if (r < 0)
749 log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
750
751 return 0;
752 }