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