1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
22 #include <sys/socket.h>
23 #include <sys/capability.h>
29 #include "path-util.h"
34 #include "bus-error.h"
35 #include "bus-message.h"
37 #include "bus-internal.h"
39 static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
40 sd_event *e = userdata;
52 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
53 _cleanup_free_ char *match = NULL;
61 /* We unregister the name here and then wait for the
62 * NameOwnerChanged signal for this event to arrive before we
63 * quit. We do this in order to make sure that any queued
64 * requests are still processed before we really exit. */
66 r = sd_bus_get_unique_name(bus, &unique);
71 "sender='org.freedesktop.DBus',"
73 "interface='org.freedesktop.DBus',"
74 "member='NameOwnerChanged',"
75 "path='/org/freedesktop/DBus',"
78 "arg2=''", name, unique);
82 r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
86 r = sd_bus_release_name(bus, name);
93 int bus_event_loop_with_idle(
98 check_idle_t check_idle,
100 bool exiting = false;
110 r = sd_event_get_state(e);
113 if (r == SD_EVENT_FINISHED)
117 idle = check_idle(userdata);
121 r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
125 if (r == 0 && !exiting) {
127 r = sd_bus_try_close(bus);
132 /* Fallback for dbus1 connections: we
133 * unregister the name and wait for
134 * the response to come through for
137 r = bus_async_unregister_and_exit(e, bus, name);
153 r = sd_event_get_exit_code(e, &code);
160 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
161 _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
162 int r, has_owner = 0;
167 r = sd_bus_call_method(c,
168 "org.freedesktop.DBus",
169 "/org/freedesktop/dbus",
170 "org.freedesktop.DBus",
179 r = sd_bus_message_read_basic(rep, 'b', &has_owner);
181 return sd_bus_error_set_errno(error, r);
186 int bus_verify_polkit(
187 sd_bus_message *call,
199 r = sd_bus_query_sender_privilege(call, capability);
206 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
207 int authorized = false, challenge = false;
210 sender = sd_bus_message_get_sender(call);
214 r = sd_bus_call_method(
216 "org.freedesktop.PolicyKit1",
217 "/org/freedesktop/PolicyKit1/Authority",
218 "org.freedesktop.PolicyKit1.Authority",
219 "CheckAuthorization",
223 "system-bus-name", 1, "name", "s", sender,
230 /* Treat no PK available as access denied */
231 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
232 sd_bus_error_free(e);
239 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
243 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
251 *_challenge = challenge;
262 typedef struct AsyncPolkitQuery {
263 sd_bus_message *request, *reply;
264 sd_bus_message_handler_t callback;
270 static void async_polkit_query_free(AsyncPolkitQuery *q) {
275 sd_bus_slot_unref(q->slot);
277 if (q->registry && q->request)
278 hashmap_remove(q->registry, q->request);
280 sd_bus_message_unref(q->request);
281 sd_bus_message_unref(q->reply);
286 static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
287 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
288 AsyncPolkitQuery *q = userdata;
295 q->slot = sd_bus_slot_unref(q->slot);
296 q->reply = sd_bus_message_ref(reply);
298 r = sd_bus_message_rewind(q->request, true);
300 r = sd_bus_reply_method_errno(q->request, r, NULL);
304 r = q->callback(bus, q->request, q->userdata, &error_buffer);
305 r = bus_maybe_reply_error(q->request, r, &error_buffer);
308 async_polkit_query_free(q);
315 int bus_verify_polkit_async(
316 sd_bus_message *call,
321 sd_bus_error *error) {
324 _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
325 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
328 sd_bus_message_handler_t callback;
338 q = hashmap_get(*registry, call);
340 int authorized, challenge;
342 /* This is the second invocation of this function, and
343 * there's already a response from polkit, let's
347 if (sd_bus_message_is_method_error(q->reply, NULL)) {
348 const sd_bus_error *e;
350 /* Copy error from polkit reply */
351 e = sd_bus_message_get_error(q->reply);
352 sd_bus_error_copy(error, e);
354 /* Treat no PK available as access denied */
355 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
358 return -sd_bus_error_get_errno(e);
361 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
363 r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
375 r = sd_bus_query_sender_privilege(call, capability);
382 if (sd_bus_get_current_message(call->bus) != call)
385 callback = sd_bus_get_current_handler(call->bus);
389 userdata = sd_bus_get_current_userdata(call->bus);
391 sender = sd_bus_message_get_sender(call);
395 r = hashmap_ensure_allocated(registry, trivial_hash_func, trivial_compare_func);
399 r = sd_bus_message_new_method_call(
402 "org.freedesktop.PolicyKit1",
403 "/org/freedesktop/PolicyKit1/Authority",
404 "org.freedesktop.PolicyKit1.Authority",
405 "CheckAuthorization");
409 r = sd_bus_message_append(
412 "system-bus-name", 1, "name", "s", sender,
420 q = new0(AsyncPolkitQuery, 1);
424 q->request = sd_bus_message_ref(call);
425 q->callback = callback;
426 q->userdata = userdata;
428 r = hashmap_put(*registry, call, q);
430 async_polkit_query_free(q);
434 q->registry = *registry;
436 r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
438 async_polkit_query_free(q);
448 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
452 while ((q = hashmap_steal_first(registry)))
453 async_polkit_query_free(q);
455 hashmap_free(registry);
459 int bus_check_peercred(sd_bus *c) {
466 fd = sd_bus_get_fd(c);
470 l = sizeof(struct ucred);
471 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
474 if (l != sizeof(struct ucred))
477 if (ucred.uid != 0 && ucred.uid != geteuid())
483 int bus_open_system_systemd(sd_bus **_bus) {
484 _cleanup_bus_unref_ sd_bus *bus = NULL;
490 return sd_bus_open_system(_bus);
492 /* If we are root and kdbus is not available, then let's talk
493 * directly to the system instance, instead of going via the
497 r = sd_bus_new(&bus);
501 r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_PATH);
505 bus->bus_client = true;
507 r = sd_bus_start(bus);
514 bus = sd_bus_unref(bus);
517 r = sd_bus_new(&bus);
521 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
525 r = sd_bus_start(bus);
527 return sd_bus_open_system(_bus);
529 r = bus_check_peercred(bus);
539 int bus_open_user_systemd(sd_bus **_bus) {
540 _cleanup_bus_unref_ sd_bus *bus = NULL;
541 _cleanup_free_ char *ee = NULL;
545 /* Try via kdbus first, and then directly */
550 r = sd_bus_new(&bus);
554 if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, getuid()) < 0)
557 bus->bus_client = true;
559 r = sd_bus_start(bus);
566 bus = sd_bus_unref(bus);
569 e = secure_getenv("XDG_RUNTIME_DIR");
571 return sd_bus_open_user(_bus);
573 ee = bus_address_escape(e);
577 r = sd_bus_new(&bus);
581 bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
585 r = sd_bus_start(bus);
587 return sd_bus_open_user(_bus);
589 r = bus_check_peercred(bus);
599 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
601 const char *contents;
607 r = sd_bus_message_peek_type(property, &type, &contents);
613 case SD_BUS_TYPE_STRING: {
616 r = sd_bus_message_read_basic(property, type, &s);
620 if (all || !isempty(s))
621 printf("%s=%s\n", name, s);
626 case SD_BUS_TYPE_BOOLEAN: {
629 r = sd_bus_message_read_basic(property, type, &b);
633 printf("%s=%s\n", name, yes_no(b));
638 case SD_BUS_TYPE_UINT64: {
641 r = sd_bus_message_read_basic(property, type, &u);
645 /* Yes, heuristics! But we can change this check
646 * should it turn out to not be sufficient */
648 if (endswith(name, "Timestamp")) {
649 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
651 t = format_timestamp(timestamp, sizeof(timestamp), u);
653 printf("%s=%s\n", name, strempty(t));
655 } else if (strstr(name, "USec")) {
656 char timespan[FORMAT_TIMESPAN_MAX];
658 printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
660 printf("%s=%llu\n", name, (unsigned long long) u);
665 case SD_BUS_TYPE_UINT32: {
668 r = sd_bus_message_read_basic(property, type, &u);
672 if (strstr(name, "UMask") || strstr(name, "Mode"))
673 printf("%s=%04o\n", name, u);
675 printf("%s=%u\n", name, (unsigned) u);
680 case SD_BUS_TYPE_INT32: {
683 r = sd_bus_message_read_basic(property, type, &i);
687 printf("%s=%i\n", name, (int) i);
691 case SD_BUS_TYPE_DOUBLE: {
694 r = sd_bus_message_read_basic(property, type, &d);
698 printf("%s=%g\n", name, d);
702 case SD_BUS_TYPE_ARRAY:
703 if (streq(contents, "s")) {
707 r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
711 while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
715 printf("%s%s", first ? "" : " ", str);
727 r = sd_bus_message_exit_container(property);
733 } else if (streq(contents, "y")) {
737 r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
746 for (i = 0; i < n; i++)
747 printf("%02x", u[i]);
754 } else if (streq(contents, "u")) {
758 r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
767 for (i = 0; i < n; i++)
768 printf("%08x", u[i]);
782 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
783 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
784 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
790 r = sd_bus_call_method(bus,
793 "org.freedesktop.DBus.Properties",
801 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
805 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
807 const char *contents;
809 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
813 if (!filter || strv_find(filter, name)) {
814 r = sd_bus_message_peek_type(reply, NULL, &contents);
818 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
822 r = bus_print_property(name, reply, all);
827 printf("%s=[unprintable]\n", name);
828 /* skip what we didn't read */
829 r = sd_bus_message_skip(reply, contents);
834 r = sd_bus_message_exit_container(reply);
838 r = sd_bus_message_skip(reply, "v");
843 r = sd_bus_message_exit_container(reply);
850 r = sd_bus_message_exit_container(reply);
857 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
858 sd_id128_t *p = userdata;
863 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
870 memcpy((*p).bytes, v, n);
877 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
881 r = sd_bus_message_peek_type(m, &type, NULL);
886 case SD_BUS_TYPE_STRING: {
891 r = sd_bus_message_read_basic(m, type, &s);
909 case SD_BUS_TYPE_ARRAY: {
910 _cleanup_strv_free_ char **l = NULL;
911 char ***p = userdata;
913 r = bus_message_read_strv_extend(m, &l);
924 case SD_BUS_TYPE_BOOLEAN: {
928 r = sd_bus_message_read_basic(m, type, &b);
937 case SD_BUS_TYPE_UINT32: {
939 uint32_t *p = userdata;
941 r = sd_bus_message_read_basic(m, type, &u);
950 case SD_BUS_TYPE_UINT64: {
952 uint64_t *p = userdata;
954 r = sd_bus_message_read_basic(m, type, &t);
970 int bus_map_all_properties(sd_bus *bus,
971 const char *destination,
973 const struct bus_properties_map *map,
975 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
976 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
984 r = sd_bus_call_method(
988 "org.freedesktop.DBus.Properties",
996 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1000 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1001 const struct bus_properties_map *prop;
1003 const char *contents;
1007 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1011 for (i = 0, prop = NULL; map[i].member; i++)
1012 if (streq(map[i].member, member)) {
1018 r = sd_bus_message_peek_type(m, NULL, &contents);
1022 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1026 v = (uint8_t *)userdata + prop->offset;
1028 r = prop->set(bus, member, m, &error, v);
1030 r = map_basic(bus, member, m, &error, v);
1034 r = sd_bus_message_exit_container(m);
1038 r = sd_bus_message_skip(m, "v");
1043 r = sd_bus_message_exit_container(m);
1051 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1054 assert(transport >= 0);
1055 assert(transport < _BUS_TRANSPORT_MAX);
1058 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1059 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP);
1061 switch (transport) {
1063 case BUS_TRANSPORT_LOCAL:
1065 r = sd_bus_default_user(bus);
1067 r = sd_bus_default_system(bus);
1071 case BUS_TRANSPORT_REMOTE:
1072 r = sd_bus_open_system_remote(bus, host);
1075 case BUS_TRANSPORT_CONTAINER:
1076 r = sd_bus_open_system_container(bus, host);
1080 assert_not_reached("Hmm, unknown transport type.");
1086 int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1089 assert(transport >= 0);
1090 assert(transport < _BUS_TRANSPORT_MAX);
1093 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1094 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP);
1096 switch (transport) {
1098 case BUS_TRANSPORT_LOCAL:
1100 r = bus_open_user_systemd(bus);
1102 r = bus_open_system_systemd(bus);
1106 case BUS_TRANSPORT_REMOTE:
1107 r = sd_bus_open_system_remote(bus, host);
1110 case BUS_TRANSPORT_CONTAINER:
1111 r = sd_bus_open_system_container(bus, host);
1115 assert_not_reached("Hmm, unknown transport type.");
1121 int bus_property_get_bool(
1124 const char *interface,
1125 const char *property,
1126 sd_bus_message *reply,
1128 sd_bus_error *error) {
1130 int b = *(bool*) userdata;
1132 return sd_bus_message_append_basic(reply, 'b', &b);
1135 #if __SIZEOF_SIZE_T__ != 8
1136 int bus_property_get_size(
1139 const char *interface,
1140 const char *property,
1141 sd_bus_message *reply,
1143 sd_bus_error *error) {
1145 uint64_t sz = *(size_t*) userdata;
1147 return sd_bus_message_append_basic(reply, 't', &sz);
1151 #if __SIZEOF_LONG__ != 8
1152 int bus_property_get_long(
1155 const char *interface,
1156 const char *property,
1157 sd_bus_message *reply,
1159 sd_bus_error *error) {
1161 int64_t l = *(long*) userdata;
1163 return sd_bus_message_append_basic(reply, 'x', &l);
1166 int bus_property_get_ulong(
1169 const char *interface,
1170 const char *property,
1171 sd_bus_message *reply,
1173 sd_bus_error *error) {
1175 uint64_t ul = *(unsigned long*) userdata;
1177 return sd_bus_message_append_basic(reply, 't', &ul);
1181 int bus_log_parse_error(int r) {
1182 log_error("Failed to parse bus message: %s", strerror(-r));
1186 int bus_log_create_error(int r) {
1187 log_error("Failed to create bus message: %s", strerror(-r));
1191 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1197 return sd_bus_message_read(
1212 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
1216 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1217 sd_bus_reply_method_errno(m, r, error);
1219 } else if (sd_bus_error_is_set(error)) {
1220 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1221 sd_bus_reply_method_error(m, error);
1225 log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
1226 bus_message_type_to_string(m->header->type),
1229 strna(m->interface),
1231 strna(m->root_container.signature),
1232 bus_error_message(error, r));
1237 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1238 const char *eq, *field;
1244 eq = strchr(assignment, '=');
1246 log_error("Not an assignment: %s", assignment);
1250 field = strndupa(assignment, eq - assignment);
1253 if (streq(field, "CPUQuota")) {
1257 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1259 return bus_log_create_error(r);
1261 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1263 } else if (endswith(eq, "%")) {
1266 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1267 log_error("CPU quota '%s' invalid.", eq);
1271 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1273 return bus_log_create_error(r);
1275 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1277 log_error("CPU quota needs to be in percent.");
1282 return bus_log_create_error(r);
1287 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1289 return bus_log_create_error(r);
1291 if (STR_IN_SET(field,
1292 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1293 "SendSIGHUP", "SendSIGKILL")) {
1295 r = parse_boolean(eq);
1297 log_error("Failed to parse boolean assignment %s.", assignment);
1301 r = sd_bus_message_append(m, "v", "b", r);
1303 } else if (streq(field, "MemoryLimit")) {
1306 r = parse_size(eq, 1024, &bytes);
1308 log_error("Failed to parse bytes specification %s", assignment);
1312 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1314 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1317 r = safe_atou64(eq, &u);
1319 log_error("Failed to parse %s value %s.", field, eq);
1323 r = sd_bus_message_append(m, "v", "t", u);
1325 } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
1326 r = sd_bus_message_append(m, "v", "s", eq);
1328 else if (streq(field, "DeviceAllow")) {
1331 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1333 const char *path, *rwm, *e;
1335 e = strchr(eq, ' ');
1337 path = strndupa(eq, e - eq);
1344 if (!path_startswith(path, "/dev")) {
1345 log_error("%s is not a device file in /dev.", path);
1349 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1352 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1355 r = sd_bus_message_append(m, "v", "a(st)", 0);
1357 const char *path, *bandwidth, *e;
1360 e = strchr(eq, ' ');
1362 path = strndupa(eq, e - eq);
1365 log_error("Failed to parse %s value %s.", field, eq);
1369 if (!path_startswith(path, "/dev")) {
1370 log_error("%s is not a device file in /dev.", path);
1374 r = parse_size(bandwidth, 1000, &bytes);
1376 log_error("Failed to parse byte value %s.", bandwidth);
1380 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1383 } else if (streq(field, "BlockIODeviceWeight")) {
1386 r = sd_bus_message_append(m, "v", "a(st)", 0);
1388 const char *path, *weight, *e;
1391 e = strchr(eq, ' ');
1393 path = strndupa(eq, e - eq);
1396 log_error("Failed to parse %s value %s.", field, eq);
1400 if (!path_startswith(path, "/dev")) {
1401 log_error("%s is not a device file in /dev.", path);
1405 r = safe_atou64(weight, &u);
1407 log_error("Failed to parse %s value %s.", field, weight);
1410 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1413 } else if (rlimit_from_string(field) >= 0) {
1416 if (streq(eq, "infinity"))
1419 r = safe_atou64(eq, &rl);
1421 log_error("Invalid resource limit: %s", eq);
1426 r = sd_bus_message_append(m, "v", "t", rl);
1428 } else if (streq(field, "Nice")) {
1431 r = safe_atoi32(eq, &i);
1433 log_error("Failed to parse %s value %s.", field, eq);
1437 r = sd_bus_message_append(m, "v", "i", i);
1439 } else if (streq(field, "Environment")) {
1441 r = sd_bus_message_append(m, "v", "as", 1, eq);
1443 } else if (streq(field, "KillSignal")) {
1446 sig = signal_from_string_try_harder(eq);
1448 log_error("Failed to parse %s value %s.", field, eq);
1452 r = sd_bus_message_append(m, "v", "i", sig);
1455 log_error("Unknown assignment %s.", assignment);
1460 return bus_log_create_error(r);