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 "alloc-util.h"
31 #include "bus-internal.h"
32 #include "bus-message.h"
39 #include "synthesize.h"
42 static int get_creds_by_name(sd_bus
*bus
, const char *name
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
43 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*c
= NULL
;
50 r
= sd_bus_get_name_creds(bus
, name
, mask
, &c
);
51 if (r
== -ESRCH
|| r
== -ENXIO
)
52 return sd_bus_error_setf(error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Name %s is currently not owned by anyone.", name
);
62 static int get_creds_by_message(sd_bus
*bus
, sd_bus_message
*m
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
70 r
= sd_bus_message_read(m
, "s", &name
);
74 return get_creds_by_name(bus
, name
, mask
, _creds
, error
);
77 static int driver_activation(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
78 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
79 ProxyActivation
*activation
= userdata
;
82 * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
83 * whether this succeeded, failed, was not implemented or timed out. We
84 * cannot assume that the target reacts to this properly. Hence, just
85 * send the reply to the activation request and be done.
88 m
= activation
->request
; /* claim reference */
90 --activation
->proxy
->n_activations
;
91 LIST_REMOVE(activations_by_proxy
, activation
->proxy
->activations
, activation
);
92 sd_bus_slot_unref(activation
->slot
);
95 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_SUCCESS
);
98 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
) {
108 if (!streq_ptr(sd_bus_message_get_destination(m
), "org.freedesktop.DBus"))
111 /* The "Hello()" call is is handled in process_hello() */
113 if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus.Introspectable", "Introspect")) {
115 if (!sd_bus_message_has_signature(m
, ""))
116 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
118 return synthetic_reply_method_return(m
, "s",
119 "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
120 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
122 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
123 " <method name=\"Introspect\">\n"
124 " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
127 " <interface name=\"org.freedesktop.DBus\">\n"
128 " <method name=\"AddMatch\">\n"
129 " <arg type=\"s\" direction=\"in\"/>\n"
131 " <method name=\"RemoveMatch\">\n"
132 " <arg type=\"s\" direction=\"in\"/>\n"
134 " <method name=\"GetConnectionCredentials\">\n"
135 " <arg type=\"s\" direction=\"in\"/>\n"
136 " <arg type=\"a{sv}\" direction=\"out\"/>\n"
138 " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
139 " <arg type=\"s\" direction=\"in\"/>\n"
140 " <arg type=\"ay\" direction=\"out\"/>\n"
142 " <method name=\"GetConnectionUnixProcessID\">\n"
143 " <arg type=\"s\" direction=\"in\"/>\n"
144 " <arg type=\"u\" direction=\"out\"/>\n"
146 " <method name=\"GetConnectionUnixUser\">\n"
147 " <arg type=\"s\" direction=\"in\"/>\n"
148 " <arg type=\"u\" direction=\"out\"/>\n"
150 " <method name=\"GetId\">\n"
151 " <arg type=\"s\" direction=\"out\"/>\n"
153 " <method name=\"GetNameOwner\">\n"
154 " <arg type=\"s\" direction=\"in\"/>\n"
155 " <arg type=\"s\" direction=\"out\"/>\n"
157 " <method name=\"Hello\">\n"
158 " <arg type=\"s\" direction=\"out\"/>\n"
160 " <method name=\"ListActivatableNames\">\n"
161 " <arg type=\"as\" direction=\"out\"/>\n"
163 " <method name=\"ListNames\">\n"
164 " <arg type=\"as\" direction=\"out\"/>\n"
166 " <method name=\"ListQueuedOwners\">\n"
167 " <arg type=\"s\" direction=\"in\"/>\n"
168 " <arg type=\"as\" direction=\"out\"/>\n"
170 " <method name=\"NameHasOwner\">\n"
171 " <arg type=\"s\" direction=\"in\"/>\n"
172 " <arg type=\"b\" direction=\"out\"/>\n"
174 " <method name=\"ReleaseName\">\n"
175 " <arg type=\"s\" direction=\"in\"/>\n"
176 " <arg type=\"u\" direction=\"out\"/>\n"
178 " <method name=\"ReloadConfig\">\n"
180 " <method name=\"RequestName\">\n"
181 " <arg type=\"s\" direction=\"in\"/>\n"
182 " <arg type=\"u\" direction=\"in\"/>\n"
183 " <arg type=\"u\" direction=\"out\"/>\n"
185 " <method name=\"StartServiceByName\">\n"
186 " <arg type=\"s\" direction=\"in\"/>\n"
187 " <arg type=\"u\" direction=\"in\"/>\n"
188 " <arg type=\"u\" direction=\"out\"/>\n"
190 " <method name=\"UpdateActivationEnvironment\">\n"
191 " <arg type=\"a{ss}\" direction=\"in\"/>\n"
193 " <signal name=\"NameAcquired\">\n"
194 " <arg type=\"s\"/>\n"
196 " <signal name=\"NameLost\">\n"
197 " <arg type=\"s\"/>\n"
199 " <signal name=\"NameOwnerChanged\">\n"
200 " <arg type=\"s\"/>\n"
201 " <arg type=\"s\"/>\n"
202 " <arg type=\"s\"/>\n"
207 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "AddMatch")) {
210 if (!sd_bus_message_has_signature(m
, "s"))
211 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
213 r
= sd_bus_message_read(m
, "s", &match
);
215 return synthetic_reply_method_errno(m
, r
, NULL
);
217 r
= sd_bus_add_match(a
, NULL
, match
, proxy_match
, p
);
219 return synthetic_reply_method_errno(m
, r
, NULL
);
221 return synthetic_reply_method_return(m
, NULL
);
223 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RemoveMatch")) {
226 if (!sd_bus_message_has_signature(m
, "s"))
227 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
229 r
= sd_bus_message_read(m
, "s", &match
);
231 return synthetic_reply_method_errno(m
, r
, NULL
);
233 r
= bus_remove_match_by_string(a
, match
, NULL
, NULL
);
235 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND
, "Match rule not found"));
237 return synthetic_reply_method_errno(m
, r
, NULL
);
239 return synthetic_reply_method_return(m
, NULL
);
241 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionCredentials")) {
242 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
243 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
244 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
246 if (!sd_bus_message_has_signature(m
, "s"))
247 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
249 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
251 return synthetic_reply_method_errno(m
, r
, &error
);
253 r
= sd_bus_message_new_method_return(m
, &reply
);
255 return synthetic_reply_method_errno(m
, r
, NULL
);
257 r
= sd_bus_message_open_container(reply
, 'a', "{sv}");
259 return synthetic_reply_method_errno(m
, r
, NULL
);
261 /* Due to i.e. namespace translations some data might be missing */
263 if (creds
->mask
& SD_BUS_CREDS_PID
) {
264 r
= sd_bus_message_append(reply
, "{sv}", "ProcessID", "u", (uint32_t) creds
->pid
);
266 return synthetic_reply_method_errno(m
, r
, NULL
);
269 if (creds
->mask
& SD_BUS_CREDS_EUID
) {
270 r
= sd_bus_message_append(reply
, "{sv}", "UnixUserID", "u", (uint32_t) creds
->euid
);
272 return synthetic_reply_method_errno(m
, r
, NULL
);
275 if (creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
276 r
= sd_bus_message_open_container(reply
, 'e', "sv");
278 return synthetic_reply_method_errno(m
, r
, NULL
);
280 r
= sd_bus_message_append(reply
, "s", "LinuxSecurityLabel");
282 return synthetic_reply_method_errno(m
, r
, NULL
);
284 r
= sd_bus_message_open_container(reply
, 'v', "ay");
286 return synthetic_reply_method_errno(m
, r
, NULL
);
288 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
290 return synthetic_reply_method_errno(m
, r
, NULL
);
292 r
= sd_bus_message_close_container(reply
);
294 return synthetic_reply_method_errno(m
, r
, NULL
);
296 r
= sd_bus_message_close_container(reply
);
298 return synthetic_reply_method_errno(m
, r
, NULL
);
301 r
= sd_bus_message_close_container(reply
);
303 return synthetic_reply_method_errno(m
, r
, NULL
);
305 return synthetic_driver_send(m
->bus
, reply
);
307 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
308 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
309 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
310 _cleanup_(sd_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_SELINUX_CONTEXT
, &creds
, &error
);
317 return synthetic_reply_method_errno(m
, r
, &error
);
319 if (!(creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
320 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
322 r
= sd_bus_message_new_method_return(m
, &reply
);
324 return synthetic_reply_method_errno(m
, r
, NULL
);
326 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
328 return synthetic_reply_method_errno(m
, r
, NULL
);
330 return synthetic_driver_send(m
->bus
, reply
);
332 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
333 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
334 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
336 if (!sd_bus_message_has_signature(m
, "s"))
337 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
339 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
, &creds
, &error
);
341 return synthetic_reply_method_errno(m
, r
, &error
);
343 if (!(creds
->mask
& SD_BUS_CREDS_PID
))
344 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
346 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->pid
);
348 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
349 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
350 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
352 if (!sd_bus_message_has_signature(m
, "s"))
353 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
355 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_EUID
, &creds
, &error
);
357 return synthetic_reply_method_errno(m
, r
, &error
);
359 if (!(creds
->mask
& SD_BUS_CREDS_EUID
))
360 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
362 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->euid
);
364 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetId")) {
365 sd_id128_t server_id
;
366 char buf
[SD_ID128_STRING_MAX
];
368 if (!sd_bus_message_has_signature(m
, ""))
369 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
371 r
= sd_bus_get_bus_id(a
, &server_id
);
373 return synthetic_reply_method_errno(m
, r
, NULL
);
375 return synthetic_reply_method_return(m
, "s", sd_id128_to_string(server_id
, buf
));
377 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetNameOwner")) {
379 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
380 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
382 if (!sd_bus_message_has_signature(m
, "s"))
383 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
385 r
= sd_bus_message_read(m
, "s", &name
);
387 return synthetic_reply_method_errno(m
, r
, NULL
);
389 if (streq(name
, "org.freedesktop.DBus"))
390 return synthetic_reply_method_return(m
, "s", "org.freedesktop.DBus");
392 r
= get_creds_by_name(a
, name
, SD_BUS_CREDS_UNIQUE_NAME
, &creds
, &error
);
394 return synthetic_reply_method_errno(m
, r
, &error
);
396 if (!(creds
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
397 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
399 return synthetic_reply_method_return(m
, "s", creds
->unique_name
);
401 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListActivatableNames")) {
402 _cleanup_strv_free_
char **names
= NULL
;
404 if (!sd_bus_message_has_signature(m
, ""))
405 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
407 r
= sd_bus_list_names(a
, NULL
, &names
);
409 return synthetic_reply_method_errno(m
, r
, NULL
);
411 /* Let's sort the names list to make it stable */
414 return synthetic_reply_method_return_strv(m
, names
);
416 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListNames")) {
417 _cleanup_strv_free_
char **names
= NULL
;
419 if (!sd_bus_message_has_signature(m
, ""))
420 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
422 r
= sd_bus_list_names(a
, &names
, NULL
);
424 return synthetic_reply_method_errno(m
, r
, NULL
);
426 r
= strv_extend(&names
, "org.freedesktop.DBus");
428 return synthetic_reply_method_errno(m
, r
, NULL
);
430 /* Let's sort the names list to make it stable */
433 return synthetic_reply_method_return_strv(m
, names
);
435 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListQueuedOwners")) {
436 struct kdbus_cmd_list cmd
= {
437 .flags
= KDBUS_LIST_QUEUED
,
440 struct kdbus_info
*name_list
, *name
;
441 _cleanup_strv_free_
char **owners
= NULL
;
442 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
446 if (!sd_bus_message_has_signature(m
, "s"))
447 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
449 r
= sd_bus_message_read(m
, "s", &arg0
);
451 return synthetic_reply_method_errno(m
, r
, NULL
);
453 r
= sd_bus_get_name_creds(a
, arg0
, 0, NULL
);
454 if (r
== -ESRCH
|| r
== -ENXIO
) {
455 sd_bus_error_setf(&error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Could not get owners of name '%s': no such name.", arg0
);
456 return synthetic_reply_method_errno(m
, r
, &error
);
459 return synthetic_reply_method_errno(m
, r
, NULL
);
461 r
= ioctl(a
->input_fd
, KDBUS_CMD_LIST
, &cmd
);
463 return synthetic_reply_method_errno(m
, -errno
, NULL
);
465 name_list
= (struct kdbus_info
*) ((uint8_t *) a
->kdbus_buffer
+ cmd
.offset
);
467 KDBUS_FOREACH(name
, name_list
, cmd
.list_size
) {
468 struct kdbus_item
*item
;
471 KDBUS_ITEM_FOREACH(item
, name
, items
) {
472 if (item
->type
== KDBUS_ITEM_OWNED_NAME
) {
473 if (!streq_ptr(item
->name
.name
, arg0
))
476 if (asprintf(&n
, ":1.%llu", (unsigned long long) name
->id
) < 0) {
481 r
= strv_consume(&owners
, n
);
493 r
= bus_kernel_cmd_free(a
, cmd
.offset
);
495 return synthetic_reply_method_errno(m
, r
, NULL
);
498 return synthetic_reply_method_errno(m
, err
, NULL
);
500 return synthetic_reply_method_return_strv(m
, owners
);
502 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "NameHasOwner")) {
505 if (!sd_bus_message_has_signature(m
, "s"))
506 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
508 r
= sd_bus_message_read(m
, "s", &name
);
510 return synthetic_reply_method_errno(m
, r
, NULL
);
512 if (streq(name
, "org.freedesktop.DBus"))
513 return synthetic_reply_method_return(m
, "b", true);
515 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
516 if (r
< 0 && r
!= -ESRCH
&& r
!= -ENXIO
)
517 return synthetic_reply_method_errno(m
, r
, NULL
);
519 return synthetic_reply_method_return(m
, "b", r
>= 0);
521 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReleaseName")) {
524 if (!sd_bus_message_has_signature(m
, "s"))
525 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
527 r
= sd_bus_message_read(m
, "s", &name
);
529 return synthetic_reply_method_errno(m
, r
, NULL
);
531 r
= sd_bus_release_name(a
, name
);
534 return synthetic_reply_method_return(m
, "u", BUS_NAME_NON_EXISTENT
);
535 if (r
== -EADDRINUSE
)
536 return synthetic_reply_method_return(m
, "u", BUS_NAME_NOT_OWNER
);
538 return synthetic_reply_method_errno(m
, r
, NULL
);
541 set_remove(owned_names
, (char*) name
);
543 return synthetic_reply_method_return(m
, "u", BUS_NAME_RELEASED
);
545 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReloadConfig")) {
546 if (!sd_bus_message_has_signature(m
, ""))
547 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
549 r
= shared_policy_reload(sp
);
551 return synthetic_reply_method_errno(m
, r
, NULL
);
553 return synthetic_reply_method_return(m
, NULL
);
555 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RequestName")) {
557 uint32_t flags
, param
;
560 if (!sd_bus_message_has_signature(m
, "su"))
561 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
563 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
565 return synthetic_reply_method_errno(m
, r
, NULL
);
571 policy
= shared_policy_acquire(sp
);
572 denied
= !policy_check_own(policy
, ucred
->uid
, ucred
->gid
, name
);
573 shared_policy_release(sp
, policy
);
575 return synthetic_reply_method_errno(m
, -EPERM
, NULL
);
578 if ((flags
& ~(BUS_NAME_ALLOW_REPLACEMENT
|BUS_NAME_REPLACE_EXISTING
|BUS_NAME_DO_NOT_QUEUE
)) != 0)
579 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
582 if (flags
& BUS_NAME_ALLOW_REPLACEMENT
)
583 param
|= SD_BUS_NAME_ALLOW_REPLACEMENT
;
584 if (flags
& BUS_NAME_REPLACE_EXISTING
)
585 param
|= SD_BUS_NAME_REPLACE_EXISTING
;
586 if (!(flags
& BUS_NAME_DO_NOT_QUEUE
))
587 param
|= SD_BUS_NAME_QUEUE
;
589 r
= set_put_strdup(owned_names
, name
);
591 return synthetic_reply_method_errno(m
, r
, NULL
);
593 r
= sd_bus_request_name(a
, name
, param
);
596 return synthetic_reply_method_return(m
, "u", BUS_NAME_ALREADY_OWNER
);
598 set_remove(owned_names
, (char*) name
);
601 return synthetic_reply_method_return(m
, "u", BUS_NAME_EXISTS
);
602 return synthetic_reply_method_errno(m
, r
, NULL
);
608 return synthetic_reply_method_return(m
, "u", BUS_NAME_IN_QUEUE
);
610 return synthetic_reply_method_return(m
, "u", BUS_NAME_PRIMARY_OWNER
);
612 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "StartServiceByName")) {
613 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*msg
= NULL
;
614 ProxyActivation
*activation
;
619 if (!sd_bus_message_has_signature(m
, "su"))
620 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
622 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
624 return synthetic_reply_method_errno(m
, r
, NULL
);
627 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
629 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
630 if (r
>= 0 || streq(name
, "org.freedesktop.DBus"))
631 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_ALREADY_RUNNING
);
633 return synthetic_reply_method_errno(m
, r
, NULL
);
635 if (p
->n_activations
>= PROXY_ACTIVATIONS_MAX
)
636 return synthetic_reply_method_errno(m
, -EMFILE
, NULL
);
638 r
= sd_bus_message_get_cookie(m
, &cookie
);
640 return synthetic_reply_method_errno(m
, r
, NULL
);
642 r
= sd_bus_message_new_method_call(a
,
646 "org.freedesktop.DBus.Peer",
649 return synthetic_reply_method_errno(m
, r
, NULL
);
651 r
= bus_message_seal(msg
, cookie
, BUS_DEFAULT_TIMEOUT
);
653 return synthetic_reply_method_errno(m
, r
, NULL
);
655 activation
= new0(ProxyActivation
, 1);
657 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
659 r
= sd_bus_call_async(a
,
667 return synthetic_reply_method_errno(m
, r
, NULL
);
670 activation
->proxy
= p
;
671 activation
->request
= sd_bus_message_ref(m
);
672 LIST_PREPEND(activations_by_proxy
, p
->activations
, activation
);
676 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
677 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*msg
= NULL
;
678 _cleanup_strv_free_
char **args
= NULL
;
680 if (!sd_bus_message_has_signature(m
, "a{ss}"))
681 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
683 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{ss}");
685 return synthetic_reply_method_errno(m
, r
, NULL
);
687 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "ss")) > 0) {
688 _cleanup_free_
char *s
= NULL
;
692 r
= sd_bus_message_read(m
, "ss", &key
, &value
);
694 return synthetic_reply_method_errno(m
, r
, NULL
);
696 s
= strjoin(key
, "=", value
, NULL
);
698 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
700 if (!env_assignment_is_valid(s
)) {
701 log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s
);
703 r
= strv_extend(&args
, s
);
705 return synthetic_reply_method_errno(m
, r
, NULL
);
708 r
= sd_bus_message_exit_container(m
);
710 return synthetic_reply_method_errno(m
, r
, NULL
);
713 r
= sd_bus_message_exit_container(m
);
715 return synthetic_reply_method_errno(m
, r
, NULL
);
717 if (strv_isempty(args
)) /* nothing to do? */
718 return synthetic_reply_method_return(m
, NULL
);
720 r
= sd_bus_message_new_method_call(
723 "org.freedesktop.systemd1",
724 "/org/freedesktop/systemd1",
725 "org.freedesktop.systemd1.Manager",
728 return synthetic_reply_method_errno(m
, r
, NULL
);
730 r
= sd_bus_message_append_strv(msg
, args
);
732 return synthetic_reply_method_errno(m
, r
, NULL
);
734 r
= sd_bus_call(a
, msg
, 0, NULL
, NULL
);
736 return synthetic_reply_method_errno(m
, r
, NULL
);
738 return synthetic_reply_method_return(m
, NULL
);
741 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
743 r
= sd_bus_error_setf(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
, "Unknown method '%s'.", m
->member
);
745 return synthetic_reply_method_errno(m
, r
, &error
);