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