chiark / gitweb /
resolve: set error code on failure
[elogind.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("Failed to send hostname reply: %s", strerror(-r));
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("Failed to send address reply: %s", strerror(-r));
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("Failed to send record reply: %s", strerror(-r));
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("Failed to parse PrepareForSleep signal: %s", strerror(-r));
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("Failed to connect to bus, trying again in 5s: %s", strerror(-r));
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                         log_error("Failed to install bus reconnect time event: %s", strerror(-r));
725                         return r;
726                 }
727
728                 return 0;
729         }
730
731         r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
732         if (r < 0) {
733                 log_error("Failed to register object: %s", strerror(-r));
734                 return r;
735         }
736
737         r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
738         if (r < 0) {
739                 log_error("Failed to register name: %s", strerror(-r));
740                 return r;
741         }
742
743         r = sd_bus_attach_event(m->bus, m->event, 0);
744         if (r < 0) {
745                 log_error("Failed to attach bus to event loop: %s", strerror(-r));
746                 return r;
747         }
748
749         r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
750                              "type='signal',"
751                              "sender='org.freedesktop.login1',"
752                              "interface='org.freedesktop.login1.Manager',"
753                              "member='PrepareForSleep',"
754                              "path='/org/freedesktop/login1'",
755                              match_prepare_for_sleep,
756                              m);
757         if (r < 0)
758                 log_error("Failed to add match for PrepareForSleep: %s", strerror(-r));
759
760         return 0;
761 }