]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
import: rename 'poll-dck' to 'pull-dkr'
[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
2ca620c4
WC
511static int property_get_smack_process_label(
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, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
527}
528
ac45f971
LP
529static int property_get_personality(
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
540 assert(bus);
541 assert(reply);
542 assert(c);
543
544 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
545}
546
4298d0b5
LP
547static int property_get_address_families(
548 sd_bus *bus,
549 const char *path,
550 const char *interface,
551 const char *property,
552 sd_bus_message *reply,
553 void *userdata,
554 sd_bus_error *error) {
555
556 ExecContext *c = userdata;
557 _cleanup_strv_free_ char **l = NULL;
558 Iterator i;
559 void *af;
560 int r;
561
562 assert(bus);
563 assert(reply);
564 assert(c);
565
566 r = sd_bus_message_open_container(reply, 'r', "bas");
567 if (r < 0)
568 return r;
569
570 r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
571 if (r < 0)
572 return r;
573
574 SET_FOREACH(af, c->address_families, i) {
575 const char *name;
576
577 name = af_to_name(PTR_TO_INT(af));
578 if (!name)
579 continue;
580
581 r = strv_extend(&l, name);
582 if (r < 0)
583 return -ENOMEM;
584 }
585
586 strv_sort(l);
587
588 r = sd_bus_message_append_strv(reply, l);
589 if (r < 0)
590 return r;
591
592 return sd_bus_message_close_container(reply);
593}
594
718db961
LP
595const sd_bus_vtable bus_exec_vtable[] = {
596 SD_BUS_VTABLE_START(0),
556089dc
LP
597 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
598 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
599 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
600 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
601 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
602 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
603 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
604 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
605 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
606 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
607 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
608 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
609 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
610 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
611 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
612 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
613 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
614 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
615 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
616 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
617 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
618 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
619 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
620 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
621 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
622 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
623 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
624 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
625 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
626 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
627 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
628 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
629 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
630 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
631 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
632 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
633 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
634 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
635 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
636 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
637 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
638 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
639 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
640 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
641 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
642 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
643 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
644 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
645 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
646 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
647 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
648 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
649 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 650 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
1b8689f9
LP
651 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
652 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
653 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
654 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 655 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
eef65bf3 656 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2ca620c4 657 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
658 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
659 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
660 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
661 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 662 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
ac45f971 663 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
4298d0b5 664 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
e66cf1a3
LP
665 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
666 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
667 SD_BUS_VTABLE_END
668};
82c121a4 669
4d4c80d0
LP
670static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
671 int r;
672
673 assert(reply);
674 assert(c);
675
676 if (!c->path)
677 return 0;
678
679 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
680 if (r < 0)
681 return r;
682
683 r = sd_bus_message_append(reply, "s", c->path);
684 if (r < 0)
685 return r;
686
687 r = sd_bus_message_append_strv(reply, c->argv);
688 if (r < 0)
689 return r;
690
691 r = sd_bus_message_append(reply, "bttttuii",
692 c->ignore,
693 c->exec_status.start_timestamp.realtime,
694 c->exec_status.start_timestamp.monotonic,
695 c->exec_status.exit_timestamp.realtime,
696 c->exec_status.exit_timestamp.monotonic,
697 (uint32_t) c->exec_status.pid,
698 (int32_t) c->exec_status.code,
699 (int32_t) c->exec_status.status);
700 if (r < 0)
701 return r;
702
703 return sd_bus_message_close_container(reply);
704}
705
718db961
LP
706int bus_property_get_exec_command(
707 sd_bus *bus,
708 const char *path,
709 const char *interface,
710 const char *property,
711 sd_bus_message *reply,
ebcf1f97
LP
712 void *userdata,
713 sd_bus_error *ret_error) {
fe68089d 714
4d4c80d0 715 ExecCommand *c = (ExecCommand*) userdata;
718db961 716 int r;
fe68089d 717
718db961
LP
718 assert(bus);
719 assert(reply);
fe68089d 720
718db961
LP
721 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
722 if (r < 0)
723 return r;
fe68089d 724
4d4c80d0
LP
725 r = append_exec_command(reply, c);
726 if (r < 0)
727 return r;
fe68089d 728
4d4c80d0
LP
729 return sd_bus_message_close_container(reply);
730}
718db961 731
4d4c80d0
LP
732int bus_property_get_exec_command_list(
733 sd_bus *bus,
734 const char *path,
735 const char *interface,
736 const char *property,
737 sd_bus_message *reply,
738 void *userdata,
739 sd_bus_error *ret_error) {
718db961 740
4d4c80d0
LP
741 ExecCommand *c = *(ExecCommand**) userdata;
742 int r;
718db961 743
4d4c80d0
LP
744 assert(bus);
745 assert(reply);
746
747 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
748 if (r < 0)
749 return r;
718db961 750
4d4c80d0
LP
751 LIST_FOREACH(command, c, c) {
752 r = append_exec_command(reply, c);
718db961
LP
753 if (r < 0)
754 return r;
fe68089d
LP
755 }
756
718db961 757 return sd_bus_message_close_container(reply);
8351ceae 758}
c7040b5d
LP
759
760int bus_exec_context_set_transient_property(
761 Unit *u,
762 ExecContext *c,
763 const char *name,
764 sd_bus_message *message,
765 UnitSetPropertiesMode mode,
766 sd_bus_error *error) {
767
768 int r;
769
770 assert(u);
771 assert(c);
772 assert(name);
773 assert(message);
774
775 if (streq(name, "User")) {
776 const char *uu;
777
778 r = sd_bus_message_read(message, "s", &uu);
779 if (r < 0)
780 return r;
781
782 if (mode != UNIT_CHECK) {
783
784 if (isempty(uu)) {
785 free(c->user);
786 c->user = NULL;
787 } else {
788 char *t;
789
790 t = strdup(uu);
791 if (!t)
792 return -ENOMEM;
793
794 free(c->user);
795 c->user = t;
796 }
797
798 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
799 }
800
801 return 1;
802
803 } else if (streq(name, "Group")) {
804 const char *gg;
805
806 r = sd_bus_message_read(message, "s", &gg);
807 if (r < 0)
808 return r;
809
810 if (mode != UNIT_CHECK) {
811
812 if (isempty(gg)) {
813 free(c->group);
814 c->group = NULL;
815 } else {
816 char *t;
817
818 t = strdup(gg);
819 if (!t)
820 return -ENOMEM;
821
822 free(c->group);
823 c->group = t;
824 }
825
826 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
827 }
828
829 return 1;
830
831 } else if (streq(name, "Nice")) {
832 int n;
833
834 r = sd_bus_message_read(message, "i", &n);
835 if (r < 0)
836 return r;
837
838 if (n < PRIO_MIN || n >= PRIO_MAX)
839 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
840
841 if (mode != UNIT_CHECK) {
842 c->nice = n;
843 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
844 }
845
846 return 1;
847
848 } else if (streq(name, "Environment")) {
849
850 _cleanup_strv_free_ char **l = NULL;
851
852 r = sd_bus_message_read_strv(message, &l);
853 if (r < 0)
854 return r;
855
856 if (!strv_env_is_valid(l))
857 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
858
859 if (mode != UNIT_CHECK) {
1006a62d 860 _cleanup_free_ char *joined = NULL;
c7040b5d
LP
861 char **e;
862
863 e = strv_env_merge(2, c->environment, l);
864 if (!e)
865 return -ENOMEM;
866
867 strv_free(c->environment);
868 c->environment = e;
869
cdd7b7df 870 joined = strv_join_quoted(c->environment);
c7040b5d
LP
871 if (!joined)
872 return -ENOMEM;
873
874 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
875 }
876
d584f638
LP
877 return 1;
878
879 } else if (rlimit_from_string(name) >= 0) {
880 uint64_t rl;
881 rlim_t x;
882
883 r = sd_bus_message_read(message, "t", &rl);
884 if (r < 0)
885 return r;
886
887 if (rl == (uint64_t) -1)
888 x = RLIM_INFINITY;
889 else {
890 x = (rlim_t) rl;
891
892 if ((uint64_t) x != rl)
893 return -ERANGE;
894 }
895
896 if (mode != UNIT_CHECK) {
897 int z;
898
899 z = rlimit_from_string(name);
900
901 if (!c->rlimit[z]) {
902 c->rlimit[z] = new(struct rlimit, 1);
903 if (!c->rlimit[z])
904 return -ENOMEM;
905 }
906
907 c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
908
909 if (x == RLIM_INFINITY)
910 unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
911 else
912 unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
913 }
914
c7040b5d
LP
915 return 1;
916 }
917
918 return 0;
919}