]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
networkd: split runtime config dir from state dir
[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),
556089dc
LP
621 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
622 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
623 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
624 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
625 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
626 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
627 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 628 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
629 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
630 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 631 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
eef65bf3 632 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
633 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
634 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
635 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
636 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 637 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
ac45f971 638 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
4298d0b5 639 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
e66cf1a3
LP
640 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
641 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
642 SD_BUS_VTABLE_END
643};
82c121a4 644
4d4c80d0
LP
645static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
646 int r;
647
648 assert(reply);
649 assert(c);
650
651 if (!c->path)
652 return 0;
653
654 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
655 if (r < 0)
656 return r;
657
658 r = sd_bus_message_append(reply, "s", c->path);
659 if (r < 0)
660 return r;
661
662 r = sd_bus_message_append_strv(reply, c->argv);
663 if (r < 0)
664 return r;
665
666 r = sd_bus_message_append(reply, "bttttuii",
667 c->ignore,
668 c->exec_status.start_timestamp.realtime,
669 c->exec_status.start_timestamp.monotonic,
670 c->exec_status.exit_timestamp.realtime,
671 c->exec_status.exit_timestamp.monotonic,
672 (uint32_t) c->exec_status.pid,
673 (int32_t) c->exec_status.code,
674 (int32_t) c->exec_status.status);
675 if (r < 0)
676 return r;
677
678 return sd_bus_message_close_container(reply);
679}
680
718db961
LP
681int bus_property_get_exec_command(
682 sd_bus *bus,
683 const char *path,
684 const char *interface,
685 const char *property,
686 sd_bus_message *reply,
ebcf1f97
LP
687 void *userdata,
688 sd_bus_error *ret_error) {
fe68089d 689
4d4c80d0 690 ExecCommand *c = (ExecCommand*) userdata;
718db961 691 int r;
fe68089d 692
718db961
LP
693 assert(bus);
694 assert(reply);
fe68089d 695
718db961
LP
696 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
697 if (r < 0)
698 return r;
fe68089d 699
4d4c80d0
LP
700 r = append_exec_command(reply, c);
701 if (r < 0)
702 return r;
fe68089d 703
4d4c80d0
LP
704 return sd_bus_message_close_container(reply);
705}
718db961 706
4d4c80d0
LP
707int bus_property_get_exec_command_list(
708 sd_bus *bus,
709 const char *path,
710 const char *interface,
711 const char *property,
712 sd_bus_message *reply,
713 void *userdata,
714 sd_bus_error *ret_error) {
718db961 715
4d4c80d0
LP
716 ExecCommand *c = *(ExecCommand**) userdata;
717 int r;
718db961 718
4d4c80d0
LP
719 assert(bus);
720 assert(reply);
721
722 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
723 if (r < 0)
724 return r;
718db961 725
4d4c80d0
LP
726 LIST_FOREACH(command, c, c) {
727 r = append_exec_command(reply, c);
718db961
LP
728 if (r < 0)
729 return r;
fe68089d
LP
730 }
731
718db961 732 return sd_bus_message_close_container(reply);
8351ceae 733}
c7040b5d
LP
734
735int bus_exec_context_set_transient_property(
736 Unit *u,
737 ExecContext *c,
738 const char *name,
739 sd_bus_message *message,
740 UnitSetPropertiesMode mode,
741 sd_bus_error *error) {
742
743 int r;
744
745 assert(u);
746 assert(c);
747 assert(name);
748 assert(message);
749
750 if (streq(name, "User")) {
751 const char *uu;
752
753 r = sd_bus_message_read(message, "s", &uu);
754 if (r < 0)
755 return r;
756
757 if (mode != UNIT_CHECK) {
758
759 if (isempty(uu)) {
760 free(c->user);
761 c->user = NULL;
762 } else {
763 char *t;
764
765 t = strdup(uu);
766 if (!t)
767 return -ENOMEM;
768
769 free(c->user);
770 c->user = t;
771 }
772
773 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
774 }
775
776 return 1;
777
778 } else if (streq(name, "Group")) {
779 const char *gg;
780
781 r = sd_bus_message_read(message, "s", &gg);
782 if (r < 0)
783 return r;
784
785 if (mode != UNIT_CHECK) {
786
787 if (isempty(gg)) {
788 free(c->group);
789 c->group = NULL;
790 } else {
791 char *t;
792
793 t = strdup(gg);
794 if (!t)
795 return -ENOMEM;
796
797 free(c->group);
798 c->group = t;
799 }
800
801 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
802 }
803
804 return 1;
805
806 } else if (streq(name, "Nice")) {
807 int n;
808
809 r = sd_bus_message_read(message, "i", &n);
810 if (r < 0)
811 return r;
812
813 if (n < PRIO_MIN || n >= PRIO_MAX)
814 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
815
816 if (mode != UNIT_CHECK) {
817 c->nice = n;
818 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
819 }
820
821 return 1;
822
823 } else if (streq(name, "Environment")) {
824
825 _cleanup_strv_free_ char **l = NULL;
826
827 r = sd_bus_message_read_strv(message, &l);
828 if (r < 0)
829 return r;
830
831 if (!strv_env_is_valid(l))
832 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
833
834 if (mode != UNIT_CHECK) {
1006a62d 835 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
836 char **e;
837
838 e = strv_env_merge(2, c->environment, l);
839 if (!e)
840 return -ENOMEM;
841
842 strv_free(c->environment);
843 c->environment = e;
844
845 joined = strv_join(c->environment, " ");
846 if (!joined)
847 return -ENOMEM;
848
849 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
850 }
851
d584f638
LP
852 return 1;
853
854 } else if (rlimit_from_string(name) >= 0) {
855 uint64_t rl;
856 rlim_t x;
857
858 r = sd_bus_message_read(message, "t", &rl);
859 if (r < 0)
860 return r;
861
862 if (rl == (uint64_t) -1)
863 x = RLIM_INFINITY;
864 else {
865 x = (rlim_t) rl;
866
867 if ((uint64_t) x != rl)
868 return -ERANGE;
869 }
870
871 if (mode != UNIT_CHECK) {
872 int z;
873
874 z = rlimit_from_string(name);
875
876 if (!c->rlimit[z]) {
877 c->rlimit[z] = new(struct rlimit, 1);
878 if (!c->rlimit[z])
879 return -ENOMEM;
880 }
881
882 c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
883
884 if (x == RLIM_INFINITY)
885 unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
886 else
887 unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
888 }
889
c7040b5d
LP
890 return 1;
891 }
892
893 return 0;
894}