1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Daniel Mack
8 Copyright 2014 Kay Sievers
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 #include "bus-internal.h"
31 #include "bus-message.h"
37 #include "synthesize.h"
39 static int get_creds_by_name(sd_bus
*bus
, const char *name
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
40 _cleanup_bus_creds_unref_ sd_bus_creds
*c
= NULL
;
47 r
= sd_bus_get_name_creds(bus
, name
, mask
, &c
);
48 if (r
== -ESRCH
|| r
== -ENXIO
)
49 return sd_bus_error_setf(error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Name %s is currently not owned by anyone.", name
);
59 static int get_creds_by_message(sd_bus
*bus
, sd_bus_message
*m
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
67 r
= sd_bus_message_read(m
, "s", &name
);
71 return get_creds_by_name(bus
, name
, mask
, _creds
, error
);
74 int bus_proxy_process_driver(Proxy
*p
, sd_bus
*a
, sd_bus
*b
, sd_bus_message
*m
, SharedPolicy
*sp
, const struct ucred
*ucred
, Set
*owned_names
) {
84 if (!streq_ptr(sd_bus_message_get_destination(m
), "org.freedesktop.DBus"))
87 /* The "Hello()" call is is handled in process_hello() */
89 if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus.Introspectable", "Introspect")) {
91 if (!sd_bus_message_has_signature(m
, ""))
92 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
94 return synthetic_reply_method_return(m
, "s",
95 "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
96 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
98 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
99 " <method name=\"Introspect\">\n"
100 " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
103 " <interface name=\"org.freedesktop.DBus\">\n"
104 " <method name=\"AddMatch\">\n"
105 " <arg type=\"s\" direction=\"in\"/>\n"
107 " <method name=\"RemoveMatch\">\n"
108 " <arg type=\"s\" direction=\"in\"/>\n"
110 " <method name=\"GetConnectionCredentials\">\n"
111 " <arg type=\"s\" direction=\"in\"/>\n"
112 " <arg type=\"a{sv}\" direction=\"out\"/>\n"
114 " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
115 " <arg type=\"s\" direction=\"in\"/>\n"
116 " <arg type=\"ay\" direction=\"out\"/>\n"
118 " <method name=\"GetConnectionUnixProcessID\">\n"
119 " <arg type=\"s\" direction=\"in\"/>\n"
120 " <arg type=\"u\" direction=\"out\"/>\n"
122 " <method name=\"GetConnectionUnixUser\">\n"
123 " <arg type=\"s\" direction=\"in\"/>\n"
124 " <arg type=\"u\" direction=\"out\"/>\n"
126 " <method name=\"GetId\">\n"
127 " <arg type=\"s\" direction=\"out\"/>\n"
129 " <method name=\"GetNameOwner\">\n"
130 " <arg type=\"s\" direction=\"in\"/>\n"
131 " <arg type=\"s\" direction=\"out\"/>\n"
133 " <method name=\"Hello\">\n"
134 " <arg type=\"s\" direction=\"out\"/>\n"
136 " <method name=\"ListActivatableNames\">\n"
137 " <arg type=\"as\" direction=\"out\"/>\n"
139 " <method name=\"ListNames\">\n"
140 " <arg type=\"as\" direction=\"out\"/>\n"
142 " <method name=\"ListQueuedOwners\">\n"
143 " <arg type=\"s\" direction=\"in\"/>\n"
144 " <arg type=\"as\" direction=\"out\"/>\n"
146 " <method name=\"NameHasOwner\">\n"
147 " <arg type=\"s\" direction=\"in\"/>\n"
148 " <arg type=\"b\" direction=\"out\"/>\n"
150 " <method name=\"ReleaseName\">\n"
151 " <arg type=\"s\" direction=\"in\"/>\n"
152 " <arg type=\"u\" direction=\"out\"/>\n"
154 " <method name=\"ReloadConfig\">\n"
156 " <method name=\"RequestName\">\n"
157 " <arg type=\"s\" direction=\"in\"/>\n"
158 " <arg type=\"u\" direction=\"in\"/>\n"
159 " <arg type=\"u\" direction=\"out\"/>\n"
161 " <method name=\"StartServiceByName\">\n"
162 " <arg type=\"s\" direction=\"in\"/>\n"
163 " <arg type=\"u\" direction=\"in\"/>\n"
164 " <arg type=\"u\" direction=\"out\"/>\n"
166 " <method name=\"UpdateActivationEnvironment\">\n"
167 " <arg type=\"a{ss}\" direction=\"in\"/>\n"
169 " <signal name=\"NameAcquired\">\n"
170 " <arg type=\"s\"/>\n"
172 " <signal name=\"NameLost\">\n"
173 " <arg type=\"s\"/>\n"
175 " <signal name=\"NameOwnerChanged\">\n"
176 " <arg type=\"s\"/>\n"
177 " <arg type=\"s\"/>\n"
178 " <arg type=\"s\"/>\n"
183 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "AddMatch")) {
186 if (!sd_bus_message_has_signature(m
, "s"))
187 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
189 r
= sd_bus_message_read(m
, "s", &match
);
191 return synthetic_reply_method_errno(m
, r
, NULL
);
193 r
= sd_bus_add_match(a
, NULL
, match
, proxy_match
, p
);
195 return synthetic_reply_method_errno(m
, r
, NULL
);
197 return synthetic_reply_method_return(m
, NULL
);
199 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RemoveMatch")) {
202 if (!sd_bus_message_has_signature(m
, "s"))
203 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
205 r
= sd_bus_message_read(m
, "s", &match
);
207 return synthetic_reply_method_errno(m
, r
, NULL
);
209 r
= bus_remove_match_by_string(a
, match
, NULL
, NULL
);
211 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND
, "Match rule not found"));
213 return synthetic_reply_method_errno(m
, r
, NULL
);
215 return synthetic_reply_method_return(m
, NULL
);
217 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionCredentials")) {
218 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
219 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
220 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
222 if (!sd_bus_message_has_signature(m
, "s"))
223 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
225 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
227 return synthetic_reply_method_errno(m
, r
, &error
);
229 r
= sd_bus_message_new_method_return(m
, &reply
);
231 return synthetic_reply_method_errno(m
, r
, NULL
);
233 r
= sd_bus_message_open_container(reply
, 'a', "{sv}");
235 return synthetic_reply_method_errno(m
, r
, NULL
);
237 /* Due to i.e. namespace translations some data might be missing */
239 if (creds
->mask
& SD_BUS_CREDS_PID
) {
240 r
= sd_bus_message_append(reply
, "{sv}", "ProcessID", "u", (uint32_t) creds
->pid
);
242 return synthetic_reply_method_errno(m
, r
, NULL
);
245 if (creds
->mask
& SD_BUS_CREDS_EUID
) {
246 r
= sd_bus_message_append(reply
, "{sv}", "UnixUserID", "u", (uint32_t) creds
->euid
);
248 return synthetic_reply_method_errno(m
, r
, NULL
);
251 if (creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
252 r
= sd_bus_message_open_container(reply
, 'e', "sv");
254 return synthetic_reply_method_errno(m
, r
, NULL
);
256 r
= sd_bus_message_append(reply
, "s", "LinuxSecurityLabel");
258 return synthetic_reply_method_errno(m
, r
, NULL
);
260 r
= sd_bus_message_open_container(reply
, 'v', "ay");
262 return synthetic_reply_method_errno(m
, r
, NULL
);
264 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
266 return synthetic_reply_method_errno(m
, r
, NULL
);
268 r
= sd_bus_message_close_container(reply
);
270 return synthetic_reply_method_errno(m
, r
, NULL
);
272 r
= sd_bus_message_close_container(reply
);
274 return synthetic_reply_method_errno(m
, r
, NULL
);
277 r
= sd_bus_message_close_container(reply
);
279 return synthetic_reply_method_errno(m
, r
, NULL
);
281 return synthetic_driver_send(m
->bus
, reply
);
283 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
284 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
285 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
286 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
288 if (!sd_bus_message_has_signature(m
, "s"))
289 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
291 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
293 return synthetic_reply_method_errno(m
, r
, &error
);
295 if (!(creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
296 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
298 r
= sd_bus_message_new_method_return(m
, &reply
);
300 return synthetic_reply_method_errno(m
, r
, NULL
);
302 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
304 return synthetic_reply_method_errno(m
, r
, NULL
);
306 return synthetic_driver_send(m
->bus
, reply
);
308 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
309 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
310 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
312 if (!sd_bus_message_has_signature(m
, "s"))
313 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
315 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
, &creds
, &error
);
317 return synthetic_reply_method_errno(m
, r
, &error
);
319 if (!(creds
->mask
& SD_BUS_CREDS_PID
))
320 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
322 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->pid
);
324 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
325 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
326 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
328 if (!sd_bus_message_has_signature(m
, "s"))
329 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
331 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_EUID
, &creds
, &error
);
333 return synthetic_reply_method_errno(m
, r
, &error
);
335 if (!(creds
->mask
& SD_BUS_CREDS_EUID
))
336 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
338 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->euid
);
340 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetId")) {
341 sd_id128_t server_id
;
342 char buf
[SD_ID128_STRING_MAX
];
344 if (!sd_bus_message_has_signature(m
, ""))
345 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
347 r
= sd_bus_get_bus_id(a
, &server_id
);
349 return synthetic_reply_method_errno(m
, r
, NULL
);
351 return synthetic_reply_method_return(m
, "s", sd_id128_to_string(server_id
, buf
));
353 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetNameOwner")) {
355 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
356 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
358 if (!sd_bus_message_has_signature(m
, "s"))
359 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
361 r
= sd_bus_message_read(m
, "s", &name
);
363 return synthetic_reply_method_errno(m
, r
, NULL
);
365 if (streq(name
, "org.freedesktop.DBus"))
366 return synthetic_reply_method_return(m
, "s", "org.freedesktop.DBus");
368 r
= get_creds_by_name(a
, name
, SD_BUS_CREDS_UNIQUE_NAME
, &creds
, &error
);
370 return synthetic_reply_method_errno(m
, r
, &error
);
372 if (!(creds
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
373 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
375 return synthetic_reply_method_return(m
, "s", creds
->unique_name
);
377 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListActivatableNames")) {
378 _cleanup_strv_free_
char **names
= NULL
;
380 if (!sd_bus_message_has_signature(m
, ""))
381 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
383 r
= sd_bus_list_names(a
, NULL
, &names
);
385 return synthetic_reply_method_errno(m
, r
, NULL
);
387 /* Let's sort the names list to make it stable */
390 return synthetic_reply_method_return_strv(m
, names
);
392 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListNames")) {
393 _cleanup_strv_free_
char **names
= NULL
;
395 if (!sd_bus_message_has_signature(m
, ""))
396 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
398 r
= sd_bus_list_names(a
, &names
, NULL
);
400 return synthetic_reply_method_errno(m
, r
, NULL
);
402 r
= strv_extend(&names
, "org.freedesktop.DBus");
404 return synthetic_reply_method_errno(m
, r
, NULL
);
406 /* Let's sort the names list to make it stable */
409 return synthetic_reply_method_return_strv(m
, names
);
411 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListQueuedOwners")) {
412 struct kdbus_cmd_list cmd
= {
413 .flags
= KDBUS_LIST_QUEUED
,
416 struct kdbus_info
*name_list
, *name
;
417 _cleanup_strv_free_
char **owners
= NULL
;
418 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
422 if (!sd_bus_message_has_signature(m
, "s"))
423 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
425 r
= sd_bus_message_read(m
, "s", &arg0
);
427 return synthetic_reply_method_errno(m
, r
, NULL
);
429 r
= sd_bus_get_name_creds(a
, arg0
, 0, NULL
);
430 if (r
== -ESRCH
|| r
== -ENXIO
) {
431 sd_bus_error_setf(&error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Could not get owners of name '%s': no such name.", arg0
);
432 return synthetic_reply_method_errno(m
, r
, &error
);
435 return synthetic_reply_method_errno(m
, r
, NULL
);
437 r
= ioctl(a
->input_fd
, KDBUS_CMD_LIST
, &cmd
);
439 return synthetic_reply_method_errno(m
, -errno
, NULL
);
441 name_list
= (struct kdbus_info
*) ((uint8_t *) a
->kdbus_buffer
+ cmd
.offset
);
443 KDBUS_FOREACH(name
, name_list
, cmd
.list_size
) {
444 struct kdbus_item
*item
;
447 KDBUS_ITEM_FOREACH(item
, name
, items
) {
448 if (item
->type
== KDBUS_ITEM_OWNED_NAME
) {
449 if (!streq_ptr(item
->name
.name
, arg0
))
452 if (asprintf(&n
, ":1.%llu", (unsigned long long) name
->id
) < 0) {
457 r
= strv_consume(&owners
, n
);
469 r
= bus_kernel_cmd_free(a
, cmd
.offset
);
471 return synthetic_reply_method_errno(m
, r
, NULL
);
474 return synthetic_reply_method_errno(m
, err
, NULL
);
476 return synthetic_reply_method_return_strv(m
, owners
);
478 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "NameHasOwner")) {
481 if (!sd_bus_message_has_signature(m
, "s"))
482 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
484 r
= sd_bus_message_read(m
, "s", &name
);
486 return synthetic_reply_method_errno(m
, r
, NULL
);
488 if (streq(name
, "org.freedesktop.DBus"))
489 return synthetic_reply_method_return(m
, "b", true);
491 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
492 if (r
< 0 && r
!= -ESRCH
&& r
!= -ENXIO
)
493 return synthetic_reply_method_errno(m
, r
, NULL
);
495 return synthetic_reply_method_return(m
, "b", r
>= 0);
497 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReleaseName")) {
500 if (!sd_bus_message_has_signature(m
, "s"))
501 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
503 r
= sd_bus_message_read(m
, "s", &name
);
505 return synthetic_reply_method_errno(m
, r
, NULL
);
507 r
= sd_bus_release_name(a
, name
);
510 return synthetic_reply_method_return(m
, "u", BUS_NAME_NON_EXISTENT
);
511 if (r
== -EADDRINUSE
)
512 return synthetic_reply_method_return(m
, "u", BUS_NAME_NOT_OWNER
);
514 return synthetic_reply_method_errno(m
, r
, NULL
);
517 set_remove(owned_names
, (char*) name
);
519 return synthetic_reply_method_return(m
, "u", BUS_NAME_RELEASED
);
521 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReloadConfig")) {
522 if (!sd_bus_message_has_signature(m
, ""))
523 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
525 r
= shared_policy_reload(sp
);
527 return synthetic_reply_method_errno(m
, r
, NULL
);
529 return synthetic_reply_method_return(m
, NULL
);
531 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RequestName")) {
533 uint32_t flags
, param
;
536 if (!sd_bus_message_has_signature(m
, "su"))
537 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
539 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
541 return synthetic_reply_method_errno(m
, r
, NULL
);
547 policy
= shared_policy_acquire(sp
);
548 denied
= !policy_check_own(policy
, ucred
->uid
, ucred
->gid
, name
);
549 shared_policy_release(sp
, policy
);
551 return synthetic_reply_method_errno(m
, -EPERM
, NULL
);
554 if ((flags
& ~(BUS_NAME_ALLOW_REPLACEMENT
|BUS_NAME_REPLACE_EXISTING
|BUS_NAME_DO_NOT_QUEUE
)) != 0)
555 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
558 if (flags
& BUS_NAME_ALLOW_REPLACEMENT
)
559 param
|= SD_BUS_NAME_ALLOW_REPLACEMENT
;
560 if (flags
& BUS_NAME_REPLACE_EXISTING
)
561 param
|= SD_BUS_NAME_REPLACE_EXISTING
;
562 if (!(flags
& BUS_NAME_DO_NOT_QUEUE
))
563 param
|= SD_BUS_NAME_QUEUE
;
565 r
= set_put_strdup(owned_names
, name
);
567 return synthetic_reply_method_errno(m
, r
, NULL
);
569 r
= sd_bus_request_name(a
, name
, param
);
572 return synthetic_reply_method_return(m
, "u", BUS_NAME_ALREADY_OWNER
);
574 set_remove(owned_names
, (char*) name
);
577 return synthetic_reply_method_return(m
, "u", BUS_NAME_EXISTS
);
578 return synthetic_reply_method_errno(m
, r
, NULL
);
584 return synthetic_reply_method_return(m
, "u", BUS_NAME_IN_QUEUE
);
586 return synthetic_reply_method_return(m
, "u", BUS_NAME_PRIMARY_OWNER
);
588 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "StartServiceByName")) {
589 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
593 if (!sd_bus_message_has_signature(m
, "su"))
594 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
596 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
598 return synthetic_reply_method_errno(m
, r
, NULL
);
601 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
603 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
604 if (r
>= 0 || streq(name
, "org.freedesktop.DBus"))
605 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_ALREADY_RUNNING
);
607 return synthetic_reply_method_errno(m
, r
, NULL
);
609 r
= sd_bus_message_new_method_call(
614 "org.freedesktop.DBus.Peer",
617 return synthetic_reply_method_errno(m
, r
, NULL
);
619 r
= sd_bus_send(a
, msg
, NULL
);
621 return synthetic_reply_method_errno(m
, r
, NULL
);
623 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_SUCCESS
);
625 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
626 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
627 _cleanup_strv_free_
char **args
= NULL
;
629 if (!sd_bus_message_has_signature(m
, "a{ss}"))
630 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
632 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{ss}");
634 return synthetic_reply_method_errno(m
, r
, NULL
);
636 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "ss")) > 0) {
637 _cleanup_free_
char *s
= NULL
;
641 r
= sd_bus_message_read(m
, "ss", &key
, &value
);
643 return synthetic_reply_method_errno(m
, r
, NULL
);
645 s
= strjoin(key
, "=", value
, NULL
);
647 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
649 r
= strv_extend(&args
, s
);
651 return synthetic_reply_method_errno(m
, r
, NULL
);
653 r
= sd_bus_message_exit_container(m
);
655 return synthetic_reply_method_errno(m
, r
, NULL
);
658 r
= sd_bus_message_exit_container(m
);
660 return synthetic_reply_method_errno(m
, r
, NULL
);
663 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
665 r
= sd_bus_message_new_method_call(
668 "org.freedesktop.systemd1",
669 "/org/freedesktop/systemd1",
670 "org.freedesktop.systemd1.Manager",
673 return synthetic_reply_method_errno(m
, r
, NULL
);
675 r
= sd_bus_message_append_strv(msg
, args
);
677 return synthetic_reply_method_errno(m
, r
, NULL
);
679 r
= sd_bus_call(a
, msg
, 0, NULL
, NULL
);
681 return synthetic_reply_method_errno(m
, r
, NULL
);
683 return synthetic_reply_method_return(m
, NULL
);
686 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
688 r
= sd_bus_error_setf(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
, "Unknown method '%s'.", m
->member
);
690 return synthetic_reply_method_errno(m
, r
, &error
);