]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
Merge pull request #1530 from teg/network-fixes-2
[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 33#include "execute.h"
5ce70e5b 34#include "capability.h"
c7040b5d 35#include "env-util.h"
4298d0b5 36#include "af-list.h"
417116f2 37#include "namespace.h"
9b15b784
LP
38#include "path-util.h"
39#include "dbus-execute.h"
4139c1b2 40
57183d11
LP
41#ifdef HAVE_SECCOMP
42#include "seccomp-util.h"
43#endif
44
718db961 45BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
82c121a4 46
718db961 47static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
8c7be95e 48
023a4f67
LP
49static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
50
1b8689f9
LP
51static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
52static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
417116f2 53
718db961
LP
54static int property_get_environment_files(
55 sd_bus *bus,
56 const char *path,
57 const char *interface,
58 const char *property,
59 sd_bus_message *reply,
ebcf1f97
LP
60 void *userdata,
61 sd_bus_error *error) {
8c7be95e 62
718db961
LP
63 ExecContext *c = userdata;
64 char **j;
65 int r;
8c7be95e 66
718db961
LP
67 assert(bus);
68 assert(reply);
69 assert(c);
70
71 r = sd_bus_message_open_container(reply, 'a', "(sb)");
72 if (r < 0)
73 return r;
8c7be95e 74
718db961
LP
75 STRV_FOREACH(j, c->environment_files) {
76 const char *fn = *j;
8c7be95e 77
718db961
LP
78 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
79 if (r < 0)
80 return r;
8c7be95e
LP
81 }
82
718db961
LP
83 return sd_bus_message_close_container(reply);
84}
85
718db961
LP
86static int property_get_oom_score_adjust(
87 sd_bus *bus,
88 const char *path,
89 const char *interface,
90 const char *property,
91 sd_bus_message *reply,
ebcf1f97
LP
92 void *userdata,
93 sd_bus_error *error) {
718db961
LP
94
95
96 ExecContext *c = userdata;
82c121a4
LP
97 int32_t n;
98
718db961
LP
99 assert(bus);
100 assert(reply);
82c121a4
LP
101 assert(c);
102
dd6c17b1
LP
103 if (c->oom_score_adjust_set)
104 n = c->oom_score_adjust;
82c121a4 105 else {
68eda4bd 106 _cleanup_free_ char *t = NULL;
82c121a4
LP
107
108 n = 0;
718db961 109 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
82c121a4 110 safe_atoi(t, &n);
82c121a4
LP
111 }
112
718db961 113 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
114}
115
718db961
LP
116static int property_get_nice(
117 sd_bus *bus,
118 const char *path,
119 const char *interface,
120 const char *property,
121 sd_bus_message *reply,
ebcf1f97
LP
122 void *userdata,
123 sd_bus_error *error) {
718db961
LP
124
125
126 ExecContext *c = userdata;
82c121a4
LP
127 int32_t n;
128
718db961
LP
129 assert(bus);
130 assert(reply);
82c121a4
LP
131 assert(c);
132
133 if (c->nice_set)
134 n = c->nice;
718db961
LP
135 else {
136 errno = 0;
82c121a4 137 n = getpriority(PRIO_PROCESS, 0);
718db961
LP
138 if (errno != 0)
139 n = 0;
140 }
82c121a4 141
718db961 142 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
143}
144
718db961
LP
145static int property_get_ioprio(
146 sd_bus *bus,
147 const char *path,
148 const char *interface,
149 const char *property,
150 sd_bus_message *reply,
ebcf1f97
LP
151 void *userdata,
152 sd_bus_error *error) {
718db961
LP
153
154
155 ExecContext *c = userdata;
82c121a4
LP
156 int32_t n;
157
718db961
LP
158 assert(bus);
159 assert(reply);
82c121a4
LP
160 assert(c);
161
162 if (c->ioprio_set)
163 n = c->ioprio;
718db961 164 else {
82c121a4 165 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
718db961
LP
166 if (n < 0)
167 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
168 }
82c121a4 169
718db961 170 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
171}
172
718db961
LP
173static int property_get_cpu_sched_policy(
174 sd_bus *bus,
175 const char *path,
176 const char *interface,
177 const char *property,
178 sd_bus_message *reply,
ebcf1f97
LP
179 void *userdata,
180 sd_bus_error *error) {
718db961
LP
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->cpu_sched_set)
190 n = c->cpu_sched_policy;
718db961 191 else {
82c121a4 192 n = sched_getscheduler(0);
718db961
LP
193 if (n < 0)
194 n = SCHED_OTHER;
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_priority(
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_priority;
218 else {
b92bea5d 219 struct sched_param p = {};
82c121a4 220
82c121a4
LP
221 if (sched_getparam(0, &p) >= 0)
222 n = p.sched_priority;
e62d8c39
ZJS
223 else
224 n = 0;
82c121a4
LP
225 }
226
718db961 227 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
228}
229
718db961
LP
230static int property_get_cpu_affinity(
231 sd_bus *bus,
232 const char *path,
233 const char *interface,
234 const char *property,
235 sd_bus_message *reply,
ebcf1f97
LP
236 void *userdata,
237 sd_bus_error *error) {
82c121a4 238
718db961 239 ExecContext *c = userdata;
82c121a4 240
718db961
LP
241 assert(bus);
242 assert(reply);
243 assert(c);
82c121a4
LP
244
245 if (c->cpuset)
718db961 246 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
82c121a4 247 else
718db961 248 return sd_bus_message_append_array(reply, 'y', NULL, 0);
82c121a4
LP
249}
250
718db961
LP
251static int property_get_timer_slack_nsec(
252 sd_bus *bus,
253 const char *path,
254 const char *interface,
255 const char *property,
256 sd_bus_message *reply,
ebcf1f97
LP
257 void *userdata,
258 sd_bus_error *error) {
718db961
LP
259
260 ExecContext *c = userdata;
82c121a4
LP
261 uint64_t u;
262
718db961
LP
263 assert(bus);
264 assert(reply);
82c121a4
LP
265 assert(c);
266
3a43da28 267 if (c->timer_slack_nsec != NSEC_INFINITY)
03fae018 268 u = (uint64_t) c->timer_slack_nsec;
82c121a4
LP
269 else
270 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
271
718db961 272 return sd_bus_message_append(reply, "t", u);
82c121a4
LP
273}
274
718db961
LP
275static int property_get_capability_bounding_set(
276 sd_bus *bus,
277 const char *path,
278 const char *interface,
279 const char *property,
280 sd_bus_message *reply,
ebcf1f97
LP
281 void *userdata,
282 sd_bus_error *error) {
260abb78 283
718db961
LP
284 ExecContext *c = userdata;
285
286 assert(bus);
287 assert(reply);
260abb78
LP
288 assert(c);
289
7c3d67ef 290 /* We store this negated internally, to match the kernel, but
260abb78 291 * we expose it normalized. */
718db961 292 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
260abb78
LP
293}
294
718db961
LP
295static int property_get_capabilities(
296 sd_bus *bus,
297 const char *path,
298 const char *interface,
299 const char *property,
300 sd_bus_message *reply,
ebcf1f97
LP
301 void *userdata,
302 sd_bus_error *error) {
718db961
LP
303
304 ExecContext *c = userdata;
5ce70e5b 305 _cleanup_cap_free_charp_ char *t = NULL;
82c121a4 306 const char *s;
82c121a4 307
718db961
LP
308 assert(bus);
309 assert(reply);
82c121a4
LP
310 assert(c);
311
312 if (c->capabilities)
313 s = t = cap_to_text(c->capabilities, NULL);
314 else
315 s = "";
316
674cdd19 317 if (!s)
82c121a4
LP
318 return -ENOMEM;
319
5ce70e5b 320 return sd_bus_message_append(reply, "s", s);
82c121a4
LP
321}
322
718db961
LP
323static int property_get_syscall_filter(
324 sd_bus *bus,
325 const char *path,
326 const char *interface,
327 const char *property,
328 sd_bus_message *reply,
ebcf1f97
LP
329 void *userdata,
330 sd_bus_error *error) {
82c121a4 331
17df7223
LP
332 ExecContext *c = userdata;
333 _cleanup_strv_free_ char **l = NULL;
57183d11
LP
334 int r;
335
351a19b1 336#ifdef HAVE_SECCOMP
17df7223
LP
337 Iterator i;
338 void *id;
351a19b1 339#endif
17df7223
LP
340
341 assert(bus);
342 assert(reply);
343 assert(c);
344
57183d11
LP
345 r = sd_bus_message_open_container(reply, 'r', "bas");
346 if (r < 0)
347 return r;
348
349 r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
350 if (r < 0)
351 return r;
352
351a19b1 353#ifdef HAVE_SECCOMP
17df7223
LP
354 SET_FOREACH(id, c->syscall_filter, i) {
355 char *name;
356
357 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
358 if (!name)
359 continue;
360
6e18964d
ZJS
361 r = strv_consume(&l, name);
362 if (r < 0)
363 return r;
17df7223 364 }
351a19b1 365#endif
17df7223
LP
366
367 strv_sort(l);
368
57183d11
LP
369 r = sd_bus_message_append_strv(reply, l);
370 if (r < 0)
371 return r;
17df7223 372
57183d11
LP
373 return sd_bus_message_close_container(reply);
374}
17df7223 375
57183d11
LP
376static int property_get_syscall_archs(
377 sd_bus *bus,
378 const char *path,
379 const char *interface,
380 const char *property,
381 sd_bus_message *reply,
382 void *userdata,
383 sd_bus_error *error) {
384
385 ExecContext *c = userdata;
386 _cleanup_strv_free_ char **l = NULL;
387 int r;
388
389#ifdef HAVE_SECCOMP
390 Iterator i;
391 void *id;
392#endif
393
394 assert(bus);
395 assert(reply);
396 assert(c);
17df7223 397
57183d11
LP
398#ifdef HAVE_SECCOMP
399 SET_FOREACH(id, c->syscall_archs, i) {
400 const char *name;
401
402 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
403 if (!name)
404 continue;
405
406 r = strv_extend(&l, name);
407 if (r < 0)
408 return -ENOMEM;
17df7223 409 }
57183d11
LP
410#endif
411
412 strv_sort(l);
413
414 r = sd_bus_message_append_strv(reply, l);
415 if (r < 0)
416 return r;
17df7223 417
57183d11 418 return 0;
17df7223
LP
419}
420
421static int property_get_syscall_errno(
422 sd_bus *bus,
423 const char *path,
424 const char *interface,
425 const char *property,
426 sd_bus_message *reply,
427 void *userdata,
428 sd_bus_error *error) {
429
718db961 430 ExecContext *c = userdata;
82c121a4 431
718db961
LP
432 assert(bus);
433 assert(reply);
434 assert(c);
82c121a4 435
17df7223 436 return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
718db961 437}
82c121a4 438
5f8640fb
LP
439static int property_get_selinux_context(
440 sd_bus *bus,
441 const char *path,
442 const char *interface,
443 const char *property,
444 sd_bus_message *reply,
445 void *userdata,
446 sd_bus_error *error) {
447
448 ExecContext *c = userdata;
449
450 assert(bus);
451 assert(reply);
452 assert(c);
453
454 return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
455}
456
eef65bf3
MS
457static int property_get_apparmor_profile(
458 sd_bus *bus,
459 const char *path,
460 const char *interface,
461 const char *property,
462 sd_bus_message *reply,
463 void *userdata,
464 sd_bus_error *error) {
465
466 ExecContext *c = userdata;
467
468 assert(bus);
469 assert(reply);
470 assert(c);
471
472 return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
473}
474
2ca620c4
WC
475static int property_get_smack_process_label(
476 sd_bus *bus,
477 const char *path,
478 const char *interface,
479 const char *property,
480 sd_bus_message *reply,
481 void *userdata,
482 sd_bus_error *error) {
483
484 ExecContext *c = userdata;
485
486 assert(bus);
487 assert(reply);
488 assert(c);
489
490 return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
491}
492
ac45f971
LP
493static int property_get_personality(
494 sd_bus *bus,
495 const char *path,
496 const char *interface,
497 const char *property,
498 sd_bus_message *reply,
499 void *userdata,
500 sd_bus_error *error) {
501
502 ExecContext *c = userdata;
503
504 assert(bus);
505 assert(reply);
506 assert(c);
507
508 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
509}
510
4298d0b5
LP
511static int property_get_address_families(
512 sd_bus *bus,
513 const char *path,
514 const char *interface,
515 const char *property,
516 sd_bus_message *reply,
517 void *userdata,
518 sd_bus_error *error) {
519
520 ExecContext *c = userdata;
521 _cleanup_strv_free_ char **l = NULL;
522 Iterator i;
523 void *af;
524 int r;
525
526 assert(bus);
527 assert(reply);
528 assert(c);
529
530 r = sd_bus_message_open_container(reply, 'r', "bas");
531 if (r < 0)
532 return r;
533
534 r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
535 if (r < 0)
536 return r;
537
538 SET_FOREACH(af, c->address_families, i) {
539 const char *name;
540
541 name = af_to_name(PTR_TO_INT(af));
542 if (!name)
543 continue;
544
545 r = strv_extend(&l, name);
546 if (r < 0)
547 return -ENOMEM;
548 }
549
550 strv_sort(l);
551
552 r = sd_bus_message_append_strv(reply, l);
553 if (r < 0)
554 return r;
555
556 return sd_bus_message_close_container(reply);
557}
558
5f5d8eab
LP
559static int property_get_working_directory(
560 sd_bus *bus,
561 const char *path,
562 const char *interface,
563 const char *property,
564 sd_bus_message *reply,
565 void *userdata,
566 sd_bus_error *error) {
567
568 ExecContext *c = userdata;
569 const char *wd;
570
571 assert(bus);
572 assert(reply);
573 assert(c);
574
575 if (c->working_directory_home)
576 wd = "~";
577 else
578 wd = c->working_directory;
579
580 if (c->working_directory_missing_ok)
581 wd = strjoina("!", wd);
582
583 return sd_bus_message_append(reply, "s", wd);
584}
585
06f2ccf9
EV
586static int property_get_syslog_level(
587 sd_bus *bus,
588 const char *path,
589 const char *interface,
590 const char *property,
591 sd_bus_message *reply,
592 void *userdata,
593 sd_bus_error *error) {
594
595 ExecContext *c = userdata;
596
597 assert(bus);
598 assert(reply);
599 assert(c);
600
601 return sd_bus_message_append(reply, "i", LOG_PRI(c->syslog_priority));
602}
603
604static int property_get_syslog_facility(
605 sd_bus *bus,
606 const char *path,
607 const char *interface,
608 const char *property,
609 sd_bus_message *reply,
610 void *userdata,
611 sd_bus_error *error) {
612
613 ExecContext *c = userdata;
614
615 assert(bus);
616 assert(reply);
617 assert(c);
618
619 return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority));
620}
621
718db961
LP
622const sd_bus_vtable bus_exec_vtable[] = {
623 SD_BUS_VTABLE_START(0),
556089dc
LP
624 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
625 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
626 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3
EV
627 SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
628 SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
629 SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
630 SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
631 SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
632 SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
633 SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
634 SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
635 SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
636 SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
637 SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
638 SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
639 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
640 SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
641 SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
642 SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
5f5d8eab 643 SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
644 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
645 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
646 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
647 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
648 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
649 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
650 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
651 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
652 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
653 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
654 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
655 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
656 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
657 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
658 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
659 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
660 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
661 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
662 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
663 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
06f2ccf9
EV
664 SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
665 SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
666 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
667 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
668 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
669 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
670 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
671 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
672 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
673 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
674 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
675 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
676 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
677 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
678 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 679 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
1b8689f9
LP
680 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
681 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
682 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
683 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
023a4f67 684 SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 685 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
eef65bf3 686 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2ca620c4 687 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
688 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
689 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
690 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
691 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 692 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
ac45f971 693 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
4298d0b5 694 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
e66cf1a3
LP
695 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
696 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
697 SD_BUS_VTABLE_END
698};
82c121a4 699
4d4c80d0
LP
700static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
701 int r;
702
703 assert(reply);
704 assert(c);
705
706 if (!c->path)
707 return 0;
708
709 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
710 if (r < 0)
711 return r;
712
713 r = sd_bus_message_append(reply, "s", c->path);
714 if (r < 0)
715 return r;
716
717 r = sd_bus_message_append_strv(reply, c->argv);
718 if (r < 0)
719 return r;
720
721 r = sd_bus_message_append(reply, "bttttuii",
722 c->ignore,
723 c->exec_status.start_timestamp.realtime,
724 c->exec_status.start_timestamp.monotonic,
725 c->exec_status.exit_timestamp.realtime,
726 c->exec_status.exit_timestamp.monotonic,
727 (uint32_t) c->exec_status.pid,
728 (int32_t) c->exec_status.code,
729 (int32_t) c->exec_status.status);
730 if (r < 0)
731 return r;
732
733 return sd_bus_message_close_container(reply);
734}
735
718db961
LP
736int bus_property_get_exec_command(
737 sd_bus *bus,
738 const char *path,
739 const char *interface,
740 const char *property,
741 sd_bus_message *reply,
ebcf1f97
LP
742 void *userdata,
743 sd_bus_error *ret_error) {
fe68089d 744
4d4c80d0 745 ExecCommand *c = (ExecCommand*) userdata;
718db961 746 int r;
fe68089d 747
718db961
LP
748 assert(bus);
749 assert(reply);
fe68089d 750
718db961
LP
751 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
752 if (r < 0)
753 return r;
fe68089d 754
4d4c80d0
LP
755 r = append_exec_command(reply, c);
756 if (r < 0)
757 return r;
fe68089d 758
4d4c80d0
LP
759 return sd_bus_message_close_container(reply);
760}
718db961 761
4d4c80d0
LP
762int bus_property_get_exec_command_list(
763 sd_bus *bus,
764 const char *path,
765 const char *interface,
766 const char *property,
767 sd_bus_message *reply,
768 void *userdata,
769 sd_bus_error *ret_error) {
718db961 770
4d4c80d0
LP
771 ExecCommand *c = *(ExecCommand**) userdata;
772 int r;
718db961 773
4d4c80d0
LP
774 assert(bus);
775 assert(reply);
776
777 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
778 if (r < 0)
779 return r;
718db961 780
4d4c80d0
LP
781 LIST_FOREACH(command, c, c) {
782 r = append_exec_command(reply, c);
718db961
LP
783 if (r < 0)
784 return r;
fe68089d
LP
785 }
786
718db961 787 return sd_bus_message_close_container(reply);
8351ceae 788}
c7040b5d
LP
789
790int bus_exec_context_set_transient_property(
791 Unit *u,
792 ExecContext *c,
793 const char *name,
794 sd_bus_message *message,
795 UnitSetPropertiesMode mode,
796 sd_bus_error *error) {
797
798 int r;
799
800 assert(u);
801 assert(c);
802 assert(name);
803 assert(message);
804
805 if (streq(name, "User")) {
806 const char *uu;
807
808 r = sd_bus_message_read(message, "s", &uu);
809 if (r < 0)
810 return r;
811
812 if (mode != UNIT_CHECK) {
813
814 if (isempty(uu)) {
a1e58e8e 815 c->user = mfree(c->user);
c7040b5d
LP
816 } else {
817 char *t;
818
819 t = strdup(uu);
820 if (!t)
821 return -ENOMEM;
822
823 free(c->user);
824 c->user = t;
825 }
826
827 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
828 }
829
830 return 1;
831
832 } else if (streq(name, "Group")) {
833 const char *gg;
834
835 r = sd_bus_message_read(message, "s", &gg);
836 if (r < 0)
837 return r;
838
839 if (mode != UNIT_CHECK) {
840
841 if (isempty(gg)) {
a1e58e8e 842 c->group = mfree(c->group);
c7040b5d
LP
843 } else {
844 char *t;
845
846 t = strdup(gg);
847 if (!t)
848 return -ENOMEM;
849
850 free(c->group);
851 c->group = t;
852 }
853
854 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
855 }
856
857 return 1;
de53c417
EV
858 } else if (streq(name, "SyslogIdentifier")) {
859 const char *id;
c7040b5d 860
de53c417
EV
861 r = sd_bus_message_read(message, "s", &id);
862 if (r < 0)
863 return r;
864
865 if (mode != UNIT_CHECK) {
866
867 if (isempty(id)) {
868 c->syslog_identifier = mfree(c->syslog_identifier);
869 } else {
870 char *t;
871
872 t = strdup(id);
873 if (!t)
874 return -ENOMEM;
875
876 free(c->syslog_identifier);
877 c->syslog_identifier = t;
878 }
879
880 unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s\n", id);
881 }
882
883 return 1;
c7040b5d
LP
884 } else if (streq(name, "Nice")) {
885 int n;
886
887 r = sd_bus_message_read(message, "i", &n);
888 if (r < 0)
889 return r;
890
891 if (n < PRIO_MIN || n >= PRIO_MAX)
892 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
893
894 if (mode != UNIT_CHECK) {
895 c->nice = n;
896 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
897 }
898
899 return 1;
900
5f5d8eab 901 } else if (STR_IN_SET(name, "TTYPath", "RootDirectory")) {
602b8355 902 const char *s;
9b15b784 903
602b8355 904 r = sd_bus_message_read(message, "s", &s);
9b15b784
LP
905 if (r < 0)
906 return r;
907
602b8355
NC
908 if (!path_is_absolute(s))
909 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
9b15b784
LP
910
911 if (mode != UNIT_CHECK) {
5f5d8eab
LP
912 if (streq(name, "TTYPath"))
913 r = free_and_strdup(&c->tty_path, s);
914 else {
915 assert(streq(name, "RootDirectory"));
916 r = free_and_strdup(&c->root_directory, s);
602b8355 917 }
5f5d8eab
LP
918 if (r < 0)
919 return r;
9b15b784 920
602b8355 921 unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, s);
9b15b784
LP
922 }
923
924 return 1;
925
5f5d8eab
LP
926 } else if (streq(name, "WorkingDirectory")) {
927 const char *s;
928 bool missing_ok;
929
930 r = sd_bus_message_read(message, "s", &s);
931 if (r < 0)
932 return r;
933
934 if (s[0] == '-') {
935 missing_ok = true;
936 s++;
937 } else
938 missing_ok = false;
939
940 if (!streq(s, "~") && !path_is_absolute(s))
941 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
942
943 if (mode != UNIT_CHECK) {
944 if (streq(s, "~")) {
945 c->working_directory = mfree(c->working_directory);
946 c->working_directory_home = true;
947 } else {
948 r = free_and_strdup(&c->working_directory, s);
949 if (r < 0)
950 return r;
951
952 c->working_directory_home = false;
953 }
954
955 c->working_directory_missing_ok = missing_ok;
956 unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
957 }
958
959 return 1;
960
9b15b784
LP
961 } else if (streq(name, "StandardInput")) {
962 const char *s;
963 ExecInput p;
964
965 r = sd_bus_message_read(message, "s", &s);
966 if (r < 0)
967 return r;
968
969 p = exec_input_from_string(s);
970 if (p < 0)
971 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
972
973 if (mode != UNIT_CHECK) {
974 c->std_input = p;
975
976 unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s\n", exec_input_to_string(p));
977 }
978
979 return 1;
980
981
982 } else if (streq(name, "StandardOutput")) {
983 const char *s;
984 ExecOutput p;
985
986 r = sd_bus_message_read(message, "s", &s);
987 if (r < 0)
988 return r;
989
990 p = exec_output_from_string(s);
991 if (p < 0)
992 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
993
994 if (mode != UNIT_CHECK) {
995 c->std_output = p;
996
997 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s\n", exec_output_to_string(p));
998 }
999
1000 return 1;
1001
1002 } else if (streq(name, "StandardError")) {
1003 const char *s;
1004 ExecOutput p;
1005
1006 r = sd_bus_message_read(message, "s", &s);
1007 if (r < 0)
1008 return r;
1009
1010 p = exec_output_from_string(s);
1011 if (p < 0)
1012 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
1013
1014 if (mode != UNIT_CHECK) {
1015 c->std_error = p;
1016
1017 unit_write_drop_in_private_format(u, mode, name, "StandardError=%s\n", exec_output_to_string(p));
1018 }
1019
1020 return 1;
1021
b9c50073
GP
1022 } else if (STR_IN_SET(name,
1023 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset",
1024 "PrivateTmp", "PrivateDevices", "PrivateNetwork",
047d9933 1025 "NoNewPrivileges", "SyslogLevelPrefix")) {
506711fd
LP
1026 int b;
1027
1028 r = sd_bus_message_read(message, "b", &b);
1029 if (r < 0)
1030 return r;
1031
1032 if (mode != UNIT_CHECK) {
b9c50073
GP
1033 if (streq(name, "IgnoreSIGPIPE"))
1034 c->ignore_sigpipe = b;
1035 else if (streq(name, "TTYVHangup"))
1036 c->tty_vhangup = b;
1037 else if (streq(name, "TTYReset"))
1038 c->tty_reset = b;
1039 else if (streq(name, "PrivateTmp"))
1040 c->private_tmp = b;
1041 else if (streq(name, "PrivateDevices"))
1042 c->private_devices = b;
1043 else if (streq(name, "PrivateNetwork"))
1044 c->private_network = b;
1045 else if (streq(name, "NoNewPrivileges"))
1046 c->no_new_privileges = b;
047d9933
EV
1047 else if (streq(name, "SyslogLevelPrefix"))
1048 c->syslog_level_prefix = b;
b9c50073
GP
1049
1050 unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, yes_no(b));
506711fd
LP
1051 }
1052
1053 return 1;
1054
1055 } else if (streq(name, "UtmpIdentifier")) {
1056 const char *id;
1057
1058 r = sd_bus_message_read(message, "s", &id);
1059 if (r < 0)
1060 return r;
1061
1062 if (mode != UNIT_CHECK) {
1063 if (isempty(id))
1064 c->utmp_id = mfree(c->utmp_id);
1065 else if (free_and_strdup(&c->utmp_id, id) < 0)
1066 return -ENOMEM;
1067
1068 unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s\n", strempty(id));
1069 }
1070
1071 return 1;
1072
1073 } else if (streq(name, "UtmpMode")) {
1074 const char *s;
1075 ExecUtmpMode m;
1076
1077 r = sd_bus_message_read(message, "s", &s);
1078 if (r < 0)
1079 return r;
1080
1081 m = exec_utmp_mode_from_string(s);
1082 if (m < 0)
1083 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
1084
1085 if (mode != UNIT_CHECK) {
1086 c->utmp_mode = m;
1087
1088 unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s\n", exec_utmp_mode_to_string(m));
1089 }
1090
1091 return 1;
1092
1093 } else if (streq(name, "PAMName")) {
1094 const char *n;
1095
1096 r = sd_bus_message_read(message, "s", &n);
1097 if (r < 0)
1098 return r;
1099
1100 if (mode != UNIT_CHECK) {
1101 if (isempty(n))
1102 c->pam_name = mfree(c->pam_name);
1103 else if (free_and_strdup(&c->pam_name, n) < 0)
1104 return -ENOMEM;
1105
1106 unit_write_drop_in_private_format(u, mode, name, "PAMName=%s\n", strempty(n));
1107 }
1108
1109 return 1;
1110
c7040b5d
LP
1111 } else if (streq(name, "Environment")) {
1112
1113 _cleanup_strv_free_ char **l = NULL;
1114
1115 r = sd_bus_message_read_strv(message, &l);
1116 if (r < 0)
1117 return r;
1118
1119 if (!strv_env_is_valid(l))
1120 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
1121
1122 if (mode != UNIT_CHECK) {
1006a62d 1123 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
1124 char **e;
1125
1126 e = strv_env_merge(2, c->environment, l);
1127 if (!e)
1128 return -ENOMEM;
1129
1130 strv_free(c->environment);
1131 c->environment = e;
1132
cdd7b7df 1133 joined = strv_join_quoted(c->environment);
c7040b5d
LP
1134 if (!joined)
1135 return -ENOMEM;
1136
1137 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
1138 }
1139
d584f638
LP
1140 return 1;
1141
1142 } else if (rlimit_from_string(name) >= 0) {
1143 uint64_t rl;
1144 rlim_t x;
1145
1146 r = sd_bus_message_read(message, "t", &rl);
1147 if (r < 0)
1148 return r;
1149
1150 if (rl == (uint64_t) -1)
1151 x = RLIM_INFINITY;
1152 else {
1153 x = (rlim_t) rl;
1154
1155 if ((uint64_t) x != rl)
1156 return -ERANGE;
1157 }
1158
1159 if (mode != UNIT_CHECK) {
1160 int z;
1161
1162 z = rlimit_from_string(name);
1163
1164 if (!c->rlimit[z]) {
1165 c->rlimit[z] = new(struct rlimit, 1);
1166 if (!c->rlimit[z])
1167 return -ENOMEM;
1168 }
1169
1170 c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
1171
1172 if (x == RLIM_INFINITY)
1173 unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
1174 else
1175 unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
1176 }
1177
c7040b5d
LP
1178 return 1;
1179 }
1180
1181 return 0;
1182}