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"
40 static int get_creds_by_name(sd_bus
*bus
, const char *name
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
41 _cleanup_bus_creds_unref_ sd_bus_creds
*c
= NULL
;
48 r
= sd_bus_get_name_creds(bus
, name
, mask
, &c
);
49 if (r
== -ESRCH
|| r
== -ENXIO
)
50 return sd_bus_error_setf(error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Name %s is currently not owned by anyone.", name
);
60 static int get_creds_by_message(sd_bus
*bus
, sd_bus_message
*m
, uint64_t mask
, sd_bus_creds
**_creds
, sd_bus_error
*error
) {
68 r
= sd_bus_message_read(m
, "s", &name
);
72 return get_creds_by_name(bus
, name
, mask
, _creds
, error
);
75 static int driver_activation(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
76 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
77 ProxyActivation
*activation
= userdata
;
80 * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
81 * whether this succeeded, failed, was not implemented or timed out. We
82 * cannot assume that the target reacts to this properly. Hence, just
83 * send the reply to the activation request and be done.
86 m
= activation
->request
; /* claim reference */
88 --activation
->proxy
->n_activations
;
89 LIST_REMOVE(activations_by_proxy
, activation
->proxy
->activations
, activation
);
90 sd_bus_slot_unref(activation
->slot
);
93 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_SUCCESS
);
96 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
) {
106 if (!streq_ptr(sd_bus_message_get_destination(m
), "org.freedesktop.DBus"))
109 /* The "Hello()" call is is handled in process_hello() */
111 if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus.Introspectable", "Introspect")) {
113 if (!sd_bus_message_has_signature(m
, ""))
114 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
116 return synthetic_reply_method_return(m
, "s",
117 "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
118 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
120 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
121 " <method name=\"Introspect\">\n"
122 " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
125 " <interface name=\"org.freedesktop.DBus\">\n"
126 " <method name=\"AddMatch\">\n"
127 " <arg type=\"s\" direction=\"in\"/>\n"
129 " <method name=\"RemoveMatch\">\n"
130 " <arg type=\"s\" direction=\"in\"/>\n"
132 " <method name=\"GetConnectionCredentials\">\n"
133 " <arg type=\"s\" direction=\"in\"/>\n"
134 " <arg type=\"a{sv}\" direction=\"out\"/>\n"
136 " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
137 " <arg type=\"s\" direction=\"in\"/>\n"
138 " <arg type=\"ay\" direction=\"out\"/>\n"
140 " <method name=\"GetConnectionUnixProcessID\">\n"
141 " <arg type=\"s\" direction=\"in\"/>\n"
142 " <arg type=\"u\" direction=\"out\"/>\n"
144 " <method name=\"GetConnectionUnixUser\">\n"
145 " <arg type=\"s\" direction=\"in\"/>\n"
146 " <arg type=\"u\" direction=\"out\"/>\n"
148 " <method name=\"GetId\">\n"
149 " <arg type=\"s\" direction=\"out\"/>\n"
151 " <method name=\"GetNameOwner\">\n"
152 " <arg type=\"s\" direction=\"in\"/>\n"
153 " <arg type=\"s\" direction=\"out\"/>\n"
155 " <method name=\"Hello\">\n"
156 " <arg type=\"s\" direction=\"out\"/>\n"
158 " <method name=\"ListActivatableNames\">\n"
159 " <arg type=\"as\" direction=\"out\"/>\n"
161 " <method name=\"ListNames\">\n"
162 " <arg type=\"as\" direction=\"out\"/>\n"
164 " <method name=\"ListQueuedOwners\">\n"
165 " <arg type=\"s\" direction=\"in\"/>\n"
166 " <arg type=\"as\" direction=\"out\"/>\n"
168 " <method name=\"NameHasOwner\">\n"
169 " <arg type=\"s\" direction=\"in\"/>\n"
170 " <arg type=\"b\" direction=\"out\"/>\n"
172 " <method name=\"ReleaseName\">\n"
173 " <arg type=\"s\" direction=\"in\"/>\n"
174 " <arg type=\"u\" direction=\"out\"/>\n"
176 " <method name=\"ReloadConfig\">\n"
178 " <method name=\"RequestName\">\n"
179 " <arg type=\"s\" direction=\"in\"/>\n"
180 " <arg type=\"u\" direction=\"in\"/>\n"
181 " <arg type=\"u\" direction=\"out\"/>\n"
183 " <method name=\"StartServiceByName\">\n"
184 " <arg type=\"s\" direction=\"in\"/>\n"
185 " <arg type=\"u\" direction=\"in\"/>\n"
186 " <arg type=\"u\" direction=\"out\"/>\n"
188 " <method name=\"UpdateActivationEnvironment\">\n"
189 " <arg type=\"a{ss}\" direction=\"in\"/>\n"
191 " <signal name=\"NameAcquired\">\n"
192 " <arg type=\"s\"/>\n"
194 " <signal name=\"NameLost\">\n"
195 " <arg type=\"s\"/>\n"
197 " <signal name=\"NameOwnerChanged\">\n"
198 " <arg type=\"s\"/>\n"
199 " <arg type=\"s\"/>\n"
200 " <arg type=\"s\"/>\n"
205 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "AddMatch")) {
208 if (!sd_bus_message_has_signature(m
, "s"))
209 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
211 r
= sd_bus_message_read(m
, "s", &match
);
213 return synthetic_reply_method_errno(m
, r
, NULL
);
215 r
= sd_bus_add_match(a
, NULL
, match
, proxy_match
, p
);
217 return synthetic_reply_method_errno(m
, r
, NULL
);
219 return synthetic_reply_method_return(m
, NULL
);
221 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RemoveMatch")) {
224 if (!sd_bus_message_has_signature(m
, "s"))
225 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
227 r
= sd_bus_message_read(m
, "s", &match
);
229 return synthetic_reply_method_errno(m
, r
, NULL
);
231 r
= bus_remove_match_by_string(a
, match
, NULL
, NULL
);
233 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND
, "Match rule not found"));
235 return synthetic_reply_method_errno(m
, r
, NULL
);
237 return synthetic_reply_method_return(m
, NULL
);
239 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionCredentials")) {
240 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
241 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
242 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
244 if (!sd_bus_message_has_signature(m
, "s"))
245 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
247 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
249 return synthetic_reply_method_errno(m
, r
, &error
);
251 r
= sd_bus_message_new_method_return(m
, &reply
);
253 return synthetic_reply_method_errno(m
, r
, NULL
);
255 r
= sd_bus_message_open_container(reply
, 'a', "{sv}");
257 return synthetic_reply_method_errno(m
, r
, NULL
);
259 /* Due to i.e. namespace translations some data might be missing */
261 if (creds
->mask
& SD_BUS_CREDS_PID
) {
262 r
= sd_bus_message_append(reply
, "{sv}", "ProcessID", "u", (uint32_t) creds
->pid
);
264 return synthetic_reply_method_errno(m
, r
, NULL
);
267 if (creds
->mask
& SD_BUS_CREDS_EUID
) {
268 r
= sd_bus_message_append(reply
, "{sv}", "UnixUserID", "u", (uint32_t) creds
->euid
);
270 return synthetic_reply_method_errno(m
, r
, NULL
);
273 if (creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
274 r
= sd_bus_message_open_container(reply
, 'e', "sv");
276 return synthetic_reply_method_errno(m
, r
, NULL
);
278 r
= sd_bus_message_append(reply
, "s", "LinuxSecurityLabel");
280 return synthetic_reply_method_errno(m
, r
, NULL
);
282 r
= sd_bus_message_open_container(reply
, 'v', "ay");
284 return synthetic_reply_method_errno(m
, r
, NULL
);
286 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
288 return synthetic_reply_method_errno(m
, r
, NULL
);
290 r
= sd_bus_message_close_container(reply
);
292 return synthetic_reply_method_errno(m
, r
, NULL
);
294 r
= sd_bus_message_close_container(reply
);
296 return synthetic_reply_method_errno(m
, r
, NULL
);
299 r
= sd_bus_message_close_container(reply
);
301 return synthetic_reply_method_errno(m
, r
, NULL
);
303 return synthetic_driver_send(m
->bus
, reply
);
305 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
306 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
307 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
308 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
310 if (!sd_bus_message_has_signature(m
, "s"))
311 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
313 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_SELINUX_CONTEXT
, &creds
, &error
);
315 return synthetic_reply_method_errno(m
, r
, &error
);
317 if (!(creds
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
318 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
320 r
= sd_bus_message_new_method_return(m
, &reply
);
322 return synthetic_reply_method_errno(m
, r
, NULL
);
324 r
= sd_bus_message_append_array(reply
, 'y', creds
->label
, strlen(creds
->label
));
326 return synthetic_reply_method_errno(m
, r
, NULL
);
328 return synthetic_driver_send(m
->bus
, reply
);
330 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
331 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
332 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
334 if (!sd_bus_message_has_signature(m
, "s"))
335 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
337 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_PID
, &creds
, &error
);
339 return synthetic_reply_method_errno(m
, r
, &error
);
341 if (!(creds
->mask
& SD_BUS_CREDS_PID
))
342 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
344 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->pid
);
346 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
347 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
348 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
350 if (!sd_bus_message_has_signature(m
, "s"))
351 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
353 r
= get_creds_by_message(a
, m
, SD_BUS_CREDS_EUID
, &creds
, &error
);
355 return synthetic_reply_method_errno(m
, r
, &error
);
357 if (!(creds
->mask
& SD_BUS_CREDS_EUID
))
358 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
360 return synthetic_reply_method_return(m
, "u", (uint32_t) creds
->euid
);
362 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetId")) {
363 sd_id128_t server_id
;
364 char buf
[SD_ID128_STRING_MAX
];
366 if (!sd_bus_message_has_signature(m
, ""))
367 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
369 r
= sd_bus_get_bus_id(a
, &server_id
);
371 return synthetic_reply_method_errno(m
, r
, NULL
);
373 return synthetic_reply_method_return(m
, "s", sd_id128_to_string(server_id
, buf
));
375 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "GetNameOwner")) {
377 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
378 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
380 if (!sd_bus_message_has_signature(m
, "s"))
381 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
383 r
= sd_bus_message_read(m
, "s", &name
);
385 return synthetic_reply_method_errno(m
, r
, NULL
);
387 if (streq(name
, "org.freedesktop.DBus"))
388 return synthetic_reply_method_return(m
, "s", "org.freedesktop.DBus");
390 r
= get_creds_by_name(a
, name
, SD_BUS_CREDS_UNIQUE_NAME
, &creds
, &error
);
392 return synthetic_reply_method_errno(m
, r
, &error
);
394 if (!(creds
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
395 return synthetic_reply_method_errno(m
, -EOPNOTSUPP
, NULL
);
397 return synthetic_reply_method_return(m
, "s", creds
->unique_name
);
399 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListActivatableNames")) {
400 _cleanup_strv_free_
char **names
= NULL
;
402 if (!sd_bus_message_has_signature(m
, ""))
403 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
405 r
= sd_bus_list_names(a
, NULL
, &names
);
407 return synthetic_reply_method_errno(m
, r
, NULL
);
409 /* Let's sort the names list to make it stable */
412 return synthetic_reply_method_return_strv(m
, names
);
414 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListNames")) {
415 _cleanup_strv_free_
char **names
= NULL
;
417 if (!sd_bus_message_has_signature(m
, ""))
418 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
420 r
= sd_bus_list_names(a
, &names
, NULL
);
422 return synthetic_reply_method_errno(m
, r
, NULL
);
424 r
= strv_extend(&names
, "org.freedesktop.DBus");
426 return synthetic_reply_method_errno(m
, r
, NULL
);
428 /* Let's sort the names list to make it stable */
431 return synthetic_reply_method_return_strv(m
, names
);
433 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ListQueuedOwners")) {
434 struct kdbus_cmd_list cmd
= {
435 .flags
= KDBUS_LIST_QUEUED
,
438 struct kdbus_info
*name_list
, *name
;
439 _cleanup_strv_free_
char **owners
= NULL
;
440 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
444 if (!sd_bus_message_has_signature(m
, "s"))
445 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
447 r
= sd_bus_message_read(m
, "s", &arg0
);
449 return synthetic_reply_method_errno(m
, r
, NULL
);
451 r
= sd_bus_get_name_creds(a
, arg0
, 0, NULL
);
452 if (r
== -ESRCH
|| r
== -ENXIO
) {
453 sd_bus_error_setf(&error
, SD_BUS_ERROR_NAME_HAS_NO_OWNER
, "Could not get owners of name '%s': no such name.", arg0
);
454 return synthetic_reply_method_errno(m
, r
, &error
);
457 return synthetic_reply_method_errno(m
, r
, NULL
);
459 r
= ioctl(a
->input_fd
, KDBUS_CMD_LIST
, &cmd
);
461 return synthetic_reply_method_errno(m
, -errno
, NULL
);
463 name_list
= (struct kdbus_info
*) ((uint8_t *) a
->kdbus_buffer
+ cmd
.offset
);
465 KDBUS_FOREACH(name
, name_list
, cmd
.list_size
) {
466 struct kdbus_item
*item
;
469 KDBUS_ITEM_FOREACH(item
, name
, items
) {
470 if (item
->type
== KDBUS_ITEM_OWNED_NAME
) {
471 if (!streq_ptr(item
->name
.name
, arg0
))
474 if (asprintf(&n
, ":1.%llu", (unsigned long long) name
->id
) < 0) {
479 r
= strv_consume(&owners
, n
);
491 r
= bus_kernel_cmd_free(a
, cmd
.offset
);
493 return synthetic_reply_method_errno(m
, r
, NULL
);
496 return synthetic_reply_method_errno(m
, err
, NULL
);
498 return synthetic_reply_method_return_strv(m
, owners
);
500 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "NameHasOwner")) {
503 if (!sd_bus_message_has_signature(m
, "s"))
504 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
506 r
= sd_bus_message_read(m
, "s", &name
);
508 return synthetic_reply_method_errno(m
, r
, NULL
);
510 if (streq(name
, "org.freedesktop.DBus"))
511 return synthetic_reply_method_return(m
, "b", true);
513 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
514 if (r
< 0 && r
!= -ESRCH
&& r
!= -ENXIO
)
515 return synthetic_reply_method_errno(m
, r
, NULL
);
517 return synthetic_reply_method_return(m
, "b", r
>= 0);
519 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReleaseName")) {
522 if (!sd_bus_message_has_signature(m
, "s"))
523 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
525 r
= sd_bus_message_read(m
, "s", &name
);
527 return synthetic_reply_method_errno(m
, r
, NULL
);
529 r
= sd_bus_release_name(a
, name
);
532 return synthetic_reply_method_return(m
, "u", BUS_NAME_NON_EXISTENT
);
533 if (r
== -EADDRINUSE
)
534 return synthetic_reply_method_return(m
, "u", BUS_NAME_NOT_OWNER
);
536 return synthetic_reply_method_errno(m
, r
, NULL
);
539 set_remove(owned_names
, (char*) name
);
541 return synthetic_reply_method_return(m
, "u", BUS_NAME_RELEASED
);
543 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "ReloadConfig")) {
544 if (!sd_bus_message_has_signature(m
, ""))
545 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
547 r
= shared_policy_reload(sp
);
549 return synthetic_reply_method_errno(m
, r
, NULL
);
551 return synthetic_reply_method_return(m
, NULL
);
553 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "RequestName")) {
555 uint32_t flags
, param
;
558 if (!sd_bus_message_has_signature(m
, "su"))
559 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
561 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
563 return synthetic_reply_method_errno(m
, r
, NULL
);
569 policy
= shared_policy_acquire(sp
);
570 denied
= !policy_check_own(policy
, ucred
->uid
, ucred
->gid
, name
);
571 shared_policy_release(sp
, policy
);
573 return synthetic_reply_method_errno(m
, -EPERM
, NULL
);
576 if ((flags
& ~(BUS_NAME_ALLOW_REPLACEMENT
|BUS_NAME_REPLACE_EXISTING
|BUS_NAME_DO_NOT_QUEUE
)) != 0)
577 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
580 if (flags
& BUS_NAME_ALLOW_REPLACEMENT
)
581 param
|= SD_BUS_NAME_ALLOW_REPLACEMENT
;
582 if (flags
& BUS_NAME_REPLACE_EXISTING
)
583 param
|= SD_BUS_NAME_REPLACE_EXISTING
;
584 if (!(flags
& BUS_NAME_DO_NOT_QUEUE
))
585 param
|= SD_BUS_NAME_QUEUE
;
587 r
= set_put_strdup(owned_names
, name
);
589 return synthetic_reply_method_errno(m
, r
, NULL
);
591 r
= sd_bus_request_name(a
, name
, param
);
594 return synthetic_reply_method_return(m
, "u", BUS_NAME_ALREADY_OWNER
);
596 set_remove(owned_names
, (char*) name
);
599 return synthetic_reply_method_return(m
, "u", BUS_NAME_EXISTS
);
600 return synthetic_reply_method_errno(m
, r
, NULL
);
606 return synthetic_reply_method_return(m
, "u", BUS_NAME_IN_QUEUE
);
608 return synthetic_reply_method_return(m
, "u", BUS_NAME_PRIMARY_OWNER
);
610 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "StartServiceByName")) {
611 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
612 ProxyActivation
*activation
;
617 if (!sd_bus_message_has_signature(m
, "su"))
618 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
620 r
= sd_bus_message_read(m
, "su", &name
, &flags
);
622 return synthetic_reply_method_errno(m
, r
, NULL
);
625 return synthetic_reply_method_errno(m
, -EINVAL
, NULL
);
627 r
= sd_bus_get_name_creds(a
, name
, 0, NULL
);
628 if (r
>= 0 || streq(name
, "org.freedesktop.DBus"))
629 return synthetic_reply_method_return(m
, "u", BUS_START_REPLY_ALREADY_RUNNING
);
631 return synthetic_reply_method_errno(m
, r
, NULL
);
633 if (p
->n_activations
>= PROXY_ACTIVATIONS_MAX
)
634 return synthetic_reply_method_errno(m
, -EMFILE
, NULL
);
636 r
= sd_bus_message_get_cookie(m
, &cookie
);
638 return synthetic_reply_method_errno(m
, r
, NULL
);
640 r
= sd_bus_message_new_method_call(a
,
644 "org.freedesktop.DBus.Peer",
647 return synthetic_reply_method_errno(m
, r
, NULL
);
649 r
= bus_message_seal(msg
, cookie
, BUS_DEFAULT_TIMEOUT
);
651 return synthetic_reply_method_errno(m
, r
, NULL
);
653 activation
= new0(ProxyActivation
, 1);
655 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
657 r
= sd_bus_call_async(a
,
665 return synthetic_reply_method_errno(m
, r
, NULL
);
668 activation
->proxy
= p
;
669 activation
->request
= sd_bus_message_ref(m
);
670 LIST_PREPEND(activations_by_proxy
, p
->activations
, activation
);
674 } else if (sd_bus_message_is_method_call(m
, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
675 _cleanup_bus_message_unref_ sd_bus_message
*msg
= NULL
;
676 _cleanup_strv_free_
char **args
= NULL
;
678 if (!sd_bus_message_has_signature(m
, "a{ss}"))
679 return synthetic_reply_method_error(m
, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS
, "Invalid parameters"));
681 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{ss}");
683 return synthetic_reply_method_errno(m
, r
, NULL
);
685 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "ss")) > 0) {
686 _cleanup_free_
char *s
= NULL
;
690 r
= sd_bus_message_read(m
, "ss", &key
, &value
);
692 return synthetic_reply_method_errno(m
, r
, NULL
);
694 s
= strjoin(key
, "=", value
, NULL
);
696 return synthetic_reply_method_errno(m
, -ENOMEM
, NULL
);
698 if (!env_assignment_is_valid(s
)) {
699 log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s
);
701 r
= strv_extend(&args
, s
);
703 return synthetic_reply_method_errno(m
, r
, NULL
);
706 r
= sd_bus_message_exit_container(m
);
708 return synthetic_reply_method_errno(m
, r
, NULL
);
711 r
= sd_bus_message_exit_container(m
);
713 return synthetic_reply_method_errno(m
, r
, NULL
);
715 if (strv_isempty(args
)) /* nothing to do? */
716 return synthetic_reply_method_return(m
, NULL
);
718 r
= sd_bus_message_new_method_call(
721 "org.freedesktop.systemd1",
722 "/org/freedesktop/systemd1",
723 "org.freedesktop.systemd1.Manager",
726 return synthetic_reply_method_errno(m
, r
, NULL
);
728 r
= sd_bus_message_append_strv(msg
, args
);
730 return synthetic_reply_method_errno(m
, r
, NULL
);
732 r
= sd_bus_call(a
, msg
, 0, NULL
, NULL
);
734 return synthetic_reply_method_errno(m
, r
, NULL
);
736 return synthetic_reply_method_return(m
, NULL
);
739 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
741 r
= sd_bus_error_setf(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
, "Unknown method '%s'.", m
->member
);
743 return synthetic_reply_method_errno(m
, r
, &error
);