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