]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
Revert "man: systemd.service(5): clarify behavior of SuccessExitStatus"
[thirdparty/systemd.git] / src / core / dbus-execute.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4139c1b2
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
4139c1b2
LP
11 (at your option) any later version.
12
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
5430f7f2 16 Lesser General Public License for more details.
4139c1b2 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
4139c1b2
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
82c121a4 22#include <sys/prctl.h>
4139c1b2 23
57183d11
LP
24#ifdef HAVE_SECCOMP
25#include <seccomp.h>
26#endif
27
718db961 28#include "bus-util.h"
82c121a4
LP
29#include "missing.h"
30#include "ioprio.h"
fe68089d 31#include "strv.h"
a5c32cff 32#include "fileio.h"
718db961
LP
33#include "execute.h"
34#include "dbus-execute.h"
5ce70e5b 35#include "capability.h"
c7040b5d 36#include "env-util.h"
4139c1b2 37
57183d11
LP
38#ifdef HAVE_SECCOMP
39#include "seccomp-util.h"
40#endif
41
718db961 42BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
82c121a4 43
718db961 44static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
8c7be95e 45
718db961
LP
46static int property_get_environment_files(
47 sd_bus *bus,
48 const char *path,
49 const char *interface,
50 const char *property,
51 sd_bus_message *reply,
ebcf1f97
LP
52 void *userdata,
53 sd_bus_error *error) {
8c7be95e 54
718db961
LP
55 ExecContext *c = userdata;
56 char **j;
57 int r;
8c7be95e 58
718db961
LP
59 assert(bus);
60 assert(reply);
61 assert(c);
62
63 r = sd_bus_message_open_container(reply, 'a', "(sb)");
64 if (r < 0)
65 return r;
8c7be95e 66
718db961
LP
67 STRV_FOREACH(j, c->environment_files) {
68 const char *fn = *j;
8c7be95e 69
718db961
LP
70 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
71 if (r < 0)
72 return r;
8c7be95e
LP
73 }
74
718db961
LP
75 return sd_bus_message_close_container(reply);
76}
77
78static int property_get_rlimit(
79 sd_bus *bus,
80 const char *path,
81 const char *interface,
82 const char *property,
83 sd_bus_message *reply,
ebcf1f97
LP
84 void *userdata,
85 sd_bus_error *error) {
718db961
LP
86
87 struct rlimit *rl;
88 uint64_t u;
89
90 assert(bus);
91 assert(reply);
92 assert(userdata);
8c7be95e 93
718db961
LP
94 rl = *(struct rlimit**) userdata;
95 if (rl)
96 u = (uint64_t) rl->rlim_max;
97 else {
98 struct rlimit buf = {};
99 int z;
100
101 z = rlimit_from_string(property);
102 assert(z >= 0);
103
104 getrlimit(z, &buf);
105
106 u = (uint64_t) buf.rlim_max;
107 }
108
109 return sd_bus_message_append(reply, "t", u);
8c7be95e
LP
110}
111
718db961
LP
112static int property_get_oom_score_adjust(
113 sd_bus *bus,
114 const char *path,
115 const char *interface,
116 const char *property,
117 sd_bus_message *reply,
ebcf1f97
LP
118 void *userdata,
119 sd_bus_error *error) {
718db961
LP
120
121
122 ExecContext *c = userdata;
82c121a4
LP
123 int32_t n;
124
718db961
LP
125 assert(bus);
126 assert(reply);
82c121a4
LP
127 assert(c);
128
dd6c17b1
LP
129 if (c->oom_score_adjust_set)
130 n = c->oom_score_adjust;
82c121a4 131 else {
68eda4bd 132 _cleanup_free_ char *t = NULL;
82c121a4
LP
133
134 n = 0;
718db961 135 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
82c121a4 136 safe_atoi(t, &n);
82c121a4
LP
137 }
138
718db961 139 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
140}
141
718db961
LP
142static int property_get_nice(
143 sd_bus *bus,
144 const char *path,
145 const char *interface,
146 const char *property,
147 sd_bus_message *reply,
ebcf1f97
LP
148 void *userdata,
149 sd_bus_error *error) {
718db961
LP
150
151
152 ExecContext *c = userdata;
82c121a4
LP
153 int32_t n;
154
718db961
LP
155 assert(bus);
156 assert(reply);
82c121a4
LP
157 assert(c);
158
159 if (c->nice_set)
160 n = c->nice;
718db961
LP
161 else {
162 errno = 0;
82c121a4 163 n = getpriority(PRIO_PROCESS, 0);
718db961
LP
164 if (errno != 0)
165 n = 0;
166 }
82c121a4 167
718db961 168 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
169}
170
718db961
LP
171static int property_get_ioprio(
172 sd_bus *bus,
173 const char *path,
174 const char *interface,
175 const char *property,
176 sd_bus_message *reply,
ebcf1f97
LP
177 void *userdata,
178 sd_bus_error *error) {
718db961
LP
179
180
181 ExecContext *c = userdata;
82c121a4
LP
182 int32_t n;
183
718db961
LP
184 assert(bus);
185 assert(reply);
82c121a4
LP
186 assert(c);
187
188 if (c->ioprio_set)
189 n = c->ioprio;
718db961 190 else {
82c121a4 191 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
718db961
LP
192 if (n < 0)
193 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
194 }
82c121a4 195
718db961 196 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
197}
198
718db961
LP
199static int property_get_cpu_sched_policy(
200 sd_bus *bus,
201 const char *path,
202 const char *interface,
203 const char *property,
204 sd_bus_message *reply,
ebcf1f97
LP
205 void *userdata,
206 sd_bus_error *error) {
718db961
LP
207
208 ExecContext *c = userdata;
82c121a4
LP
209 int32_t n;
210
718db961
LP
211 assert(bus);
212 assert(reply);
82c121a4
LP
213 assert(c);
214
215 if (c->cpu_sched_set)
216 n = c->cpu_sched_policy;
718db961 217 else {
82c121a4 218 n = sched_getscheduler(0);
718db961
LP
219 if (n < 0)
220 n = SCHED_OTHER;
221 }
82c121a4 222
718db961 223 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
224}
225
718db961
LP
226static int property_get_cpu_sched_priority(
227 sd_bus *bus,
228 const char *path,
229 const char *interface,
230 const char *property,
231 sd_bus_message *reply,
ebcf1f97
LP
232 void *userdata,
233 sd_bus_error *error) {
718db961
LP
234
235 ExecContext *c = userdata;
82c121a4
LP
236 int32_t n;
237
718db961
LP
238 assert(bus);
239 assert(reply);
82c121a4
LP
240 assert(c);
241
242 if (c->cpu_sched_set)
243 n = c->cpu_sched_priority;
244 else {
b92bea5d 245 struct sched_param p = {};
82c121a4 246
82c121a4
LP
247 if (sched_getparam(0, &p) >= 0)
248 n = p.sched_priority;
e62d8c39
ZJS
249 else
250 n = 0;
82c121a4
LP
251 }
252
718db961 253 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
254}
255
718db961
LP
256static int property_get_cpu_affinity(
257 sd_bus *bus,
258 const char *path,
259 const char *interface,
260 const char *property,
261 sd_bus_message *reply,
ebcf1f97
LP
262 void *userdata,
263 sd_bus_error *error) {
82c121a4 264
718db961 265 ExecContext *c = userdata;
82c121a4 266
718db961
LP
267 assert(bus);
268 assert(reply);
269 assert(c);
82c121a4
LP
270
271 if (c->cpuset)
718db961 272 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
82c121a4 273 else
718db961 274 return sd_bus_message_append_array(reply, 'y', NULL, 0);
82c121a4
LP
275}
276
718db961
LP
277static int property_get_timer_slack_nsec(
278 sd_bus *bus,
279 const char *path,
280 const char *interface,
281 const char *property,
282 sd_bus_message *reply,
ebcf1f97
LP
283 void *userdata,
284 sd_bus_error *error) {
718db961
LP
285
286 ExecContext *c = userdata;
82c121a4
LP
287 uint64_t u;
288
718db961
LP
289 assert(bus);
290 assert(reply);
82c121a4
LP
291 assert(c);
292
d88a251b 293 if (c->timer_slack_nsec != (nsec_t) -1)
03fae018 294 u = (uint64_t) c->timer_slack_nsec;
82c121a4
LP
295 else
296 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
297
718db961 298 return sd_bus_message_append(reply, "t", u);
82c121a4
LP
299}
300
718db961
LP
301static int property_get_capability_bounding_set(
302 sd_bus *bus,
303 const char *path,
304 const char *interface,
305 const char *property,
306 sd_bus_message *reply,
ebcf1f97
LP
307 void *userdata,
308 sd_bus_error *error) {
260abb78 309
718db961
LP
310 ExecContext *c = userdata;
311
312 assert(bus);
313 assert(reply);
260abb78
LP
314 assert(c);
315
7c3d67ef 316 /* We store this negated internally, to match the kernel, but
260abb78 317 * we expose it normalized. */
718db961 318 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
260abb78
LP
319}
320
718db961
LP
321static int property_get_capabilities(
322 sd_bus *bus,
323 const char *path,
324 const char *interface,
325 const char *property,
326 sd_bus_message *reply,
ebcf1f97
LP
327 void *userdata,
328 sd_bus_error *error) {
718db961
LP
329
330 ExecContext *c = userdata;
5ce70e5b 331 _cleanup_cap_free_charp_ char *t = NULL;
82c121a4 332 const char *s;
82c121a4 333
718db961
LP
334 assert(bus);
335 assert(reply);
82c121a4
LP
336 assert(c);
337
338 if (c->capabilities)
339 s = t = cap_to_text(c->capabilities, NULL);
340 else
341 s = "";
342
674cdd19 343 if (!s)
82c121a4
LP
344 return -ENOMEM;
345
5ce70e5b 346 return sd_bus_message_append(reply, "s", s);
82c121a4
LP
347}
348
718db961
LP
349static int property_get_syscall_filter(
350 sd_bus *bus,
351 const char *path,
352 const char *interface,
353 const char *property,
354 sd_bus_message *reply,
ebcf1f97
LP
355 void *userdata,
356 sd_bus_error *error) {
82c121a4 357
17df7223
LP
358 ExecContext *c = userdata;
359 _cleanup_strv_free_ char **l = NULL;
57183d11
LP
360 int r;
361
351a19b1 362#ifdef HAVE_SECCOMP
17df7223
LP
363 Iterator i;
364 void *id;
351a19b1 365#endif
17df7223
LP
366
367 assert(bus);
368 assert(reply);
369 assert(c);
370
57183d11
LP
371 r = sd_bus_message_open_container(reply, 'r', "bas");
372 if (r < 0)
373 return r;
374
375 r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
376 if (r < 0)
377 return r;
378
351a19b1 379#ifdef HAVE_SECCOMP
17df7223
LP
380 SET_FOREACH(id, c->syscall_filter, i) {
381 char *name;
382
383 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
384 if (!name)
385 continue;
386
387 r = strv_push(&l, name);
388 if (r < 0) {
389 free(name);
390 return -ENOMEM;
391 }
392 }
351a19b1 393#endif
17df7223
LP
394
395 strv_sort(l);
396
57183d11
LP
397 r = sd_bus_message_append_strv(reply, l);
398 if (r < 0)
399 return r;
17df7223 400
57183d11
LP
401 return sd_bus_message_close_container(reply);
402}
17df7223 403
57183d11
LP
404static int property_get_syscall_archs(
405 sd_bus *bus,
406 const char *path,
407 const char *interface,
408 const char *property,
409 sd_bus_message *reply,
410 void *userdata,
411 sd_bus_error *error) {
412
413 ExecContext *c = userdata;
414 _cleanup_strv_free_ char **l = NULL;
415 int r;
416
417#ifdef HAVE_SECCOMP
418 Iterator i;
419 void *id;
420#endif
421
422 assert(bus);
423 assert(reply);
424 assert(c);
17df7223 425
57183d11
LP
426#ifdef HAVE_SECCOMP
427 SET_FOREACH(id, c->syscall_archs, i) {
428 const char *name;
429
430 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
431 if (!name)
432 continue;
433
434 r = strv_extend(&l, name);
435 if (r < 0)
436 return -ENOMEM;
17df7223 437 }
57183d11
LP
438#endif
439
440 strv_sort(l);
441
442 r = sd_bus_message_append_strv(reply, l);
443 if (r < 0)
444 return r;
17df7223 445
57183d11 446 return 0;
17df7223
LP
447}
448
449static int property_get_syscall_errno(
450 sd_bus *bus,
451 const char *path,
452 const char *interface,
453 const char *property,
454 sd_bus_message *reply,
455 void *userdata,
456 sd_bus_error *error) {
457
718db961 458 ExecContext *c = userdata;
82c121a4 459
718db961
LP
460 assert(bus);
461 assert(reply);
462 assert(c);
82c121a4 463
17df7223 464 return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
718db961 465}
82c121a4 466
718db961
LP
467const sd_bus_vtable bus_exec_vtable[] = {
468 SD_BUS_VTABLE_START(0),
556089dc
LP
469 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
470 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
471 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
472 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
473 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
474 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
475 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
476 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
477 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
478 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
479 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
480 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
481 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
482 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
483 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
484 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
485 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
486 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
487 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
488 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
489 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
490 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
491 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
492 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
493 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
494 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
495 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
496 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
497 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
498 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
499 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
500 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
501 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
502 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
503 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
504 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
505 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
506 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
507 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
508 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
509 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
510 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
511 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
512 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
513 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
514 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
515 SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), SD_BUS_VTABLE_PROPERTY_CONST),
516 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
517 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
518 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
519 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
520 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
521 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
522 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 523 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
524 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
525 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
7b52a628 526 SD_BUS_PROPERTY("SELinuxContext", "s", NULL, offsetof(ExecContext, selinux_context), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
527 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
528 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
529 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
530 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 531 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
532 SD_BUS_VTABLE_END
533};
82c121a4 534
4d4c80d0
LP
535static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
536 int r;
537
538 assert(reply);
539 assert(c);
540
541 if (!c->path)
542 return 0;
543
544 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
545 if (r < 0)
546 return r;
547
548 r = sd_bus_message_append(reply, "s", c->path);
549 if (r < 0)
550 return r;
551
552 r = sd_bus_message_append_strv(reply, c->argv);
553 if (r < 0)
554 return r;
555
556 r = sd_bus_message_append(reply, "bttttuii",
557 c->ignore,
558 c->exec_status.start_timestamp.realtime,
559 c->exec_status.start_timestamp.monotonic,
560 c->exec_status.exit_timestamp.realtime,
561 c->exec_status.exit_timestamp.monotonic,
562 (uint32_t) c->exec_status.pid,
563 (int32_t) c->exec_status.code,
564 (int32_t) c->exec_status.status);
565 if (r < 0)
566 return r;
567
568 return sd_bus_message_close_container(reply);
569}
570
718db961
LP
571int bus_property_get_exec_command(
572 sd_bus *bus,
573 const char *path,
574 const char *interface,
575 const char *property,
576 sd_bus_message *reply,
ebcf1f97
LP
577 void *userdata,
578 sd_bus_error *ret_error) {
fe68089d 579
4d4c80d0 580 ExecCommand *c = (ExecCommand*) userdata;
718db961 581 int r;
fe68089d 582
718db961
LP
583 assert(bus);
584 assert(reply);
fe68089d 585
718db961
LP
586 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
587 if (r < 0)
588 return r;
fe68089d 589
4d4c80d0
LP
590 r = append_exec_command(reply, c);
591 if (r < 0)
592 return r;
fe68089d 593
4d4c80d0
LP
594 return sd_bus_message_close_container(reply);
595}
718db961 596
4d4c80d0
LP
597int bus_property_get_exec_command_list(
598 sd_bus *bus,
599 const char *path,
600 const char *interface,
601 const char *property,
602 sd_bus_message *reply,
603 void *userdata,
604 sd_bus_error *ret_error) {
718db961 605
4d4c80d0
LP
606 ExecCommand *c = *(ExecCommand**) userdata;
607 int r;
718db961 608
4d4c80d0
LP
609 assert(bus);
610 assert(reply);
611
612 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
613 if (r < 0)
614 return r;
718db961 615
4d4c80d0
LP
616 LIST_FOREACH(command, c, c) {
617 r = append_exec_command(reply, c);
718db961
LP
618 if (r < 0)
619 return r;
fe68089d
LP
620 }
621
718db961 622 return sd_bus_message_close_container(reply);
8351ceae 623}
c7040b5d
LP
624
625int bus_exec_context_set_transient_property(
626 Unit *u,
627 ExecContext *c,
628 const char *name,
629 sd_bus_message *message,
630 UnitSetPropertiesMode mode,
631 sd_bus_error *error) {
632
633 int r;
634
635 assert(u);
636 assert(c);
637 assert(name);
638 assert(message);
639
640 if (streq(name, "User")) {
641 const char *uu;
642
643 r = sd_bus_message_read(message, "s", &uu);
644 if (r < 0)
645 return r;
646
647 if (mode != UNIT_CHECK) {
648
649 if (isempty(uu)) {
650 free(c->user);
651 c->user = NULL;
652 } else {
653 char *t;
654
655 t = strdup(uu);
656 if (!t)
657 return -ENOMEM;
658
659 free(c->user);
660 c->user = t;
661 }
662
663 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
664 }
665
666 return 1;
667
668 } else if (streq(name, "Group")) {
669 const char *gg;
670
671 r = sd_bus_message_read(message, "s", &gg);
672 if (r < 0)
673 return r;
674
675 if (mode != UNIT_CHECK) {
676
677 if (isempty(gg)) {
678 free(c->group);
679 c->group = NULL;
680 } else {
681 char *t;
682
683 t = strdup(gg);
684 if (!t)
685 return -ENOMEM;
686
687 free(c->group);
688 c->group = t;
689 }
690
691 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
692 }
693
694 return 1;
695
696 } else if (streq(name, "Nice")) {
697 int n;
698
699 r = sd_bus_message_read(message, "i", &n);
700 if (r < 0)
701 return r;
702
703 if (n < PRIO_MIN || n >= PRIO_MAX)
704 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
705
706 if (mode != UNIT_CHECK) {
707 c->nice = n;
708 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
709 }
710
711 return 1;
712
713 } else if (streq(name, "Environment")) {
714
715 _cleanup_strv_free_ char **l = NULL;
716
717 r = sd_bus_message_read_strv(message, &l);
718 if (r < 0)
719 return r;
720
721 if (!strv_env_is_valid(l))
722 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
723
724 if (mode != UNIT_CHECK) {
1006a62d 725 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
726 char **e;
727
728 e = strv_env_merge(2, c->environment, l);
729 if (!e)
730 return -ENOMEM;
731
732 strv_free(c->environment);
733 c->environment = e;
734
735 joined = strv_join(c->environment, " ");
736 if (!joined)
737 return -ENOMEM;
738
739 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
740 }
741
742 return 1;
743 }
744
745 return 0;
746}