]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
nspawn: no need for duplicate checks against EEXIST
[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
5f8640fb
LP
467static int property_get_selinux_context(
468 sd_bus *bus,
469 const char *path,
470 const char *interface,
471 const char *property,
472 sd_bus_message *reply,
473 void *userdata,
474 sd_bus_error *error) {
475
476 ExecContext *c = userdata;
477
478 assert(bus);
479 assert(reply);
480 assert(c);
481
482 return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
483}
484
eef65bf3
MS
485static int property_get_apparmor_profile(
486 sd_bus *bus,
487 const char *path,
488 const char *interface,
489 const char *property,
490 sd_bus_message *reply,
491 void *userdata,
492 sd_bus_error *error) {
493
494 ExecContext *c = userdata;
495
496 assert(bus);
497 assert(reply);
498 assert(c);
499
500 return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
501}
502
ac45f971
LP
503static int property_get_personality(
504 sd_bus *bus,
505 const char *path,
506 const char *interface,
507 const char *property,
508 sd_bus_message *reply,
509 void *userdata,
510 sd_bus_error *error) {
511
512 ExecContext *c = userdata;
513
514 assert(bus);
515 assert(reply);
516 assert(c);
517
518 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
519}
520
718db961
LP
521const sd_bus_vtable bus_exec_vtable[] = {
522 SD_BUS_VTABLE_START(0),
556089dc
LP
523 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
524 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
525 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
526 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
527 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
528 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
529 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
530 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
531 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
532 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
533 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
534 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
535 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
536 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
537 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
538 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
539 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
540 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
541 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
542 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
543 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
544 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
545 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
546 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
547 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
548 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
549 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
550 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
551 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
552 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
553 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
554 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
555 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
556 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
557 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
558 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
559 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
560 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
561 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
562 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
563 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
564 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
565 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
566 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
567 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
568 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
569 SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), SD_BUS_VTABLE_PROPERTY_CONST),
570 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
571 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
572 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
573 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
574 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
575 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
576 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 577 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
578 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
579 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 580 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
eef65bf3 581 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
582 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
583 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
584 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
585 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 586 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
ac45f971 587 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
588 SD_BUS_VTABLE_END
589};
82c121a4 590
4d4c80d0
LP
591static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
592 int r;
593
594 assert(reply);
595 assert(c);
596
597 if (!c->path)
598 return 0;
599
600 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
601 if (r < 0)
602 return r;
603
604 r = sd_bus_message_append(reply, "s", c->path);
605 if (r < 0)
606 return r;
607
608 r = sd_bus_message_append_strv(reply, c->argv);
609 if (r < 0)
610 return r;
611
612 r = sd_bus_message_append(reply, "bttttuii",
613 c->ignore,
614 c->exec_status.start_timestamp.realtime,
615 c->exec_status.start_timestamp.monotonic,
616 c->exec_status.exit_timestamp.realtime,
617 c->exec_status.exit_timestamp.monotonic,
618 (uint32_t) c->exec_status.pid,
619 (int32_t) c->exec_status.code,
620 (int32_t) c->exec_status.status);
621 if (r < 0)
622 return r;
623
624 return sd_bus_message_close_container(reply);
625}
626
718db961
LP
627int bus_property_get_exec_command(
628 sd_bus *bus,
629 const char *path,
630 const char *interface,
631 const char *property,
632 sd_bus_message *reply,
ebcf1f97
LP
633 void *userdata,
634 sd_bus_error *ret_error) {
fe68089d 635
4d4c80d0 636 ExecCommand *c = (ExecCommand*) userdata;
718db961 637 int r;
fe68089d 638
718db961
LP
639 assert(bus);
640 assert(reply);
fe68089d 641
718db961
LP
642 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
643 if (r < 0)
644 return r;
fe68089d 645
4d4c80d0
LP
646 r = append_exec_command(reply, c);
647 if (r < 0)
648 return r;
fe68089d 649
4d4c80d0
LP
650 return sd_bus_message_close_container(reply);
651}
718db961 652
4d4c80d0
LP
653int bus_property_get_exec_command_list(
654 sd_bus *bus,
655 const char *path,
656 const char *interface,
657 const char *property,
658 sd_bus_message *reply,
659 void *userdata,
660 sd_bus_error *ret_error) {
718db961 661
4d4c80d0
LP
662 ExecCommand *c = *(ExecCommand**) userdata;
663 int r;
718db961 664
4d4c80d0
LP
665 assert(bus);
666 assert(reply);
667
668 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
669 if (r < 0)
670 return r;
718db961 671
4d4c80d0
LP
672 LIST_FOREACH(command, c, c) {
673 r = append_exec_command(reply, c);
718db961
LP
674 if (r < 0)
675 return r;
fe68089d
LP
676 }
677
718db961 678 return sd_bus_message_close_container(reply);
8351ceae 679}
c7040b5d
LP
680
681int bus_exec_context_set_transient_property(
682 Unit *u,
683 ExecContext *c,
684 const char *name,
685 sd_bus_message *message,
686 UnitSetPropertiesMode mode,
687 sd_bus_error *error) {
688
689 int r;
690
691 assert(u);
692 assert(c);
693 assert(name);
694 assert(message);
695
696 if (streq(name, "User")) {
697 const char *uu;
698
699 r = sd_bus_message_read(message, "s", &uu);
700 if (r < 0)
701 return r;
702
703 if (mode != UNIT_CHECK) {
704
705 if (isempty(uu)) {
706 free(c->user);
707 c->user = NULL;
708 } else {
709 char *t;
710
711 t = strdup(uu);
712 if (!t)
713 return -ENOMEM;
714
715 free(c->user);
716 c->user = t;
717 }
718
719 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
720 }
721
722 return 1;
723
724 } else if (streq(name, "Group")) {
725 const char *gg;
726
727 r = sd_bus_message_read(message, "s", &gg);
728 if (r < 0)
729 return r;
730
731 if (mode != UNIT_CHECK) {
732
733 if (isempty(gg)) {
734 free(c->group);
735 c->group = NULL;
736 } else {
737 char *t;
738
739 t = strdup(gg);
740 if (!t)
741 return -ENOMEM;
742
743 free(c->group);
744 c->group = t;
745 }
746
747 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
748 }
749
750 return 1;
751
752 } else if (streq(name, "Nice")) {
753 int n;
754
755 r = sd_bus_message_read(message, "i", &n);
756 if (r < 0)
757 return r;
758
759 if (n < PRIO_MIN || n >= PRIO_MAX)
760 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
761
762 if (mode != UNIT_CHECK) {
763 c->nice = n;
764 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
765 }
766
767 return 1;
768
769 } else if (streq(name, "Environment")) {
770
771 _cleanup_strv_free_ char **l = NULL;
772
773 r = sd_bus_message_read_strv(message, &l);
774 if (r < 0)
775 return r;
776
777 if (!strv_env_is_valid(l))
778 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
779
780 if (mode != UNIT_CHECK) {
1006a62d 781 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
782 char **e;
783
784 e = strv_env_merge(2, c->environment, l);
785 if (!e)
786 return -ENOMEM;
787
788 strv_free(c->environment);
789 c->environment = e;
790
791 joined = strv_join(c->environment, " ");
792 if (!joined)
793 return -ENOMEM;
794
795 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
796 }
797
798 return 1;
799 }
800
801 return 0;
802}