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