]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
build-sys: fixups for libsystemd-daemon merge
[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
718db961
LP
485const sd_bus_vtable bus_exec_vtable[] = {
486 SD_BUS_VTABLE_START(0),
556089dc
LP
487 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
488 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
489 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
490 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
491 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
492 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
493 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
494 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
495 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
496 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
497 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
498 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
499 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
500 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
501 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
502 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
503 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
504 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
505 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
506 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
507 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
508 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
509 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
510 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
511 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
512 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
513 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
514 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
515 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
516 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
517 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
518 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
519 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
520 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
521 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
522 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
523 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
524 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
525 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
526 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
527 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
528 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
529 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
530 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
531 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
532 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
533 SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), SD_BUS_VTABLE_PROPERTY_CONST),
534 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
535 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
536 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
537 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
538 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
539 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
540 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 541 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
542 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
543 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 544 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
545 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
546 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
547 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
548 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 549 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
550 SD_BUS_VTABLE_END
551};
82c121a4 552
4d4c80d0
LP
553static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
554 int r;
555
556 assert(reply);
557 assert(c);
558
559 if (!c->path)
560 return 0;
561
562 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
563 if (r < 0)
564 return r;
565
566 r = sd_bus_message_append(reply, "s", c->path);
567 if (r < 0)
568 return r;
569
570 r = sd_bus_message_append_strv(reply, c->argv);
571 if (r < 0)
572 return r;
573
574 r = sd_bus_message_append(reply, "bttttuii",
575 c->ignore,
576 c->exec_status.start_timestamp.realtime,
577 c->exec_status.start_timestamp.monotonic,
578 c->exec_status.exit_timestamp.realtime,
579 c->exec_status.exit_timestamp.monotonic,
580 (uint32_t) c->exec_status.pid,
581 (int32_t) c->exec_status.code,
582 (int32_t) c->exec_status.status);
583 if (r < 0)
584 return r;
585
586 return sd_bus_message_close_container(reply);
587}
588
718db961
LP
589int bus_property_get_exec_command(
590 sd_bus *bus,
591 const char *path,
592 const char *interface,
593 const char *property,
594 sd_bus_message *reply,
ebcf1f97
LP
595 void *userdata,
596 sd_bus_error *ret_error) {
fe68089d 597
4d4c80d0 598 ExecCommand *c = (ExecCommand*) userdata;
718db961 599 int r;
fe68089d 600
718db961
LP
601 assert(bus);
602 assert(reply);
fe68089d 603
718db961
LP
604 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
605 if (r < 0)
606 return r;
fe68089d 607
4d4c80d0
LP
608 r = append_exec_command(reply, c);
609 if (r < 0)
610 return r;
fe68089d 611
4d4c80d0
LP
612 return sd_bus_message_close_container(reply);
613}
718db961 614
4d4c80d0
LP
615int bus_property_get_exec_command_list(
616 sd_bus *bus,
617 const char *path,
618 const char *interface,
619 const char *property,
620 sd_bus_message *reply,
621 void *userdata,
622 sd_bus_error *ret_error) {
718db961 623
4d4c80d0
LP
624 ExecCommand *c = *(ExecCommand**) userdata;
625 int r;
718db961 626
4d4c80d0
LP
627 assert(bus);
628 assert(reply);
629
630 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
631 if (r < 0)
632 return r;
718db961 633
4d4c80d0
LP
634 LIST_FOREACH(command, c, c) {
635 r = append_exec_command(reply, c);
718db961
LP
636 if (r < 0)
637 return r;
fe68089d
LP
638 }
639
718db961 640 return sd_bus_message_close_container(reply);
8351ceae 641}
c7040b5d
LP
642
643int bus_exec_context_set_transient_property(
644 Unit *u,
645 ExecContext *c,
646 const char *name,
647 sd_bus_message *message,
648 UnitSetPropertiesMode mode,
649 sd_bus_error *error) {
650
651 int r;
652
653 assert(u);
654 assert(c);
655 assert(name);
656 assert(message);
657
658 if (streq(name, "User")) {
659 const char *uu;
660
661 r = sd_bus_message_read(message, "s", &uu);
662 if (r < 0)
663 return r;
664
665 if (mode != UNIT_CHECK) {
666
667 if (isempty(uu)) {
668 free(c->user);
669 c->user = NULL;
670 } else {
671 char *t;
672
673 t = strdup(uu);
674 if (!t)
675 return -ENOMEM;
676
677 free(c->user);
678 c->user = t;
679 }
680
681 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
682 }
683
684 return 1;
685
686 } else if (streq(name, "Group")) {
687 const char *gg;
688
689 r = sd_bus_message_read(message, "s", &gg);
690 if (r < 0)
691 return r;
692
693 if (mode != UNIT_CHECK) {
694
695 if (isempty(gg)) {
696 free(c->group);
697 c->group = NULL;
698 } else {
699 char *t;
700
701 t = strdup(gg);
702 if (!t)
703 return -ENOMEM;
704
705 free(c->group);
706 c->group = t;
707 }
708
709 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
710 }
711
712 return 1;
713
714 } else if (streq(name, "Nice")) {
715 int n;
716
717 r = sd_bus_message_read(message, "i", &n);
718 if (r < 0)
719 return r;
720
721 if (n < PRIO_MIN || n >= PRIO_MAX)
722 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
723
724 if (mode != UNIT_CHECK) {
725 c->nice = n;
726 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
727 }
728
729 return 1;
730
731 } else if (streq(name, "Environment")) {
732
733 _cleanup_strv_free_ char **l = NULL;
734
735 r = sd_bus_message_read_strv(message, &l);
736 if (r < 0)
737 return r;
738
739 if (!strv_env_is_valid(l))
740 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
741
742 if (mode != UNIT_CHECK) {
1006a62d 743 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
744 char **e;
745
746 e = strv_env_merge(2, c->environment, l);
747 if (!e)
748 return -ENOMEM;
749
750 strv_free(c->environment);
751 c->environment = e;
752
753 joined = strv_join(c->environment, " ");
754 if (!joined)
755 return -ENOMEM;
756
757 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
758 }
759
760 return 1;
761 }
762
763 return 0;
764}