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"
38 #include "synthesize.h"
41 static int get_creds_by_name(sd_bus
*bus
, const char *name
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
42 _cleanup_bus_creds_unref_ sd_bus_creds
*c
= NULL
;
49 r
= sd_bus_get_name_creds(bus
, name
, mask
, &c
);
50 if (r
== -ESRCH
|| r
== -ENXIO
)
51 return sd_bus_error_setf(error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Name %s is currently not owned by anyone.", name
);
61 static int get_creds_by_message(sd_bus
*bus
, sd_bus_message
*m
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
69 r
= sd_bus_message_read(m
, "s", &name
);
73 return get_creds_by_name(bus
, name
, mask
, _creds
, error
);
76 static int driver_activation(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
77 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
78 ProxyActivation
*activation
= userdata
;
81 * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
82 * whether this succeeded, failed, was not implemented or timed out. We
83 * cannot assume that the target reacts to this properly. Hence, just
84 * send the reply to the activation request and be done.
87 m
= activation
->request
; /* claim reference */
89 --activation
->proxy
->n_activations
;
90 LIST_REMOVE(activations_by_proxy
, activation
->proxy
->activations
, activation
);
91 sd_bus_slot_unref(activation
->slot
);
94 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_SUCCESS
);
97 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
) {
107 if (!streq_ptr(sd_bus_message_get_destination(m
), "org.freedesktop.DBus"))
110 /* The "Hello()" call is is handled in process_hello() */
112 if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus.Introspectable", "Introspect")) {
114 if (!sd_bus_message_has_signature(m
, ""))
115 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
117 return synthetic_reply_method_return(m
, "s",
118 "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
119 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
121 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
122 " <method name=\"Introspect\">\n"
123 " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
126 " <interface name=\"org.freedesktop.DBus\">\n"
127 " <method name=\"AddMatch\">\n"
128 " <arg type=\"s\" direction=\"in\"/>\n"
130 " <method name=\"RemoveMatch\">\n"
131 " <arg type=\"s\" direction=\"in\"/>\n"
133 " <method name=\"GetConnectionCredentials\">\n"
134 " <arg type=\"s\" direction=\"in\"/>\n"
135 " <arg type=\"a{sv}\" direction=\"out\"/>\n"
137 " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
138 " <arg type=\"s\" direction=\"in\"/>\n"
139 " <arg type=\"ay\" direction=\"out\"/>\n"
141 " <method name=\"GetConnectionUnixProcessID\">\n"
142 " <arg type=\"s\" direction=\"in\"/>\n"
143 " <arg type=\"u\" direction=\"out\"/>\n"
145 " <method name=\"GetConnectionUnixUser\">\n"
146 " <arg type=\"s\" direction=\"in\"/>\n"
147 " <arg type=\"u\" direction=\"out\"/>\n"
149 " <method name=\"GetId\">\n"
150 " <arg type=\"s\" direction=\"out\"/>\n"
152 " <method name=\"GetNameOwner\">\n"
153 " <arg type=\"s\" direction=\"in\"/>\n"
154 " <arg type=\"s\" direction=\"out\"/>\n"
156 " <method name=\"Hello\">\n"
157 " <arg type=\"s\" direction=\"out\"/>\n"
159 " <method name=\"ListActivatableNames\">\n"
160 " <arg type=\"as\" direction=\"out\"/>\n"
162 " <method name=\"ListNames\">\n"
163 " <arg type=\"as\" direction=\"out\"/>\n"
165 " <method name=\"ListQueuedOwners\">\n"
166 " <arg type=\"s\" direction=\"in\"/>\n"
167 " <arg type=\"as\" direction=\"out\"/>\n"
169 " <method name=\"NameHasOwner\">\n"
170 " <arg type=\"s\" direction=\"in\"/>\n"
171 " <arg type=\"b\" direction=\"out\"/>\n"
173 " <method name=\"ReleaseName\">\n"
174 " <arg type=\"s\" direction=\"in\"/>\n"
175 " <arg type=\"u\" direction=\"out\"/>\n"
177 " <method name=\"ReloadConfig\">\n"
179 " <method name=\"RequestName\">\n"
180 " <arg type=\"s\" direction=\"in\"/>\n"
181 " <arg type=\"u\" direction=\"in\"/>\n"
182 " <arg type=\"u\" direction=\"out\"/>\n"
184 " <method name=\"StartServiceByName\">\n"
185 " <arg type=\"s\" direction=\"in\"/>\n"
186 " <arg type=\"u\" direction=\"in\"/>\n"
187 " <arg type=\"u\" direction=\"out\"/>\n"
189 " <method name=\"UpdateActivationEnvironment\">\n"
190 " <arg type=\"a{ss}\" direction=\"in\"/>\n"
192 " <signal name=\"NameAcquired\">\n"
193 " <arg type=\"s\"/>\n"
195 " <signal name=\"NameLost\">\n"
196 " <arg type=\"s\"/>\n"
198 " <signal name=\"NameOwnerChanged\">\n"
199 " <arg type=\"s\"/>\n"
200 " <arg type=\"s\"/>\n"
201 " <arg type=\"s\"/>\n"
206 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "AddMatch")) {
209 if (!sd_bus_message_has_signature(m
, "s"))
210 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
212 r
= sd_bus_message_read(m
, "s", &match
);
214 return synthetic_reply_method_errno(m
, r
, NULL
);
216 r
= sd_bus_add_match(a
, NULL
, match
, proxy_match
, p
);
218 return synthetic_reply_method_errno(m
, r
, NULL
);
220 return synthetic_reply_method_return(m
, NULL
);
222 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RemoveMatch")) {
225 if (!sd_bus_message_has_signature(m
, "s"))
226 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
228 r
= sd_bus_message_read(m
, "s", &match
);
230 return synthetic_reply_method_errno(m
, r
, NULL
);
232 r
= bus_remove_match_by_string(a
, match
, NULL
, NULL
);
234 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND
, "Match rule not found"));
236 return synthetic_reply_method_errno(m
, r
, NULL
);
238 return synthetic_reply_method_return(m
, NULL
);
240 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionCredentials")) {
241 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
242 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
243 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
245 if (!sd_bus_message_has_signature(m
, "s"))
246 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
248 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
250 return synthetic_reply_method_errno(m
, r
, &error
);
252 r
= sd_bus_message_new_method_return(m
, &reply
);
254 return synthetic_reply_method_errno(m
, r
, NULL
);
256 r
= sd_bus_message_open_container(reply
, 'a', "{sv}");
258 return synthetic_reply_method_errno(m
, r
, NULL
);
260 /* Due to i.e. namespace translations some data might be missing */
262 if (creds
->mask
& SD_BUS_CREDS_PID
) {
263 r
= sd_bus_message_append(reply
, "{sv}", "ProcessID", "u", (uint32_t) creds
->pid
);
265 return synthetic_reply_method_errno(m
, r
, NULL
);
268 if (creds
->mask
& SD_BUS_CREDS_EUID
) {
269 r
= sd_bus_message_append(reply
, "{sv}", "UnixUserID", "u", (uint32_t) creds
->euid
);
271 return synthetic_reply_method_errno(m
, r
, NULL
);
274 if (creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
275 r
= sd_bus_message_open_container(reply
, 'e', "sv");
277 return synthetic_reply_method_errno(m
, r
, NULL
);
279 r
= sd_bus_message_append(reply
, "s", "LinuxSecurityLabel");
281 return synthetic_reply_method_errno(m
, r
, NULL
);
283 r
= sd_bus_message_open_container(reply
, 'v', "ay");
285 return synthetic_reply_method_errno(m
, r
, NULL
);
287 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
289 return synthetic_reply_method_errno(m
, r
, NULL
);
291 r
= sd_bus_message_close_container(reply
);
293 return synthetic_reply_method_errno(m
, r
, NULL
);
295 r
= sd_bus_message_close_container(reply
);
297 return synthetic_reply_method_errno(m
, r
, NULL
);
300 r
= sd_bus_message_close_container(reply
);
302 return synthetic_reply_method_errno(m
, r
, NULL
);
304 return synthetic_driver_send(m
->bus
, reply
);
306 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
307 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
308 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
309 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
311 if (!sd_bus_message_has_signature(m
, "s"))
312 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
314 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
316 return synthetic_reply_method_errno(m
, r
, &error
);
318 if (!(creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
319 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
321 r
= sd_bus_message_new_method_return(m
, &reply
);
323 return synthetic_reply_method_errno(m
, r
, NULL
);
325 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
327 return synthetic_reply_method_errno(m
, r
, NULL
);
329 return synthetic_driver_send(m
->bus
, reply
);
331 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
332 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
333 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
335 if (!sd_bus_message_has_signature(m
, "s"))
336 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
338 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
, &creds
, &error
);
340 return synthetic_reply_method_errno(m
, r
, &error
);
342 if (!(creds
->mask
& SD_BUS_CREDS_PID
))
343 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
345 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->pid
);
347 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
348 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
349 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
351 if (!sd_bus_message_has_signature(m
, "s"))
352 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
354 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_EUID
, &creds
, &error
);
356 return synthetic_reply_method_errno(m
, r
, &error
);
358 if (!(creds
->mask
& SD_BUS_CREDS_EUID
))
359 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
361 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->euid
);
363 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetId")) {
364 sd_id128_t server_id
;
365 char buf
[SD_ID128_STRING_MAX
];
367 if (!sd_bus_message_has_signature(m
, ""))
368 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
370 r
= sd_bus_get_bus_id(a
, &server_id
);
372 return synthetic_reply_method_errno(m
, r
, NULL
);
374 return synthetic_reply_method_return(m
, "s", sd_id128_to_string(server_id
, buf
));
376 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetNameOwner")) {
378 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
379 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
381 if (!sd_bus_message_has_signature(m
, "s"))
382 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
384 r
= sd_bus_message_read(m
, "s", &name
);
386 return synthetic_reply_method_errno(m
, r
, NULL
);
388 if (streq(name
, "org.freedesktop.DBus"))
389 return synthetic_reply_method_return(m
, "s", "org.freedesktop.DBus");
391 r
= get_creds_by_name(a
, name
, SD_BUS_CREDS_UNIQUE_NAME
, &creds
, &error
);
393 return synthetic_reply_method_errno(m
, r
, &error
);
395 if (!(creds
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
396 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
398 return synthetic_reply_method_return(m
, "s", creds
->unique_name
);
400 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListActivatableNames")) {
401 _cleanup_strv_free_
char **names
= NULL
;
403 if (!sd_bus_message_has_signature(m
, ""))
404 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
406 r
= sd_bus_list_names(a
, NULL
, &names
);
408 return synthetic_reply_method_errno(m
, r
, NULL
);
410 /* Let's sort the names list to make it stable */
413 return synthetic_reply_method_return_strv(m
, names
);
415 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListNames")) {
416 _cleanup_strv_free_
char **names
= NULL
;
418 if (!sd_bus_message_has_signature(m
, ""))
419 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
421 r
= sd_bus_list_names(a
, &names
, NULL
);
423 return synthetic_reply_method_errno(m
, r
, NULL
);
425 r
= strv_extend(&names
, "org.freedesktop.DBus");
427 return synthetic_reply_method_errno(m
, r
, NULL
);
429 /* Let's sort the names list to make it stable */
432 return synthetic_reply_method_return_strv(m
, names
);
434 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListQueuedOwners")) {
435 struct kdbus_cmd_list cmd
= {
436 .flags
= KDBUS_LIST_QUEUED
,
439 struct kdbus_info
*name_list
, *name
;
440 _cleanup_strv_free_
char **owners
= NULL
;
441 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
445 if (!sd_bus_message_has_signature(m
, "s"))
446 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
448 r
= sd_bus_message_read(m
, "s", &arg0
);
450 return synthetic_reply_method_errno(m
, r
, NULL
);
452 r
= sd_bus_get_name_creds(a
, arg0
, 0, NULL
);
453 if (r
== -ESRCH
|| r
== -ENXIO
) {
454 sd_bus_error_setf(&error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Could not get owners of name '%s': no such name.", arg0
);
455 return synthetic_reply_method_errno(m
, r
, &error
);
458 return synthetic_reply_method_errno(m
, r
, NULL
);
460 r
= ioctl(a
->input_fd
, KDBUS_CMD_LIST
, &cmd
);
462 return synthetic_reply_method_errno(m
, -errno
, NULL
);
464 name_list
= (struct kdbus_info
*) ((uint8_t *) a
->kdbus_buffer
+ cmd
.offset
);
466 KDBUS_FOREACH(name
, name_list
, cmd
.list_size
) {
467 struct kdbus_item
*item
;
470 KDBUS_ITEM_FOREACH(item
, name
, items
) {
471 if (item
->type
== KDBUS_ITEM_OWNED_NAME
) {
472 if (!streq_ptr(item
->name
.name
, arg0
))
475 if (asprintf(&n
, ":1.%llu", (unsigned long long) name
->id
) < 0) {
480 r
= strv_consume(&owners
, n
);
492 r
= bus_kernel_cmd_free(a
, cmd
.offset
);
494 return synthetic_reply_method_errno(m
, r
, NULL
);
497 return synthetic_reply_method_errno(m
, err
, NULL
);
499 return synthetic_reply_method_return_strv(m
, owners
);
501 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "NameHasOwner")) {
504 if (!sd_bus_message_has_signature(m
, "s"))
505 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
507 r
= sd_bus_message_read(m
, "s", &name
);
509 return synthetic_reply_method_errno(m
, r
, NULL
);
511 if (streq(name
, "org.freedesktop.DBus"))
512 return synthetic_reply_method_return(m
, "b", true);
514 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
515 if (r
< 0 && r
!= -ESRCH
&& r
!= -ENXIO
)
516 return synthetic_reply_method_errno(m
, r
, NULL
);
518 return synthetic_reply_method_return(m
, "b", r
>= 0);
520 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReleaseName")) {
523 if (!sd_bus_message_has_signature(m
, "s"))
524 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
526 r
= sd_bus_message_read(m
, "s", &name
);
528 return synthetic_reply_method_errno(m
, r
, NULL
);
530 r
= sd_bus_release_name(a
, name
);
533 return synthetic_reply_method_return(m
, "u", BUS_NAME_NON_EXISTENT
);
534 if (r
== -EADDRINUSE
)
535 return synthetic_reply_method_return(m
, "u", BUS_NAME_NOT_OWNER
);
537 return synthetic_reply_method_errno(m
, r
, NULL
);
540 set_remove(owned_names
, (char*) name
);
542 return synthetic_reply_method_return(m
, "u", BUS_NAME_RELEASED
);
544 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReloadConfig")) {
545 if (!sd_bus_message_has_signature(m
, ""))
546 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
548 r
= shared_policy_reload(sp
);
550 return synthetic_reply_method_errno(m
, r
, NULL
);
552 return synthetic_reply_method_return(m
, NULL
);
554 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RequestName")) {
556 uint32_t flags
, param
;
559 if (!sd_bus_message_has_signature(m
, "su"))
560 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
562 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
564 return synthetic_reply_method_errno(m
, r
, NULL
);
570 policy
= shared_policy_acquire(sp
);
571 denied
= !policy_check_own(policy
, ucred
->uid
, ucred
->gid
, name
);
572 shared_policy_release(sp
, policy
);
574 return synthetic_reply_method_errno(m
, -EPERM
, NULL
);
577 if ((flags
& ~(BUS_NAME_ALLOW_REPLACEMENT
|BUS_NAME_REPLACE_EXISTING
|BUS_NAME_DO_NOT_QUEUE
)) != 0)
578 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
581 if (flags
& BUS_NAME_ALLOW_REPLACEMENT
)
582 param
|= SD_BUS_NAME_ALLOW_REPLACEMENT
;
583 if (flags
& BUS_NAME_REPLACE_EXISTING
)
584 param
|= SD_BUS_NAME_REPLACE_EXISTING
;
585 if (!(flags
& BUS_NAME_DO_NOT_QUEUE
))
586 param
|= SD_BUS_NAME_QUEUE
;
588 r
= set_put_strdup(owned_names
, name
);
590 return synthetic_reply_method_errno(m
, r
, NULL
);
592 r
= sd_bus_request_name(a
, name
, param
);
595 return synthetic_reply_method_return(m
, "u", BUS_NAME_ALREADY_OWNER
);
597 set_remove(owned_names
, (char*) name
);
600 return synthetic_reply_method_return(m
, "u", BUS_NAME_EXISTS
);
601 return synthetic_reply_method_errno(m
, r
, NULL
);
607 return synthetic_reply_method_return(m
, "u", BUS_NAME_IN_QUEUE
);
609 return synthetic_reply_method_return(m
, "u", BUS_NAME_PRIMARY_OWNER
);
611 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "StartServiceByName")) {
612 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
613 ProxyActivation
*activation
;
618 if (!sd_bus_message_has_signature(m
, "su"))
619 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
621 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
623 return synthetic_reply_method_errno(m
, r
, NULL
);
626 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
628 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
629 if (r
>= 0 || streq(name
, "org.freedesktop.DBus"))
630 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_ALREADY_RUNNING
);
632 return synthetic_reply_method_errno(m
, r
, NULL
);
634 if (p
->n_activations
>= PROXY_ACTIVATIONS_MAX
)
635 return synthetic_reply_method_errno(m
, -EMFILE
, NULL
);
637 r
= sd_bus_message_get_cookie(m
, &cookie
);
639 return synthetic_reply_method_errno(m
, r
, NULL
);
641 r
= sd_bus_message_new_method_call(a
,
645 "org.freedesktop.DBus.Peer",
648 return synthetic_reply_method_errno(m
, r
, NULL
);
650 r
= bus_message_seal(msg
, cookie
, BUS_DEFAULT_TIMEOUT
);
652 return synthetic_reply_method_errno(m
, r
, NULL
);
654 activation
= new0(ProxyActivation
, 1);
656 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
658 r
= sd_bus_call_async(a
,
666 return synthetic_reply_method_errno(m
, r
, NULL
);
669 activation
->proxy
= p
;
670 activation
->request
= sd_bus_message_ref(m
);
671 LIST_PREPEND(activations_by_proxy
, p
->activations
, activation
);
675 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
676 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
677 _cleanup_strv_free_
char **args
= NULL
;
679 if (!sd_bus_message_has_signature(m
, "a{ss}"))
680 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
682 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{ss}");
684 return synthetic_reply_method_errno(m
, r
, NULL
);
686 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "ss")) > 0) {
687 _cleanup_free_
char *s
= NULL
;
691 r
= sd_bus_message_read(m
, "ss", &key
, &value
);
693 return synthetic_reply_method_errno(m
, r
, NULL
);
695 s
= strjoin(key
, "=", value
, NULL
);
697 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
699 if (!env_assignment_is_valid(s
)) {
700 log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s
);
702 r
= strv_extend(&args
, s
);
704 return synthetic_reply_method_errno(m
, r
, NULL
);
707 r
= sd_bus_message_exit_container(m
);
709 return synthetic_reply_method_errno(m
, r
, NULL
);
712 r
= sd_bus_message_exit_container(m
);
714 return synthetic_reply_method_errno(m
, r
, NULL
);
716 if (strv_isempty(args
)) /* nothing to do? */
717 return synthetic_reply_method_return(m
, NULL
);
719 r
= sd_bus_message_new_method_call(
722 "org.freedesktop.systemd1",
723 "/org/freedesktop/systemd1",
724 "org.freedesktop.systemd1.Manager",
727 return synthetic_reply_method_errno(m
, r
, NULL
);
729 r
= sd_bus_message_append_strv(msg
, args
);
731 return synthetic_reply_method_errno(m
, r
, NULL
);
733 r
= sd_bus_call(a
, msg
, 0, NULL
, NULL
);
735 return synthetic_reply_method_errno(m
, r
, NULL
);
737 return synthetic_reply_method_return(m
, NULL
);
740 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
742 r
= sd_bus_error_setf(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
, "Unknown method '%s'.", m
->member
);
744 return synthetic_reply_method_errno(m
, r
, &error
);