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