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