Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <sys/mount.h>
4 : : #include <sys/prctl.h>
5 : :
6 : : #if HAVE_SECCOMP
7 : : #include <seccomp.h>
8 : : #endif
9 : :
10 : : #include "af-list.h"
11 : : #include "alloc-util.h"
12 : : #include "bus-util.h"
13 : : #include "cap-list.h"
14 : : #include "capability-util.h"
15 : : #include "cpu-set-util.h"
16 : : #include "dbus-execute.h"
17 : : #include "dbus-util.h"
18 : : #include "env-util.h"
19 : : #include "errno-list.h"
20 : : #include "escape.h"
21 : : #include "execute.h"
22 : : #include "fd-util.h"
23 : : #include "fileio.h"
24 : : #include "hexdecoct.h"
25 : : #include "io-util.h"
26 : : #include "ioprio.h"
27 : : #include "journal-util.h"
28 : : #include "missing.h"
29 : : #include "mountpoint-util.h"
30 : : #include "namespace.h"
31 : : #include "parse-util.h"
32 : : #include "path-util.h"
33 : : #include "process-util.h"
34 : : #include "rlimit-util.h"
35 : : #if HAVE_SECCOMP
36 : : #include "seccomp-util.h"
37 : : #endif
38 : : #include "securebits-util.h"
39 : : #include "specifier.h"
40 : : #include "strv.h"
41 : : #include "syslog-util.h"
42 : : #include "unit-printf.h"
43 : : #include "user-util.h"
44 : : #include "utf8.h"
45 : :
46 [ # # # # : 0 : BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
# # ]
47 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
# # ]
48 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
# # ]
49 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
# # ]
50 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
# # ]
51 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_home, protect_home, ProtectHome);
# # ]
52 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
# # ]
53 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
# # ]
54 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
# # ]
55 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
# # ]
56 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
# # ]
57 [ # # # # ]: 0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
58 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
# # ]
59 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
# # ]
60 : :
61 : 0 : static int property_get_environment_files(
62 : : sd_bus *bus,
63 : : const char *path,
64 : : const char *interface,
65 : : const char *property,
66 : : sd_bus_message *reply,
67 : : void *userdata,
68 : : sd_bus_error *error) {
69 : :
70 : 0 : ExecContext *c = userdata;
71 : : char **j;
72 : : int r;
73 : :
74 [ # # ]: 0 : assert(bus);
75 [ # # ]: 0 : assert(reply);
76 [ # # ]: 0 : assert(c);
77 : :
78 : 0 : r = sd_bus_message_open_container(reply, 'a', "(sb)");
79 [ # # ]: 0 : if (r < 0)
80 : 0 : return r;
81 : :
82 [ # # # # ]: 0 : STRV_FOREACH(j, c->environment_files) {
83 : 0 : const char *fn = *j;
84 : :
85 [ # # ]: 0 : r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
86 [ # # ]: 0 : if (r < 0)
87 : 0 : return r;
88 : : }
89 : :
90 : 0 : return sd_bus_message_close_container(reply);
91 : : }
92 : :
93 : 0 : static int property_get_oom_score_adjust(
94 : : sd_bus *bus,
95 : : const char *path,
96 : : const char *interface,
97 : : const char *property,
98 : : sd_bus_message *reply,
99 : : void *userdata,
100 : : sd_bus_error *error) {
101 : :
102 : 0 : ExecContext *c = userdata;
103 : : int32_t n;
104 : :
105 [ # # ]: 0 : assert(bus);
106 [ # # ]: 0 : assert(reply);
107 [ # # ]: 0 : assert(c);
108 : :
109 [ # # ]: 0 : if (c->oom_score_adjust_set)
110 : 0 : n = c->oom_score_adjust;
111 : : else {
112 : 0 : _cleanup_free_ char *t = NULL;
113 : :
114 : 0 : n = 0;
115 [ # # ]: 0 : if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
116 : 0 : safe_atoi32(t, &n);
117 : : }
118 : :
119 : 0 : return sd_bus_message_append(reply, "i", n);
120 : : }
121 : :
122 : 0 : static int property_get_nice(
123 : : sd_bus *bus,
124 : : const char *path,
125 : : const char *interface,
126 : : const char *property,
127 : : sd_bus_message *reply,
128 : : void *userdata,
129 : : sd_bus_error *error) {
130 : :
131 : 0 : ExecContext *c = userdata;
132 : : int32_t n;
133 : :
134 [ # # ]: 0 : assert(bus);
135 [ # # ]: 0 : assert(reply);
136 [ # # ]: 0 : assert(c);
137 : :
138 [ # # ]: 0 : if (c->nice_set)
139 : 0 : n = c->nice;
140 : : else {
141 : 0 : errno = 0;
142 : 0 : n = getpriority(PRIO_PROCESS, 0);
143 [ # # ]: 0 : if (errno > 0)
144 : 0 : n = 0;
145 : : }
146 : :
147 : 0 : return sd_bus_message_append(reply, "i", n);
148 : : }
149 : :
150 : 0 : static int property_get_cpu_sched_policy(
151 : : sd_bus *bus,
152 : : const char *path,
153 : : const char *interface,
154 : : const char *property,
155 : : sd_bus_message *reply,
156 : : void *userdata,
157 : : sd_bus_error *error) {
158 : :
159 : 0 : ExecContext *c = userdata;
160 : : int32_t n;
161 : :
162 [ # # ]: 0 : assert(bus);
163 [ # # ]: 0 : assert(reply);
164 [ # # ]: 0 : assert(c);
165 : :
166 [ # # ]: 0 : if (c->cpu_sched_set)
167 : 0 : n = c->cpu_sched_policy;
168 : : else {
169 : 0 : n = sched_getscheduler(0);
170 [ # # ]: 0 : if (n < 0)
171 : 0 : n = SCHED_OTHER;
172 : : }
173 : :
174 : 0 : return sd_bus_message_append(reply, "i", n);
175 : : }
176 : :
177 : 0 : static int property_get_cpu_sched_priority(
178 : : sd_bus *bus,
179 : : const char *path,
180 : : const char *interface,
181 : : const char *property,
182 : : sd_bus_message *reply,
183 : : void *userdata,
184 : : sd_bus_error *error) {
185 : :
186 : 0 : ExecContext *c = userdata;
187 : : int32_t n;
188 : :
189 [ # # ]: 0 : assert(bus);
190 [ # # ]: 0 : assert(reply);
191 [ # # ]: 0 : assert(c);
192 : :
193 [ # # ]: 0 : if (c->cpu_sched_set)
194 : 0 : n = c->cpu_sched_priority;
195 : : else {
196 : 0 : struct sched_param p = {};
197 : :
198 [ # # ]: 0 : if (sched_getparam(0, &p) >= 0)
199 : 0 : n = p.sched_priority;
200 : : else
201 : 0 : n = 0;
202 : : }
203 : :
204 : 0 : return sd_bus_message_append(reply, "i", n);
205 : : }
206 : :
207 : 0 : static int property_get_cpu_affinity(
208 : : sd_bus *bus,
209 : : const char *path,
210 : : const char *interface,
211 : : const char *property,
212 : : sd_bus_message *reply,
213 : : void *userdata,
214 : : sd_bus_error *error) {
215 : :
216 : 0 : ExecContext *c = userdata;
217 : 0 : _cleanup_free_ uint8_t *array = NULL;
218 : : size_t allocated;
219 : :
220 [ # # ]: 0 : assert(bus);
221 [ # # ]: 0 : assert(reply);
222 [ # # ]: 0 : assert(c);
223 : :
224 : 0 : (void) cpu_set_to_dbus(&c->cpu_set, &array, &allocated);
225 : 0 : return sd_bus_message_append_array(reply, 'y', array, allocated);
226 : : }
227 : :
228 : 0 : static int property_get_numa_mask(
229 : : sd_bus *bus,
230 : : const char *path,
231 : : const char *interface,
232 : : const char *property,
233 : : sd_bus_message *reply,
234 : : void *userdata,
235 : : sd_bus_error *error) {
236 : :
237 : 0 : ExecContext *c = userdata;
238 : 0 : _cleanup_free_ uint8_t *array = NULL;
239 : : size_t allocated;
240 : :
241 [ # # ]: 0 : assert(bus);
242 [ # # ]: 0 : assert(reply);
243 [ # # ]: 0 : assert(c);
244 : :
245 : 0 : (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
246 : :
247 : 0 : return sd_bus_message_append_array(reply, 'y', array, allocated);
248 : : }
249 : :
250 : 0 : static int property_get_numa_policy(
251 : : sd_bus *bus,
252 : : const char *path,
253 : : const char *interface,
254 : : const char *property,
255 : : sd_bus_message *reply,
256 : : void *userdata,
257 : : sd_bus_error *error) {
258 : 0 : ExecContext *c = userdata;
259 : : int32_t policy;
260 : :
261 [ # # ]: 0 : assert(bus);
262 [ # # ]: 0 : assert(reply);
263 [ # # ]: 0 : assert(c);
264 : :
265 : 0 : policy = numa_policy_get_type(&c->numa_policy);
266 : :
267 : 0 : return sd_bus_message_append_basic(reply, 'i', &policy);
268 : : }
269 : :
270 : 0 : static int property_get_timer_slack_nsec(
271 : : sd_bus *bus,
272 : : const char *path,
273 : : const char *interface,
274 : : const char *property,
275 : : sd_bus_message *reply,
276 : : void *userdata,
277 : : sd_bus_error *error) {
278 : :
279 : 0 : ExecContext *c = userdata;
280 : : uint64_t u;
281 : :
282 [ # # ]: 0 : assert(bus);
283 [ # # ]: 0 : assert(reply);
284 [ # # ]: 0 : assert(c);
285 : :
286 [ # # ]: 0 : if (c->timer_slack_nsec != NSEC_INFINITY)
287 : 0 : u = (uint64_t) c->timer_slack_nsec;
288 : : else
289 : 0 : u = (uint64_t) prctl(PR_GET_TIMERSLACK);
290 : :
291 : 0 : return sd_bus_message_append(reply, "t", u);
292 : : }
293 : :
294 : 0 : static int property_get_syscall_filter(
295 : : sd_bus *bus,
296 : : const char *path,
297 : : const char *interface,
298 : : const char *property,
299 : : sd_bus_message *reply,
300 : : void *userdata,
301 : : sd_bus_error *error) {
302 : :
303 : 0 : ExecContext *c = userdata;
304 : 0 : _cleanup_strv_free_ char **l = NULL;
305 : : int r;
306 : :
307 : : #if HAVE_SECCOMP
308 : : Iterator i;
309 : : void *id, *val;
310 : : #endif
311 : :
312 [ # # ]: 0 : assert(bus);
313 [ # # ]: 0 : assert(reply);
314 [ # # ]: 0 : assert(c);
315 : :
316 : 0 : r = sd_bus_message_open_container(reply, 'r', "bas");
317 [ # # ]: 0 : if (r < 0)
318 : 0 : return r;
319 : :
320 : 0 : r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
321 [ # # ]: 0 : if (r < 0)
322 : 0 : return r;
323 : :
324 : : #if HAVE_SECCOMP
325 [ # # ]: 0 : HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, i) {
326 [ # # # ]: 0 : _cleanup_free_ char *name = NULL;
327 : 0 : const char *e = NULL;
328 : : char *s;
329 : 0 : int num = PTR_TO_INT(val);
330 : :
331 : 0 : name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
332 [ # # ]: 0 : if (!name)
333 : 0 : continue;
334 : :
335 [ # # ]: 0 : if (num >= 0) {
336 : 0 : e = errno_to_name(num);
337 [ # # ]: 0 : if (e) {
338 : 0 : s = strjoin(name, ":", e);
339 [ # # ]: 0 : if (!s)
340 : 0 : return -ENOMEM;
341 : : } else {
342 : 0 : r = asprintf(&s, "%s:%d", name, num);
343 [ # # ]: 0 : if (r < 0)
344 : 0 : return -ENOMEM;
345 : : }
346 : : } else
347 : 0 : s = TAKE_PTR(name);
348 : :
349 : 0 : r = strv_consume(&l, s);
350 [ # # ]: 0 : if (r < 0)
351 : 0 : return r;
352 : : }
353 : : #endif
354 : :
355 : 0 : strv_sort(l);
356 : :
357 : 0 : r = sd_bus_message_append_strv(reply, l);
358 [ # # ]: 0 : if (r < 0)
359 : 0 : return r;
360 : :
361 : 0 : return sd_bus_message_close_container(reply);
362 : : }
363 : :
364 : 0 : static int property_get_syscall_archs(
365 : : sd_bus *bus,
366 : : const char *path,
367 : : const char *interface,
368 : : const char *property,
369 : : sd_bus_message *reply,
370 : : void *userdata,
371 : : sd_bus_error *error) {
372 : :
373 : 0 : ExecContext *c = userdata;
374 : 0 : _cleanup_strv_free_ char **l = NULL;
375 : : int r;
376 : :
377 : : #if HAVE_SECCOMP
378 : : Iterator i;
379 : : void *id;
380 : : #endif
381 : :
382 [ # # ]: 0 : assert(bus);
383 [ # # ]: 0 : assert(reply);
384 [ # # ]: 0 : assert(c);
385 : :
386 : : #if HAVE_SECCOMP
387 [ # # ]: 0 : SET_FOREACH(id, c->syscall_archs, i) {
388 : : const char *name;
389 : :
390 : 0 : name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
391 [ # # ]: 0 : if (!name)
392 : 0 : continue;
393 : :
394 : 0 : r = strv_extend(&l, name);
395 [ # # ]: 0 : if (r < 0)
396 : 0 : return -ENOMEM;
397 : : }
398 : : #endif
399 : :
400 : 0 : strv_sort(l);
401 : :
402 : 0 : r = sd_bus_message_append_strv(reply, l);
403 [ # # ]: 0 : if (r < 0)
404 : 0 : return r;
405 : :
406 : 0 : return 0;
407 : : }
408 : :
409 : 0 : static int property_get_selinux_context(
410 : : sd_bus *bus,
411 : : const char *path,
412 : : const char *interface,
413 : : const char *property,
414 : : sd_bus_message *reply,
415 : : void *userdata,
416 : : sd_bus_error *error) {
417 : :
418 : 0 : ExecContext *c = userdata;
419 : :
420 [ # # ]: 0 : assert(bus);
421 [ # # ]: 0 : assert(reply);
422 [ # # ]: 0 : assert(c);
423 : :
424 : 0 : return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
425 : : }
426 : :
427 : 0 : static int property_get_apparmor_profile(
428 : : sd_bus *bus,
429 : : const char *path,
430 : : const char *interface,
431 : : const char *property,
432 : : sd_bus_message *reply,
433 : : void *userdata,
434 : : sd_bus_error *error) {
435 : :
436 : 0 : ExecContext *c = userdata;
437 : :
438 [ # # ]: 0 : assert(bus);
439 [ # # ]: 0 : assert(reply);
440 [ # # ]: 0 : assert(c);
441 : :
442 : 0 : return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
443 : : }
444 : :
445 : 0 : static int property_get_smack_process_label(
446 : : sd_bus *bus,
447 : : const char *path,
448 : : const char *interface,
449 : : const char *property,
450 : : sd_bus_message *reply,
451 : : void *userdata,
452 : : sd_bus_error *error) {
453 : :
454 : 0 : ExecContext *c = userdata;
455 : :
456 [ # # ]: 0 : assert(bus);
457 [ # # ]: 0 : assert(reply);
458 [ # # ]: 0 : assert(c);
459 : :
460 : 0 : return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
461 : : }
462 : :
463 : 0 : static int property_get_address_families(
464 : : sd_bus *bus,
465 : : const char *path,
466 : : const char *interface,
467 : : const char *property,
468 : : sd_bus_message *reply,
469 : : void *userdata,
470 : : sd_bus_error *error) {
471 : :
472 : 0 : ExecContext *c = userdata;
473 : 0 : _cleanup_strv_free_ char **l = NULL;
474 : : Iterator i;
475 : : void *af;
476 : : int r;
477 : :
478 [ # # ]: 0 : assert(bus);
479 [ # # ]: 0 : assert(reply);
480 [ # # ]: 0 : assert(c);
481 : :
482 : 0 : r = sd_bus_message_open_container(reply, 'r', "bas");
483 [ # # ]: 0 : if (r < 0)
484 : 0 : return r;
485 : :
486 : 0 : r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
487 [ # # ]: 0 : if (r < 0)
488 : 0 : return r;
489 : :
490 [ # # ]: 0 : SET_FOREACH(af, c->address_families, i) {
491 : : const char *name;
492 : :
493 : 0 : name = af_to_name(PTR_TO_INT(af));
494 [ # # ]: 0 : if (!name)
495 : 0 : continue;
496 : :
497 : 0 : r = strv_extend(&l, name);
498 [ # # ]: 0 : if (r < 0)
499 : 0 : return -ENOMEM;
500 : : }
501 : :
502 : 0 : strv_sort(l);
503 : :
504 : 0 : r = sd_bus_message_append_strv(reply, l);
505 [ # # ]: 0 : if (r < 0)
506 : 0 : return r;
507 : :
508 : 0 : return sd_bus_message_close_container(reply);
509 : : }
510 : :
511 : 0 : static int property_get_working_directory(
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 : 0 : ExecContext *c = userdata;
521 : : const char *wd;
522 : :
523 [ # # ]: 0 : assert(bus);
524 [ # # ]: 0 : assert(reply);
525 [ # # ]: 0 : assert(c);
526 : :
527 [ # # ]: 0 : if (c->working_directory_home)
528 : 0 : wd = "~";
529 : : else
530 : 0 : wd = c->working_directory;
531 : :
532 [ # # ]: 0 : if (c->working_directory_missing_ok)
533 [ # # # # : 0 : wd = strjoina("!", wd);
# # # # #
# # # ]
534 : :
535 : 0 : return sd_bus_message_append(reply, "s", wd);
536 : : }
537 : :
538 : 0 : static int property_get_stdio_fdname(
539 : : sd_bus *bus,
540 : : const char *path,
541 : : const char *interface,
542 : : const char *property,
543 : : sd_bus_message *reply,
544 : : void *userdata,
545 : : sd_bus_error *error) {
546 : :
547 : 0 : ExecContext *c = userdata;
548 : : int fileno;
549 : :
550 [ # # ]: 0 : assert(bus);
551 [ # # ]: 0 : assert(c);
552 [ # # ]: 0 : assert(property);
553 [ # # ]: 0 : assert(reply);
554 : :
555 [ # # ]: 0 : if (streq(property, "StandardInputFileDescriptorName"))
556 : 0 : fileno = STDIN_FILENO;
557 [ # # ]: 0 : else if (streq(property, "StandardOutputFileDescriptorName"))
558 : 0 : fileno = STDOUT_FILENO;
559 : : else {
560 [ # # ]: 0 : assert(streq(property, "StandardErrorFileDescriptorName"));
561 : 0 : fileno = STDERR_FILENO;
562 : : }
563 : :
564 : 0 : return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
565 : : }
566 : :
567 : 0 : static int property_get_input_data(
568 : : sd_bus *bus,
569 : : const char *path,
570 : : const char *interface,
571 : : const char *property,
572 : : sd_bus_message *reply,
573 : : void *userdata,
574 : : sd_bus_error *error) {
575 : :
576 : 0 : ExecContext *c = userdata;
577 : :
578 [ # # ]: 0 : assert(bus);
579 [ # # ]: 0 : assert(c);
580 [ # # ]: 0 : assert(property);
581 [ # # ]: 0 : assert(reply);
582 : :
583 : 0 : return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
584 : : }
585 : :
586 : 0 : static int property_get_bind_paths(
587 : : sd_bus *bus,
588 : : const char *path,
589 : : const char *interface,
590 : : const char *property,
591 : : sd_bus_message *reply,
592 : : void *userdata,
593 : : sd_bus_error *error) {
594 : :
595 : 0 : ExecContext *c = userdata;
596 : : unsigned i;
597 : : bool ro;
598 : : int r;
599 : :
600 [ # # ]: 0 : assert(bus);
601 [ # # ]: 0 : assert(c);
602 [ # # ]: 0 : assert(property);
603 [ # # ]: 0 : assert(reply);
604 : :
605 : 0 : ro = strstr(property, "ReadOnly");
606 : :
607 : 0 : r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
608 [ # # ]: 0 : if (r < 0)
609 : 0 : return r;
610 : :
611 [ # # ]: 0 : for (i = 0; i < c->n_bind_mounts; i++) {
612 : :
613 [ # # ]: 0 : if (ro != c->bind_mounts[i].read_only)
614 : 0 : continue;
615 : :
616 : 0 : r = sd_bus_message_append(
617 : : reply, "(ssbt)",
618 : 0 : c->bind_mounts[i].source,
619 : 0 : c->bind_mounts[i].destination,
620 : 0 : c->bind_mounts[i].ignore_enoent,
621 : 0 : c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
622 [ # # ]: 0 : if (r < 0)
623 : 0 : return r;
624 : : }
625 : :
626 : 0 : return sd_bus_message_close_container(reply);
627 : : }
628 : :
629 : 0 : static int property_get_temporary_filesystems(
630 : : sd_bus *bus,
631 : : const char *path,
632 : : const char *interface,
633 : : const char *property,
634 : : sd_bus_message *reply,
635 : : void *userdata,
636 : : sd_bus_error *error) {
637 : :
638 : 0 : ExecContext *c = userdata;
639 : : unsigned i;
640 : : int r;
641 : :
642 [ # # ]: 0 : assert(bus);
643 [ # # ]: 0 : assert(c);
644 [ # # ]: 0 : assert(property);
645 [ # # ]: 0 : assert(reply);
646 : :
647 : 0 : r = sd_bus_message_open_container(reply, 'a', "(ss)");
648 [ # # ]: 0 : if (r < 0)
649 : 0 : return r;
650 : :
651 [ # # ]: 0 : for (i = 0; i < c->n_temporary_filesystems; i++) {
652 : 0 : TemporaryFileSystem *t = c->temporary_filesystems + i;
653 : :
654 : 0 : r = sd_bus_message_append(
655 : : reply, "(ss)",
656 : : t->path,
657 : : t->options);
658 [ # # ]: 0 : if (r < 0)
659 : 0 : return r;
660 : : }
661 : :
662 : 0 : return sd_bus_message_close_container(reply);
663 : : }
664 : :
665 : 0 : static int property_get_log_extra_fields(
666 : : sd_bus *bus,
667 : : const char *path,
668 : : const char *interface,
669 : : const char *property,
670 : : sd_bus_message *reply,
671 : : void *userdata,
672 : : sd_bus_error *error) {
673 : :
674 : 0 : ExecContext *c = userdata;
675 : : size_t i;
676 : : int r;
677 : :
678 [ # # ]: 0 : assert(bus);
679 [ # # ]: 0 : assert(c);
680 [ # # ]: 0 : assert(property);
681 [ # # ]: 0 : assert(reply);
682 : :
683 : 0 : r = sd_bus_message_open_container(reply, 'a', "ay");
684 [ # # ]: 0 : if (r < 0)
685 : 0 : return r;
686 : :
687 [ # # ]: 0 : for (i = 0; i < c->n_log_extra_fields; i++) {
688 : 0 : r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len);
689 [ # # ]: 0 : if (r < 0)
690 : 0 : return r;
691 : : }
692 : :
693 : 0 : return sd_bus_message_close_container(reply);
694 : : }
695 : :
696 : : const sd_bus_vtable bus_exec_vtable[] = {
697 : : SD_BUS_VTABLE_START(0),
698 : : SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
699 : : SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
700 : : SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
701 : : SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
702 : : SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
703 : : SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
704 : : SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
705 : : SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
706 : : SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
707 : : SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
708 : : SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
709 : : SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
710 : : SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
711 : : SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
712 : : SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
713 : : SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
714 : : SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
715 : : SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
716 : : SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
717 : : SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
718 : : SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
719 : : SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
720 : : SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
721 : : SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
722 : : SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
723 : : SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
724 : : SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
725 : : SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
726 : : SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
727 : : SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
728 : : SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
729 : : SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
730 : : SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
731 : : SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
732 : : SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
733 : : SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
734 : : SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
735 : : SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
736 : : SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
737 : : SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
738 : : SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
739 : : SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
740 : : SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
741 : : SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
742 : : SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
743 : : SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
744 : : SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
745 : : SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
746 : : SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
747 : : SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
748 : : SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
749 : : SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
750 : : SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
751 : : SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
752 : : SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
753 : : SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
754 : : SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
755 : : SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
756 : : SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
757 : : SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
758 : : SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
759 : : SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
760 : : SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
761 : : SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
762 : : SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
763 : : SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
764 : : SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
765 : : SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
766 : : SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
767 : : SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST),
768 : : SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
769 : : SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
770 : : SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
771 : : SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
772 : : SD_BUS_PROPERTY("AmbientCapabilities", "t", NULL, offsetof(ExecContext, capability_ambient_set), SD_BUS_VTABLE_PROPERTY_CONST),
773 : : SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
774 : : SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
775 : : SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
776 : : SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
777 : : SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
778 : : SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
779 : : SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
780 : : SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
781 : : SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
782 : : SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
783 : : SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
784 : : SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
785 : : SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
786 : : SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
787 : : SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
788 : : SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
789 : : SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
790 : : SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_bool, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST),
791 : : SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
792 : : SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
793 : : SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
794 : : SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
795 : : SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
796 : : SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
797 : : SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
798 : : SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
799 : : SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
800 : : SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
801 : : SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
802 : : SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
803 : : SD_BUS_PROPERTY("SystemCallErrorNumber", "i", bus_property_get_int, offsetof(ExecContext, syscall_errno), SD_BUS_VTABLE_PROPERTY_CONST),
804 : : SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST),
805 : : SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
806 : : SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
807 : : SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
808 : : SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
809 : : SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST),
810 : : SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
811 : : SD_BUS_PROPERTY("StateDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
812 : : SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
813 : : SD_BUS_PROPERTY("CacheDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
814 : : SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
815 : : SD_BUS_PROPERTY("LogsDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].paths), SD_BUS_VTABLE_PROPERTY_CONST),
816 : : SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
817 : : SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
818 : : SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
819 : : SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
820 : : SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
821 : : SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
822 : : SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
823 : : SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
824 : : SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
825 : : SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
826 : : SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
827 : : SD_BUS_PROPERTY("ProtectHostname", "b", bus_property_get_bool, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
828 : : SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
829 : :
830 : : /* Obsolete/redundant properties: */
831 : : SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
832 : : SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
833 : : SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
834 : : SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
835 : : SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
836 : :
837 : : SD_BUS_VTABLE_END
838 : : };
839 : :
840 : 0 : static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
841 : : int r;
842 : :
843 [ # # ]: 0 : assert(reply);
844 [ # # ]: 0 : assert(c);
845 : :
846 [ # # ]: 0 : if (!c->path)
847 : 0 : return 0;
848 : :
849 : 0 : r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
850 [ # # ]: 0 : if (r < 0)
851 : 0 : return r;
852 : :
853 : 0 : r = sd_bus_message_append(reply, "s", c->path);
854 [ # # ]: 0 : if (r < 0)
855 : 0 : return r;
856 : :
857 : 0 : r = sd_bus_message_append_strv(reply, c->argv);
858 [ # # ]: 0 : if (r < 0)
859 : 0 : return r;
860 : :
861 : 0 : r = sd_bus_message_append(reply, "bttttuii",
862 : 0 : !!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
863 : : c->exec_status.start_timestamp.realtime,
864 : : c->exec_status.start_timestamp.monotonic,
865 : : c->exec_status.exit_timestamp.realtime,
866 : : c->exec_status.exit_timestamp.monotonic,
867 : 0 : (uint32_t) c->exec_status.pid,
868 : : (int32_t) c->exec_status.code,
869 : : (int32_t) c->exec_status.status);
870 [ # # ]: 0 : if (r < 0)
871 : 0 : return r;
872 : :
873 : 0 : return sd_bus_message_close_container(reply);
874 : : }
875 : :
876 : 0 : static int append_exec_ex_command(sd_bus_message *reply, ExecCommand *c) {
877 : 0 : _cleanup_strv_free_ char **ex_opts = NULL;
878 : : int r;
879 : :
880 [ # # ]: 0 : assert(reply);
881 [ # # ]: 0 : assert(c);
882 : :
883 [ # # ]: 0 : if (!c->path)
884 : 0 : return 0;
885 : :
886 : 0 : r = sd_bus_message_open_container(reply, 'r', "sasasttttuii");
887 [ # # ]: 0 : if (r < 0)
888 : 0 : return r;
889 : :
890 : 0 : r = sd_bus_message_append(reply, "s", c->path);
891 [ # # ]: 0 : if (r < 0)
892 : 0 : return r;
893 : :
894 : 0 : r = sd_bus_message_append_strv(reply, c->argv);
895 [ # # ]: 0 : if (r < 0)
896 : 0 : return r;
897 : :
898 : 0 : r = exec_command_flags_to_strv(c->flags, &ex_opts);
899 [ # # ]: 0 : if (r < 0)
900 : 0 : return r;
901 : :
902 : 0 : r = sd_bus_message_append_strv(reply, ex_opts);
903 [ # # ]: 0 : if (r < 0)
904 : 0 : return r;
905 : :
906 : 0 : r = sd_bus_message_append(reply, "ttttuii",
907 : : c->exec_status.start_timestamp.realtime,
908 : : c->exec_status.start_timestamp.monotonic,
909 : : c->exec_status.exit_timestamp.realtime,
910 : : c->exec_status.exit_timestamp.monotonic,
911 : 0 : (uint32_t) c->exec_status.pid,
912 : : (int32_t) c->exec_status.code,
913 : : (int32_t) c->exec_status.status);
914 [ # # ]: 0 : if (r < 0)
915 : 0 : return r;
916 : :
917 : 0 : return sd_bus_message_close_container(reply);
918 : : }
919 : :
920 : 0 : int bus_property_get_exec_command(
921 : : sd_bus *bus,
922 : : const char *path,
923 : : const char *interface,
924 : : const char *property,
925 : : sd_bus_message *reply,
926 : : void *userdata,
927 : : sd_bus_error *ret_error) {
928 : :
929 : 0 : ExecCommand *c = (ExecCommand*) userdata;
930 : : int r;
931 : :
932 [ # # ]: 0 : assert(bus);
933 [ # # ]: 0 : assert(reply);
934 : :
935 : 0 : r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
936 [ # # ]: 0 : if (r < 0)
937 : 0 : return r;
938 : :
939 : 0 : r = append_exec_command(reply, c);
940 [ # # ]: 0 : if (r < 0)
941 : 0 : return r;
942 : :
943 : 0 : return sd_bus_message_close_container(reply);
944 : : }
945 : :
946 : 0 : int bus_property_get_exec_command_list(
947 : : sd_bus *bus,
948 : : const char *path,
949 : : const char *interface,
950 : : const char *property,
951 : : sd_bus_message *reply,
952 : : void *userdata,
953 : : sd_bus_error *ret_error) {
954 : :
955 : 0 : ExecCommand *c = *(ExecCommand**) userdata;
956 : : int r;
957 : :
958 [ # # ]: 0 : assert(bus);
959 [ # # ]: 0 : assert(reply);
960 : :
961 : 0 : r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
962 [ # # ]: 0 : if (r < 0)
963 : 0 : return r;
964 : :
965 [ # # ]: 0 : LIST_FOREACH(command, c, c) {
966 : 0 : r = append_exec_command(reply, c);
967 [ # # ]: 0 : if (r < 0)
968 : 0 : return r;
969 : : }
970 : :
971 : 0 : return sd_bus_message_close_container(reply);
972 : : }
973 : :
974 : 0 : int bus_property_get_exec_ex_command_list(
975 : : sd_bus *bus,
976 : : const char *path,
977 : : const char *interface,
978 : : const char *property,
979 : : sd_bus_message *reply,
980 : : void *userdata,
981 : : sd_bus_error *ret_error) {
982 : :
983 : 0 : ExecCommand *c, *exec_command = *(ExecCommand**) userdata;
984 : : int r;
985 : :
986 [ # # ]: 0 : assert(bus);
987 [ # # ]: 0 : assert(reply);
988 : :
989 : 0 : r = sd_bus_message_open_container(reply, 'a', "(sasasttttuii)");
990 [ # # ]: 0 : if (r < 0)
991 : 0 : return r;
992 : :
993 [ # # ]: 0 : LIST_FOREACH(command, c, exec_command) {
994 : 0 : r = append_exec_ex_command(reply, c);
995 [ # # ]: 0 : if (r < 0)
996 : 0 : return r;
997 : : }
998 : :
999 : 0 : return sd_bus_message_close_container(reply);
1000 : : }
1001 : :
1002 : 0 : static char *exec_command_flags_to_exec_chars(ExecCommandFlags flags) {
1003 [ # # # # : 0 : return strjoin(FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE) ? "-" : "",
# # # # #
# ]
1004 : : FLAGS_SET(flags, EXEC_COMMAND_NO_ENV_EXPAND) ? ":" : "",
1005 : : FLAGS_SET(flags, EXEC_COMMAND_FULLY_PRIVILEGED) ? "+" : "",
1006 : : FLAGS_SET(flags, EXEC_COMMAND_NO_SETUID) ? "!" : "",
1007 : : FLAGS_SET(flags, EXEC_COMMAND_AMBIENT_MAGIC) ? "!!" : "");
1008 : : }
1009 : :
1010 : 0 : int bus_set_transient_exec_command(
1011 : : Unit *u,
1012 : : const char *name,
1013 : : ExecCommand **exec_command,
1014 : : sd_bus_message *message,
1015 : : UnitWriteFlags flags,
1016 : : sd_bus_error *error) {
1017 : 0 : bool is_ex_prop = endswith(name, "Ex");
1018 : 0 : unsigned n = 0;
1019 : : int r;
1020 : :
1021 [ # # ]: 0 : r = sd_bus_message_enter_container(message, 'a', is_ex_prop ? "(sasas)" : "(sasb)");
1022 [ # # ]: 0 : if (r < 0)
1023 : 0 : return r;
1024 : :
1025 [ # # # # ]: 0 : while ((r = sd_bus_message_enter_container(message, 'r', is_ex_prop ? "sasas" : "sasb")) > 0) {
1026 [ # # # # ]: 0 : _cleanup_strv_free_ char **argv = NULL, **ex_opts = NULL;
1027 : : const char *path;
1028 : : int b;
1029 : :
1030 : 0 : r = sd_bus_message_read(message, "s", &path);
1031 [ # # ]: 0 : if (r < 0)
1032 : 0 : return r;
1033 : :
1034 [ # # ]: 0 : if (!path_is_absolute(path))
1035 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
1036 : :
1037 : 0 : r = sd_bus_message_read_strv(message, &argv);
1038 [ # # ]: 0 : if (r < 0)
1039 : 0 : return r;
1040 : :
1041 [ # # ]: 0 : r = is_ex_prop ? sd_bus_message_read_strv(message, &ex_opts) : sd_bus_message_read(message, "b", &b);
1042 [ # # ]: 0 : if (r < 0)
1043 : 0 : return r;
1044 : :
1045 : 0 : r = sd_bus_message_exit_container(message);
1046 [ # # ]: 0 : if (r < 0)
1047 : 0 : return r;
1048 : :
1049 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1050 : : ExecCommand *c;
1051 : :
1052 : 0 : c = new0(ExecCommand, 1);
1053 [ # # ]: 0 : if (!c)
1054 : 0 : return -ENOMEM;
1055 : :
1056 : 0 : c->path = strdup(path);
1057 [ # # ]: 0 : if (!c->path) {
1058 : 0 : free(c);
1059 : 0 : return -ENOMEM;
1060 : : }
1061 : :
1062 : 0 : c->argv = TAKE_PTR(argv);
1063 : :
1064 [ # # ]: 0 : if (is_ex_prop) {
1065 : 0 : r = exec_command_flags_from_strv(ex_opts, &c->flags);
1066 [ # # ]: 0 : if (r < 0)
1067 : 0 : return r;
1068 : : } else
1069 : 0 : c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
1070 : :
1071 : 0 : path_simplify(c->path, false);
1072 : 0 : exec_command_append_list(exec_command, c);
1073 : : }
1074 : :
1075 : 0 : n++;
1076 : : }
1077 [ # # ]: 0 : if (r < 0)
1078 : 0 : return r;
1079 : :
1080 : 0 : r = sd_bus_message_exit_container(message);
1081 [ # # ]: 0 : if (r < 0)
1082 : 0 : return r;
1083 : :
1084 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1085 [ # # ]: 0 : _cleanup_free_ char *buf = NULL;
1086 [ # # ]: 0 : _cleanup_fclose_ FILE *f = NULL;
1087 : : ExecCommand *c;
1088 : 0 : size_t size = 0;
1089 : :
1090 [ # # ]: 0 : if (n == 0)
1091 : 0 : *exec_command = exec_command_free_list(*exec_command);
1092 : :
1093 : 0 : f = open_memstream_unlocked(&buf, &size);
1094 [ # # ]: 0 : if (!f)
1095 : 0 : return -ENOMEM;
1096 : :
1097 : 0 : fputs("ExecStart=\n", f);
1098 : :
1099 [ # # ]: 0 : LIST_FOREACH(command, c, *exec_command) {
1100 [ # # # # : 0 : _cleanup_free_ char *a = NULL, *t = NULL, *exec_chars = NULL;
# # ]
1101 : : const char *p;
1102 : :
1103 : 0 : p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t);
1104 [ # # ]: 0 : if (!p)
1105 : 0 : return -ENOMEM;
1106 : :
1107 : 0 : a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS);
1108 [ # # ]: 0 : if (!a)
1109 : 0 : return -ENOMEM;
1110 : :
1111 : 0 : exec_chars = exec_command_flags_to_exec_chars(c->flags);
1112 [ # # ]: 0 : if (!exec_chars)
1113 : 0 : return -ENOMEM;
1114 : :
1115 : 0 : fprintf(f, "%s=%s@%s %s\n", name, exec_chars, p, a);
1116 : : }
1117 : :
1118 : 0 : r = fflush_and_check(f);
1119 [ # # ]: 0 : if (r < 0)
1120 : 0 : return r;
1121 : :
1122 : 0 : unit_write_setting(u, flags, name, buf);
1123 : : }
1124 : :
1125 : 0 : return 1;
1126 : : }
1127 : :
1128 : 0 : static int parse_personality(const char *s, unsigned long *p) {
1129 : : unsigned long v;
1130 : :
1131 [ # # ]: 0 : assert(p);
1132 : :
1133 : 0 : v = personality_from_string(s);
1134 [ # # ]: 0 : if (v == PERSONALITY_INVALID)
1135 : 0 : return -EINVAL;
1136 : :
1137 : 0 : *p = v;
1138 : 0 : return 0;
1139 : : }
1140 : :
1141 : 0 : static const char* mount_propagation_flags_to_string_with_check(unsigned long n) {
1142 [ # # # # ]: 0 : if (!IN_SET(n, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
1143 : 0 : return NULL;
1144 : :
1145 : 0 : return mount_propagation_flags_to_string(n);
1146 : : }
1147 : :
1148 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
# # ]
1149 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
# # # # ]
1150 : : #if HAVE_SECCOMP
1151 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, errno_is_valid);
# # # # ]
1152 : : #endif
1153 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
# # # # ]
1154 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
# # # # ]
1155 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
# # # # ]
1156 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
# # # # ]
1157 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
# # # # ]
1158 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
# # # # ]
1159 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
# # # # ]
1160 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
# # # # ]
1161 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
# # # # #
# ]
1162 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc);
# # # # #
# ]
1163 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
# # # # #
# ]
1164 [ # # # # : 0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check);
# # # # ]
1165 : :
1166 : 0 : int bus_exec_context_set_transient_property(
1167 : : Unit *u,
1168 : : ExecContext *c,
1169 : : const char *name,
1170 : : sd_bus_message *message,
1171 : : UnitWriteFlags flags,
1172 : : sd_bus_error *error) {
1173 : :
1174 : : const char *suffix;
1175 : : int r;
1176 : :
1177 [ # # ]: 0 : assert(u);
1178 [ # # ]: 0 : assert(c);
1179 [ # # ]: 0 : assert(name);
1180 [ # # ]: 0 : assert(message);
1181 : :
1182 : 0 : flags |= UNIT_PRIVATE;
1183 : :
1184 [ # # ]: 0 : if (streq(name, "User"))
1185 : 0 : return bus_set_transient_user(u, name, &c->user, message, flags, error);
1186 : :
1187 [ # # ]: 0 : if (streq(name, "Group"))
1188 : 0 : return bus_set_transient_user(u, name, &c->group, message, flags, error);
1189 : :
1190 [ # # ]: 0 : if (streq(name, "TTYPath"))
1191 : 0 : return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
1192 : :
1193 [ # # ]: 0 : if (streq(name, "RootImage"))
1194 : 0 : return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
1195 : :
1196 [ # # ]: 0 : if (streq(name, "RootDirectory"))
1197 : 0 : return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
1198 : :
1199 [ # # ]: 0 : if (streq(name, "SyslogIdentifier"))
1200 : 0 : return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
1201 : :
1202 [ # # ]: 0 : if (streq(name, "LogLevelMax"))
1203 : 0 : return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
1204 : :
1205 [ # # ]: 0 : if (streq(name, "LogRateLimitIntervalUSec"))
1206 : 0 : return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error);
1207 : :
1208 [ # # ]: 0 : if (streq(name, "LogRateLimitBurst"))
1209 : 0 : return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error);
1210 : :
1211 [ # # ]: 0 : if (streq(name, "Personality"))
1212 : 0 : return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
1213 : :
1214 [ # # ]: 0 : if (streq(name, "StandardInput"))
1215 : 0 : return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
1216 : :
1217 [ # # ]: 0 : if (streq(name, "StandardOutput"))
1218 : 0 : return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
1219 : :
1220 [ # # ]: 0 : if (streq(name, "StandardError"))
1221 : 0 : return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
1222 : :
1223 [ # # ]: 0 : if (streq(name, "IgnoreSIGPIPE"))
1224 : 0 : return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
1225 : :
1226 [ # # ]: 0 : if (streq(name, "TTYVHangup"))
1227 : 0 : return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
1228 : :
1229 [ # # ]: 0 : if (streq(name, "TTYReset"))
1230 : 0 : return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
1231 : :
1232 [ # # ]: 0 : if (streq(name, "TTYVTDisallocate"))
1233 : 0 : return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
1234 : :
1235 [ # # ]: 0 : if (streq(name, "PrivateTmp"))
1236 : 0 : return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error);
1237 : :
1238 [ # # ]: 0 : if (streq(name, "PrivateDevices"))
1239 : 0 : return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
1240 : :
1241 [ # # ]: 0 : if (streq(name, "PrivateMounts"))
1242 : 0 : return bus_set_transient_bool(u, name, &c->private_mounts, message, flags, error);
1243 : :
1244 [ # # ]: 0 : if (streq(name, "PrivateNetwork"))
1245 : 0 : return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
1246 : :
1247 [ # # ]: 0 : if (streq(name, "PrivateUsers"))
1248 : 0 : return bus_set_transient_bool(u, name, &c->private_users, message, flags, error);
1249 : :
1250 [ # # ]: 0 : if (streq(name, "NoNewPrivileges"))
1251 : 0 : return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
1252 : :
1253 [ # # ]: 0 : if (streq(name, "SyslogLevelPrefix"))
1254 : 0 : return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
1255 : :
1256 [ # # ]: 0 : if (streq(name, "MemoryDenyWriteExecute"))
1257 : 0 : return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
1258 : :
1259 [ # # ]: 0 : if (streq(name, "RestrictRealtime"))
1260 : 0 : return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
1261 : :
1262 [ # # ]: 0 : if (streq(name, "RestrictSUIDSGID"))
1263 : 0 : return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
1264 : :
1265 [ # # ]: 0 : if (streq(name, "DynamicUser"))
1266 : 0 : return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
1267 : :
1268 [ # # ]: 0 : if (streq(name, "RemoveIPC"))
1269 : 0 : return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
1270 : :
1271 [ # # ]: 0 : if (streq(name, "ProtectKernelTunables"))
1272 : 0 : return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
1273 : :
1274 [ # # ]: 0 : if (streq(name, "ProtectKernelModules"))
1275 : 0 : return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
1276 : :
1277 [ # # ]: 0 : if (streq(name, "ProtectControlGroups"))
1278 : 0 : return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
1279 : :
1280 [ # # ]: 0 : if (streq(name, "MountAPIVFS"))
1281 : 0 : return bus_set_transient_bool(u, name, &c->mount_apivfs, message, flags, error);
1282 : :
1283 [ # # ]: 0 : if (streq(name, "CPUSchedulingResetOnFork"))
1284 : 0 : return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
1285 : :
1286 [ # # ]: 0 : if (streq(name, "NonBlocking"))
1287 : 0 : return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
1288 : :
1289 [ # # ]: 0 : if (streq(name, "LockPersonality"))
1290 : 0 : return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
1291 : :
1292 [ # # ]: 0 : if (streq(name, "ProtectHostname"))
1293 : 0 : return bus_set_transient_bool(u, name, &c->protect_hostname, message, flags, error);
1294 : :
1295 [ # # ]: 0 : if (streq(name, "UtmpIdentifier"))
1296 : 0 : return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
1297 : :
1298 [ # # ]: 0 : if (streq(name, "UtmpMode"))
1299 : 0 : return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
1300 : :
1301 [ # # ]: 0 : if (streq(name, "PAMName"))
1302 : 0 : return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
1303 : :
1304 [ # # ]: 0 : if (streq(name, "TimerSlackNSec"))
1305 : 0 : return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
1306 : :
1307 [ # # ]: 0 : if (streq(name, "ProtectSystem"))
1308 : 0 : return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
1309 : :
1310 [ # # ]: 0 : if (streq(name, "ProtectHome"))
1311 : 0 : return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
1312 : :
1313 [ # # ]: 0 : if (streq(name, "KeyringMode"))
1314 : 0 : return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
1315 : :
1316 [ # # ]: 0 : if (streq(name, "RuntimeDirectoryPreserve"))
1317 : 0 : return bus_set_transient_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
1318 : :
1319 [ # # ]: 0 : if (streq(name, "UMask"))
1320 : 0 : return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
1321 : :
1322 [ # # ]: 0 : if (streq(name, "RuntimeDirectoryMode"))
1323 : 0 : return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
1324 : :
1325 [ # # ]: 0 : if (streq(name, "StateDirectoryMode"))
1326 : 0 : return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
1327 : :
1328 [ # # ]: 0 : if (streq(name, "CacheDirectoryMode"))
1329 : 0 : return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
1330 : :
1331 [ # # ]: 0 : if (streq(name, "LogsDirectoryMode"))
1332 : 0 : return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
1333 : :
1334 [ # # ]: 0 : if (streq(name, "ConfigurationDirectoryMode"))
1335 : 0 : return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
1336 : :
1337 [ # # ]: 0 : if (streq(name, "SELinuxContext"))
1338 : 0 : return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
1339 : :
1340 [ # # ]: 0 : if (streq(name, "SecureBits"))
1341 : 0 : return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
1342 : :
1343 [ # # ]: 0 : if (streq(name, "CapabilityBoundingSet"))
1344 : 0 : return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
1345 : :
1346 [ # # ]: 0 : if (streq(name, "AmbientCapabilities"))
1347 : 0 : return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
1348 : :
1349 [ # # ]: 0 : if (streq(name, "RestrictNamespaces"))
1350 : 0 : return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
1351 : :
1352 [ # # ]: 0 : if (streq(name, "MountFlags"))
1353 : 0 : return bus_set_transient_mount_flags(u, name, &c->mount_flags, message, flags, error);
1354 : :
1355 [ # # ]: 0 : if (streq(name, "NetworkNamespacePath"))
1356 : 0 : return bus_set_transient_path(u, name, &c->network_namespace_path, message, flags, error);
1357 : :
1358 [ # # ]: 0 : if (streq(name, "SupplementaryGroups")) {
1359 : 0 : _cleanup_strv_free_ char **l = NULL;
1360 : : char **p;
1361 : :
1362 : 0 : r = sd_bus_message_read_strv(message, &l);
1363 [ # # ]: 0 : if (r < 0)
1364 : 0 : return r;
1365 : :
1366 [ # # # # ]: 0 : STRV_FOREACH(p, l) {
1367 [ # # # # ]: 0 : if (!isempty(*p) && !valid_user_group_name_or_id(*p))
1368 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
1369 : : }
1370 : :
1371 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1372 [ # # ]: 0 : if (strv_isempty(l)) {
1373 : 0 : c->supplementary_groups = strv_free(c->supplementary_groups);
1374 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
1375 : : } else {
1376 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
1377 : :
1378 : 0 : r = strv_extend_strv(&c->supplementary_groups, l, true);
1379 [ # # ]: 0 : if (r < 0)
1380 : 0 : return -ENOMEM;
1381 : :
1382 : 0 : joined = strv_join(c->supplementary_groups, " ");
1383 [ # # ]: 0 : if (!joined)
1384 : 0 : return -ENOMEM;
1385 : :
1386 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
1387 : : }
1388 : : }
1389 : :
1390 : 0 : return 1;
1391 : :
1392 [ # # ]: 0 : } else if (streq(name, "SyslogLevel")) {
1393 : : int32_t level;
1394 : :
1395 : 0 : r = sd_bus_message_read(message, "i", &level);
1396 [ # # ]: 0 : if (r < 0)
1397 : 0 : return r;
1398 : :
1399 [ # # ]: 0 : if (!log_level_is_valid(level))
1400 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
1401 : :
1402 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1403 : 0 : c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
1404 : 0 : unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
1405 : : }
1406 : :
1407 : 0 : return 1;
1408 : :
1409 [ # # ]: 0 : } else if (streq(name, "SyslogFacility")) {
1410 : : int32_t facility;
1411 : :
1412 : 0 : r = sd_bus_message_read(message, "i", &facility);
1413 [ # # ]: 0 : if (r < 0)
1414 : 0 : return r;
1415 : :
1416 [ # # ]: 0 : if (!log_facility_unshifted_is_valid(facility))
1417 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
1418 : :
1419 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1420 : 0 : c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
1421 : 0 : unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
1422 : : }
1423 : :
1424 : 0 : return 1;
1425 : :
1426 [ # # ]: 0 : } else if (streq(name, "LogExtraFields")) {
1427 : 0 : size_t n = 0;
1428 : :
1429 : 0 : r = sd_bus_message_enter_container(message, 'a', "ay");
1430 [ # # ]: 0 : if (r < 0)
1431 : 0 : return r;
1432 : :
1433 : 0 : for (;;) {
1434 [ # # # ]: 0 : _cleanup_free_ void *copy = NULL;
1435 : : struct iovec *t;
1436 : : const char *eq;
1437 : : const void *p;
1438 : : size_t sz;
1439 : :
1440 : : /* Note that we expect a byte array for each field, instead of a string. That's because on the
1441 : : * lower-level journal fields can actually contain binary data and are not restricted to text,
1442 : : * and we should not "lose precision" in our types on the way. That said, I am pretty sure
1443 : : * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
1444 : : * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
1445 : : * limitation, should a good, valid usecase arise. */
1446 : :
1447 : 0 : r = sd_bus_message_read_array(message, 'y', &p, &sz);
1448 [ # # ]: 0 : if (r < 0)
1449 : 0 : return r;
1450 [ # # ]: 0 : if (r == 0)
1451 : 0 : break;
1452 : :
1453 [ # # ]: 0 : if (memchr(p, 0, sz))
1454 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
1455 : :
1456 : 0 : eq = memchr(p, '=', sz);
1457 [ # # ]: 0 : if (!eq)
1458 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
1459 [ # # ]: 0 : if (!journal_field_valid(p, eq - (const char*) p, false))
1460 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
1461 : :
1462 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1463 : 0 : t = reallocarray(c->log_extra_fields, c->n_log_extra_fields+1, sizeof(struct iovec));
1464 [ # # ]: 0 : if (!t)
1465 : 0 : return -ENOMEM;
1466 : 0 : c->log_extra_fields = t;
1467 : : }
1468 : :
1469 : 0 : copy = malloc(sz + 1);
1470 [ # # ]: 0 : if (!copy)
1471 : 0 : return -ENOMEM;
1472 : :
1473 : 0 : memcpy(copy, p, sz);
1474 : 0 : ((uint8_t*) copy)[sz] = 0;
1475 : :
1476 [ # # ]: 0 : if (!utf8_is_valid(copy))
1477 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
1478 : :
1479 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1480 : 0 : c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
1481 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
1482 : :
1483 : 0 : copy = NULL;
1484 : : }
1485 : :
1486 : 0 : n++;
1487 : : }
1488 : :
1489 : 0 : r = sd_bus_message_exit_container(message);
1490 [ # # ]: 0 : if (r < 0)
1491 : 0 : return r;
1492 : :
1493 [ # # # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
1494 : 0 : exec_context_free_log_extra_fields(c);
1495 : 0 : unit_write_setting(u, flags, name, "LogExtraFields=");
1496 : : }
1497 : :
1498 : 0 : return 1;
1499 : : }
1500 : :
1501 : : #if HAVE_SECCOMP
1502 : :
1503 [ # # ]: 0 : if (streq(name, "SystemCallErrorNumber"))
1504 : 0 : return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
1505 : :
1506 [ # # ]: 0 : if (streq(name, "SystemCallFilter")) {
1507 : : int whitelist;
1508 : 0 : _cleanup_strv_free_ char **l = NULL;
1509 : :
1510 : 0 : r = sd_bus_message_enter_container(message, 'r', "bas");
1511 [ # # ]: 0 : if (r < 0)
1512 : 0 : return r;
1513 : :
1514 : 0 : r = sd_bus_message_read(message, "b", &whitelist);
1515 [ # # ]: 0 : if (r < 0)
1516 : 0 : return r;
1517 : :
1518 : 0 : r = sd_bus_message_read_strv(message, &l);
1519 [ # # ]: 0 : if (r < 0)
1520 : 0 : return r;
1521 : :
1522 : 0 : r = sd_bus_message_exit_container(message);
1523 [ # # ]: 0 : if (r < 0)
1524 : 0 : return r;
1525 : :
1526 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1527 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
1528 : 0 : SeccompParseFlags invert_flag = whitelist ? 0 : SECCOMP_PARSE_INVERT;
1529 : : char **s;
1530 : :
1531 [ # # ]: 0 : if (strv_isempty(l)) {
1532 : 0 : c->syscall_whitelist = false;
1533 : 0 : c->syscall_filter = hashmap_free(c->syscall_filter);
1534 : :
1535 : 0 : unit_write_settingf(u, flags, name, "SystemCallFilter=");
1536 : 0 : return 1;
1537 : : }
1538 : :
1539 [ # # ]: 0 : if (!c->syscall_filter) {
1540 : 0 : c->syscall_filter = hashmap_new(NULL);
1541 [ # # ]: 0 : if (!c->syscall_filter)
1542 : 0 : return log_oom();
1543 : :
1544 : 0 : c->syscall_whitelist = whitelist;
1545 : :
1546 [ # # ]: 0 : if (c->syscall_whitelist) {
1547 : 0 : r = seccomp_parse_syscall_filter("@default",
1548 : : -1,
1549 : : c->syscall_filter,
1550 : 0 : SECCOMP_PARSE_WHITELIST | invert_flag,
1551 : 0 : u->id,
1552 : : NULL, 0);
1553 [ # # ]: 0 : if (r < 0)
1554 : 0 : return r;
1555 : : }
1556 : : }
1557 : :
1558 [ # # # # ]: 0 : STRV_FOREACH(s, l) {
1559 [ # # ]: 0 : _cleanup_free_ char *n = NULL;
1560 : : int e;
1561 : :
1562 : 0 : r = parse_syscall_and_errno(*s, &n, &e);
1563 [ # # ]: 0 : if (r < 0)
1564 : 0 : return r;
1565 : :
1566 : 0 : r = seccomp_parse_syscall_filter(n,
1567 : : e,
1568 : : c->syscall_filter,
1569 : 0 : (c->syscall_whitelist ? SECCOMP_PARSE_WHITELIST : 0) | invert_flag,
1570 : 0 : u->id,
1571 : : NULL, 0);
1572 [ # # ]: 0 : if (r < 0)
1573 : 0 : return r;
1574 : : }
1575 : :
1576 : 0 : joined = strv_join(l, " ");
1577 [ # # ]: 0 : if (!joined)
1578 : 0 : return -ENOMEM;
1579 : :
1580 [ # # ]: 0 : unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
1581 : : }
1582 : :
1583 : 0 : return 1;
1584 : :
1585 [ # # ]: 0 : } else if (streq(name, "SystemCallArchitectures")) {
1586 : 0 : _cleanup_strv_free_ char **l = NULL;
1587 : :
1588 : 0 : r = sd_bus_message_read_strv(message, &l);
1589 [ # # ]: 0 : if (r < 0)
1590 : 0 : return r;
1591 : :
1592 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1593 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
1594 : :
1595 [ # # ]: 0 : if (strv_isempty(l))
1596 : 0 : c->syscall_archs = set_free(c->syscall_archs);
1597 : : else {
1598 : : char **s;
1599 : :
1600 : 0 : r = set_ensure_allocated(&c->syscall_archs, NULL);
1601 [ # # ]: 0 : if (r < 0)
1602 : 0 : return r;
1603 : :
1604 [ # # # # ]: 0 : STRV_FOREACH(s, l) {
1605 : : uint32_t a;
1606 : :
1607 : 0 : r = seccomp_arch_from_string(*s, &a);
1608 [ # # ]: 0 : if (r < 0)
1609 : 0 : return r;
1610 : :
1611 : 0 : r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
1612 [ # # ]: 0 : if (r < 0)
1613 : 0 : return r;
1614 : : }
1615 : :
1616 : : }
1617 : :
1618 : 0 : joined = strv_join(l, " ");
1619 [ # # ]: 0 : if (!joined)
1620 : 0 : return -ENOMEM;
1621 : :
1622 : 0 : unit_write_settingf(u, flags, name, "%s=%s", name, joined);
1623 : : }
1624 : :
1625 : 0 : return 1;
1626 : :
1627 [ # # ]: 0 : } else if (streq(name, "RestrictAddressFamilies")) {
1628 : : int whitelist;
1629 : 0 : _cleanup_strv_free_ char **l = NULL;
1630 : :
1631 : 0 : r = sd_bus_message_enter_container(message, 'r', "bas");
1632 [ # # ]: 0 : if (r < 0)
1633 : 0 : return r;
1634 : :
1635 : 0 : r = sd_bus_message_read(message, "b", &whitelist);
1636 [ # # ]: 0 : if (r < 0)
1637 : 0 : return r;
1638 : :
1639 : 0 : r = sd_bus_message_read_strv(message, &l);
1640 [ # # ]: 0 : if (r < 0)
1641 : 0 : return r;
1642 : :
1643 : 0 : r = sd_bus_message_exit_container(message);
1644 [ # # ]: 0 : if (r < 0)
1645 : 0 : return r;
1646 : :
1647 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1648 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
1649 : : char **s;
1650 : :
1651 [ # # ]: 0 : if (strv_isempty(l)) {
1652 : 0 : c->address_families_whitelist = false;
1653 : 0 : c->address_families = set_free(c->address_families);
1654 : :
1655 : 0 : unit_write_settingf(u, flags, name, "RestrictAddressFamilies=");
1656 : 0 : return 1;
1657 : : }
1658 : :
1659 [ # # ]: 0 : if (!c->address_families) {
1660 : 0 : c->address_families = set_new(NULL);
1661 [ # # ]: 0 : if (!c->address_families)
1662 : 0 : return log_oom();
1663 : :
1664 : 0 : c->address_families_whitelist = whitelist;
1665 : : }
1666 : :
1667 [ # # # # ]: 0 : STRV_FOREACH(s, l) {
1668 : : int af;
1669 : :
1670 : 0 : af = af_from_name(*s);
1671 [ # # ]: 0 : if (af < 0)
1672 : 0 : return af;
1673 : :
1674 [ # # ]: 0 : if (whitelist == c->address_families_whitelist) {
1675 : 0 : r = set_put(c->address_families, INT_TO_PTR(af));
1676 [ # # ]: 0 : if (r < 0)
1677 : 0 : return r;
1678 : : } else
1679 : 0 : (void) set_remove(c->address_families, INT_TO_PTR(af));
1680 : : }
1681 : :
1682 : 0 : joined = strv_join(l, " ");
1683 [ # # ]: 0 : if (!joined)
1684 : 0 : return -ENOMEM;
1685 : :
1686 [ # # ]: 0 : unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
1687 : : }
1688 : :
1689 : 0 : return 1;
1690 : : }
1691 : : #endif
1692 [ # # ]: 0 : if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
1693 : : const void *a;
1694 : : size_t n;
1695 : 0 : bool affinity = streq(name, "CPUAffinity");
1696 : 0 : _cleanup_(cpu_set_reset) CPUSet set = {};
1697 : :
1698 : 0 : r = sd_bus_message_read_array(message, 'y', &a, &n);
1699 [ # # ]: 0 : if (r < 0)
1700 : 0 : return r;
1701 : :
1702 : 0 : r = cpu_set_from_dbus(a, n, &set);
1703 [ # # ]: 0 : if (r < 0)
1704 : 0 : return r;
1705 : :
1706 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1707 [ # # ]: 0 : if (n == 0) {
1708 [ # # ]: 0 : cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
1709 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
1710 : : } else {
1711 [ # # ]: 0 : _cleanup_free_ char *str = NULL;
1712 : :
1713 : 0 : str = cpu_set_to_string(&set);
1714 [ # # ]: 0 : if (!str)
1715 : 0 : return -ENOMEM;
1716 : :
1717 : : /* We forego any optimizations here, and always create the structure using
1718 : : * cpu_set_add_all(), because we don't want to care if the existing size we
1719 : : * got over dbus is appropriate. */
1720 [ # # ]: 0 : r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
1721 [ # # ]: 0 : if (r < 0)
1722 : 0 : return r;
1723 : :
1724 : 0 : unit_write_settingf(u, flags, name, "%s=%s", name, str);
1725 : : }
1726 : : }
1727 : :
1728 : 0 : return 1;
1729 : :
1730 [ # # ]: 0 : } else if (streq(name, "NUMAPolicy")) {
1731 : : int32_t type;
1732 : :
1733 : 0 : r = sd_bus_message_read(message, "i", &type);
1734 [ # # ]: 0 : if (r < 0)
1735 : 0 : return r;
1736 : :
1737 [ # # ]: 0 : if (!mpol_is_valid(type))
1738 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
1739 : :
1740 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags))
1741 : 0 : c->numa_policy.type = type;
1742 : :
1743 : 0 : return 1;
1744 [ # # ]: 0 : } else if (streq(name, "Nice")) {
1745 : : int32_t q;
1746 : :
1747 : 0 : r = sd_bus_message_read(message, "i", &q);
1748 [ # # ]: 0 : if (r < 0)
1749 : 0 : return r;
1750 : :
1751 [ # # ]: 0 : if (!nice_is_valid(q))
1752 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
1753 : :
1754 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1755 : 0 : c->nice = q;
1756 : 0 : c->nice_set = true;
1757 : :
1758 : 0 : unit_write_settingf(u, flags, name, "Nice=%i", q);
1759 : : }
1760 : :
1761 : 0 : return 1;
1762 : :
1763 [ # # ]: 0 : } else if (streq(name, "CPUSchedulingPolicy")) {
1764 : : int32_t q;
1765 : :
1766 : 0 : r = sd_bus_message_read(message, "i", &q);
1767 [ # # ]: 0 : if (r < 0)
1768 : 0 : return r;
1769 : :
1770 [ # # ]: 0 : if (!sched_policy_is_valid(q))
1771 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
1772 : :
1773 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1774 [ # # ]: 0 : _cleanup_free_ char *s = NULL;
1775 : :
1776 : 0 : r = sched_policy_to_string_alloc(q, &s);
1777 [ # # ]: 0 : if (r < 0)
1778 : 0 : return r;
1779 : :
1780 : 0 : c->cpu_sched_policy = q;
1781 [ # # ]: 0 : c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
1782 : 0 : c->cpu_sched_set = true;
1783 : :
1784 : 0 : unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
1785 : : }
1786 : :
1787 : 0 : return 1;
1788 : :
1789 [ # # ]: 0 : } else if (streq(name, "CPUSchedulingPriority")) {
1790 : : int32_t p, min, max;
1791 : :
1792 : 0 : r = sd_bus_message_read(message, "i", &p);
1793 [ # # ]: 0 : if (r < 0)
1794 : 0 : return r;
1795 : :
1796 : 0 : min = sched_get_priority_min(c->cpu_sched_policy);
1797 : 0 : max = sched_get_priority_max(c->cpu_sched_policy);
1798 [ # # # # ]: 0 : if (p < min || p > max)
1799 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority: %i", p);
1800 : :
1801 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1802 : 0 : c->cpu_sched_priority = p;
1803 : 0 : c->cpu_sched_set = true;
1804 : :
1805 : 0 : unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
1806 : : }
1807 : :
1808 : 0 : return 1;
1809 : :
1810 [ # # ]: 0 : } else if (streq(name, "IOSchedulingClass")) {
1811 : : int32_t q;
1812 : :
1813 : 0 : r = sd_bus_message_read(message, "i", &q);
1814 [ # # ]: 0 : if (r < 0)
1815 : 0 : return r;
1816 : :
1817 [ # # ]: 0 : if (!ioprio_class_is_valid(q))
1818 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
1819 : :
1820 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1821 [ # # ]: 0 : _cleanup_free_ char *s = NULL;
1822 : :
1823 : 0 : r = ioprio_class_to_string_alloc(q, &s);
1824 [ # # ]: 0 : if (r < 0)
1825 : 0 : return r;
1826 : :
1827 : 0 : c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
1828 : 0 : c->ioprio_set = true;
1829 : :
1830 : 0 : unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
1831 : : }
1832 : :
1833 : 0 : return 1;
1834 : :
1835 [ # # ]: 0 : } else if (streq(name, "IOSchedulingPriority")) {
1836 : : int32_t p;
1837 : :
1838 : 0 : r = sd_bus_message_read(message, "i", &p);
1839 [ # # ]: 0 : if (r < 0)
1840 : 0 : return r;
1841 : :
1842 [ # # ]: 0 : if (!ioprio_priority_is_valid(p))
1843 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
1844 : :
1845 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1846 : 0 : c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
1847 : 0 : c->ioprio_set = true;
1848 : :
1849 : 0 : unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
1850 : : }
1851 : :
1852 : 0 : return 1;
1853 : :
1854 [ # # ]: 0 : } else if (streq(name, "WorkingDirectory")) {
1855 : : const char *s;
1856 : : bool missing_ok;
1857 : :
1858 : 0 : r = sd_bus_message_read(message, "s", &s);
1859 [ # # ]: 0 : if (r < 0)
1860 : 0 : return r;
1861 : :
1862 [ # # ]: 0 : if (s[0] == '-') {
1863 : 0 : missing_ok = true;
1864 : 0 : s++;
1865 : : } else
1866 : 0 : missing_ok = false;
1867 : :
1868 [ # # # # : 0 : if (!isempty(s) && !streq(s, "~") && !path_is_absolute(s))
# # ]
1869 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
1870 : :
1871 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1872 [ # # ]: 0 : if (streq(s, "~")) {
1873 : 0 : c->working_directory = mfree(c->working_directory);
1874 : 0 : c->working_directory_home = true;
1875 : : } else {
1876 : 0 : r = free_and_strdup(&c->working_directory, empty_to_null(s));
1877 [ # # ]: 0 : if (r < 0)
1878 : 0 : return r;
1879 : :
1880 : 0 : c->working_directory_home = false;
1881 : : }
1882 : :
1883 : 0 : c->working_directory_missing_ok = missing_ok;
1884 [ # # ]: 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
1885 : : }
1886 : :
1887 : 0 : return 1;
1888 : :
1889 [ # # ]: 0 : } else if (STR_IN_SET(name,
1890 : : "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1891 : : const char *s;
1892 : :
1893 : 0 : r = sd_bus_message_read(message, "s", &s);
1894 [ # # ]: 0 : if (r < 0)
1895 : 0 : return r;
1896 : :
1897 [ # # # # ]: 0 : if (!isempty(s) && !fdname_is_valid(s))
1898 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
1899 : :
1900 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1901 : :
1902 [ # # ]: 0 : if (streq(name, "StandardInputFileDescriptorName")) {
1903 : 0 : r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s));
1904 [ # # ]: 0 : if (r < 0)
1905 : 0 : return r;
1906 : :
1907 : 0 : c->std_input = EXEC_INPUT_NAMED_FD;
1908 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO));
1909 : :
1910 [ # # ]: 0 : } else if (streq(name, "StandardOutputFileDescriptorName")) {
1911 : 0 : r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s));
1912 [ # # ]: 0 : if (r < 0)
1913 : 0 : return r;
1914 : :
1915 : 0 : c->std_output = EXEC_OUTPUT_NAMED_FD;
1916 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO));
1917 : :
1918 : : } else {
1919 [ # # ]: 0 : assert(streq(name, "StandardErrorFileDescriptorName"));
1920 : :
1921 : 0 : r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s));
1922 [ # # ]: 0 : if (r < 0)
1923 : 0 : return r;
1924 : :
1925 : 0 : c->std_error = EXEC_OUTPUT_NAMED_FD;
1926 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
1927 : : }
1928 : : }
1929 : :
1930 : 0 : return 1;
1931 : :
1932 [ # # ]: 0 : } else if (STR_IN_SET(name,
1933 : : "StandardInputFile",
1934 : : "StandardOutputFile", "StandardOutputFileToAppend",
1935 : : "StandardErrorFile", "StandardErrorFileToAppend")) {
1936 : : const char *s;
1937 : :
1938 : 0 : r = sd_bus_message_read(message, "s", &s);
1939 [ # # ]: 0 : if (r < 0)
1940 : 0 : return r;
1941 : :
1942 [ # # ]: 0 : if (!isempty(s)) {
1943 [ # # ]: 0 : if (!path_is_absolute(s))
1944 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
1945 [ # # ]: 0 : if (!path_is_normalized(s))
1946 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
1947 : : }
1948 : :
1949 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1950 : :
1951 [ # # ]: 0 : if (streq(name, "StandardInputFile")) {
1952 : 0 : r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s));
1953 [ # # ]: 0 : if (r < 0)
1954 : 0 : return r;
1955 : :
1956 : 0 : c->std_input = EXEC_INPUT_FILE;
1957 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
1958 : :
1959 [ # # ]: 0 : } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend")) {
1960 : 0 : r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
1961 [ # # ]: 0 : if (r < 0)
1962 : 0 : return r;
1963 : :
1964 [ # # ]: 0 : if (streq(name, "StandardOutputFile")) {
1965 : 0 : c->std_output = EXEC_OUTPUT_FILE;
1966 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
1967 : : } else {
1968 [ # # ]: 0 : assert(streq(name, "StandardOutputFileToAppend"));
1969 : 0 : c->std_output = EXEC_OUTPUT_FILE_APPEND;
1970 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s);
1971 : : }
1972 : : } else {
1973 [ # # ]: 0 : assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend"));
1974 : :
1975 : 0 : r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
1976 [ # # ]: 0 : if (r < 0)
1977 : 0 : return r;
1978 : :
1979 [ # # ]: 0 : if (streq(name, "StandardErrorFile")) {
1980 : 0 : c->std_error = EXEC_OUTPUT_FILE;
1981 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
1982 : : } else {
1983 [ # # ]: 0 : assert(streq(name, "StandardErrorFileToAppend"));
1984 : 0 : c->std_error = EXEC_OUTPUT_FILE_APPEND;
1985 : 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
1986 : : }
1987 : : }
1988 : : }
1989 : :
1990 : 0 : return 1;
1991 : :
1992 [ # # ]: 0 : } else if (streq(name, "StandardInputData")) {
1993 : : const void *p;
1994 : : size_t sz;
1995 : :
1996 : 0 : r = sd_bus_message_read_array(message, 'y', &p, &sz);
1997 [ # # ]: 0 : if (r < 0)
1998 : 0 : return r;
1999 : :
2000 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2001 [ # # ]: 0 : _cleanup_free_ char *encoded = NULL;
2002 : :
2003 [ # # ]: 0 : if (sz == 0) {
2004 : 0 : c->stdin_data = mfree(c->stdin_data);
2005 : 0 : c->stdin_data_size = 0;
2006 : :
2007 : 0 : unit_write_settingf(u, flags, name, "StandardInputData=");
2008 : : } else {
2009 : : void *q;
2010 : : ssize_t n;
2011 : :
2012 [ # # ]: 0 : if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
2013 [ # # ]: 0 : c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
2014 : 0 : return -E2BIG;
2015 : :
2016 : 0 : n = base64mem(p, sz, &encoded);
2017 [ # # ]: 0 : if (n < 0)
2018 : 0 : return (int) n;
2019 : :
2020 : 0 : q = realloc(c->stdin_data, c->stdin_data_size + sz);
2021 [ # # ]: 0 : if (!q)
2022 : 0 : return -ENOMEM;
2023 : :
2024 : 0 : memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
2025 : :
2026 : 0 : c->stdin_data = q;
2027 : 0 : c->stdin_data_size += sz;
2028 : :
2029 : 0 : unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
2030 : : }
2031 : : }
2032 : :
2033 : 0 : return 1;
2034 : :
2035 [ # # ]: 0 : } else if (streq(name, "Environment")) {
2036 : :
2037 : 0 : _cleanup_strv_free_ char **l = NULL;
2038 : :
2039 : 0 : r = sd_bus_message_read_strv(message, &l);
2040 [ # # ]: 0 : if (r < 0)
2041 : 0 : return r;
2042 : :
2043 [ # # ]: 0 : if (!strv_env_is_valid(l))
2044 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
2045 : :
2046 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2047 [ # # ]: 0 : if (strv_isempty(l)) {
2048 : 0 : c->environment = strv_free(c->environment);
2049 : 0 : unit_write_setting(u, flags, name, "Environment=");
2050 : : } else {
2051 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
2052 : : char **e;
2053 : :
2054 : 0 : joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
2055 [ # # ]: 0 : if (!joined)
2056 : 0 : return -ENOMEM;
2057 : :
2058 : 0 : e = strv_env_merge(2, c->environment, l);
2059 [ # # ]: 0 : if (!e)
2060 : 0 : return -ENOMEM;
2061 : :
2062 : 0 : strv_free_and_replace(c->environment, e);
2063 : 0 : unit_write_settingf(u, flags, name, "Environment=%s", joined);
2064 : : }
2065 : : }
2066 : :
2067 : 0 : return 1;
2068 : :
2069 [ # # ]: 0 : } else if (streq(name, "UnsetEnvironment")) {
2070 : :
2071 : 0 : _cleanup_strv_free_ char **l = NULL;
2072 : :
2073 : 0 : r = sd_bus_message_read_strv(message, &l);
2074 [ # # ]: 0 : if (r < 0)
2075 : 0 : return r;
2076 : :
2077 [ # # ]: 0 : if (!strv_env_name_or_assignment_is_valid(l))
2078 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
2079 : :
2080 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2081 [ # # ]: 0 : if (strv_isempty(l)) {
2082 : 0 : c->unset_environment = strv_free(c->unset_environment);
2083 : 0 : unit_write_setting(u, flags, name, "UnsetEnvironment=");
2084 : : } else {
2085 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
2086 : : char **e;
2087 : :
2088 : 0 : joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
2089 [ # # ]: 0 : if (!joined)
2090 : 0 : return -ENOMEM;
2091 : :
2092 : 0 : e = strv_env_merge(2, c->unset_environment, l);
2093 [ # # ]: 0 : if (!e)
2094 : 0 : return -ENOMEM;
2095 : :
2096 : 0 : strv_free_and_replace(c->unset_environment, e);
2097 : 0 : unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
2098 : : }
2099 : : }
2100 : :
2101 : 0 : return 1;
2102 : :
2103 [ # # ]: 0 : } else if (streq(name, "OOMScoreAdjust")) {
2104 : : int oa;
2105 : :
2106 : 0 : r = sd_bus_message_read(message, "i", &oa);
2107 [ # # ]: 0 : if (r < 0)
2108 : 0 : return r;
2109 : :
2110 [ # # ]: 0 : if (!oom_score_adjust_is_valid(oa))
2111 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
2112 : :
2113 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2114 : 0 : c->oom_score_adjust = oa;
2115 : 0 : c->oom_score_adjust_set = true;
2116 : 0 : unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
2117 : : }
2118 : :
2119 : 0 : return 1;
2120 : :
2121 [ # # ]: 0 : } else if (streq(name, "EnvironmentFiles")) {
2122 : :
2123 : 0 : _cleanup_free_ char *joined = NULL;
2124 : 0 : _cleanup_fclose_ FILE *f = NULL;
2125 : 0 : _cleanup_strv_free_ char **l = NULL;
2126 : 0 : size_t size = 0;
2127 : : char **i;
2128 : :
2129 : 0 : r = sd_bus_message_enter_container(message, 'a', "(sb)");
2130 [ # # ]: 0 : if (r < 0)
2131 : 0 : return r;
2132 : :
2133 : 0 : f = open_memstream_unlocked(&joined, &size);
2134 [ # # ]: 0 : if (!f)
2135 : 0 : return -ENOMEM;
2136 : :
2137 : 0 : fputs("EnvironmentFile=\n", f);
2138 : :
2139 [ # # # # ]: 0 : STRV_FOREACH(i, c->environment_files) {
2140 [ # # ]: 0 : _cleanup_free_ char *q = NULL;
2141 : :
2142 : 0 : q = specifier_escape(*i);
2143 [ # # ]: 0 : if (!q)
2144 : 0 : return -ENOMEM;
2145 : :
2146 : 0 : fprintf(f, "EnvironmentFile=%s\n", q);
2147 : : }
2148 : :
2149 [ # # ]: 0 : while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
2150 : : const char *path;
2151 : : int b;
2152 : :
2153 : 0 : r = sd_bus_message_read(message, "sb", &path, &b);
2154 [ # # ]: 0 : if (r < 0)
2155 : 0 : return r;
2156 : :
2157 : 0 : r = sd_bus_message_exit_container(message);
2158 [ # # ]: 0 : if (r < 0)
2159 : 0 : return r;
2160 : :
2161 [ # # ]: 0 : if (!path_is_absolute(path))
2162 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
2163 : :
2164 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2165 [ # # # # ]: 0 : _cleanup_free_ char *q = NULL, *buf = NULL;
2166 : :
2167 [ # # ]: 0 : buf = strjoin(b ? "-" : "", path);
2168 [ # # ]: 0 : if (!buf)
2169 : 0 : return -ENOMEM;
2170 : :
2171 : 0 : q = specifier_escape(buf);
2172 [ # # ]: 0 : if (!q)
2173 : 0 : return -ENOMEM;
2174 : :
2175 : 0 : fprintf(f, "EnvironmentFile=%s\n", q);
2176 : :
2177 : 0 : r = strv_consume(&l, TAKE_PTR(buf));
2178 [ # # ]: 0 : if (r < 0)
2179 : 0 : return r;
2180 : : }
2181 : : }
2182 [ # # ]: 0 : if (r < 0)
2183 : 0 : return r;
2184 : :
2185 : 0 : r = sd_bus_message_exit_container(message);
2186 [ # # ]: 0 : if (r < 0)
2187 : 0 : return r;
2188 : :
2189 : 0 : r = fflush_and_check(f);
2190 [ # # ]: 0 : if (r < 0)
2191 : 0 : return r;
2192 : :
2193 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2194 [ # # ]: 0 : if (strv_isempty(l)) {
2195 : 0 : c->environment_files = strv_free(c->environment_files);
2196 : 0 : unit_write_setting(u, flags, name, "EnvironmentFile=");
2197 : : } else {
2198 : 0 : r = strv_extend_strv(&c->environment_files, l, true);
2199 [ # # ]: 0 : if (r < 0)
2200 : 0 : return r;
2201 : :
2202 : 0 : unit_write_setting(u, flags, name, joined);
2203 : : }
2204 : : }
2205 : :
2206 : 0 : return 1;
2207 : :
2208 [ # # ]: 0 : } else if (streq(name, "PassEnvironment")) {
2209 : :
2210 : 0 : _cleanup_strv_free_ char **l = NULL;
2211 : :
2212 : 0 : r = sd_bus_message_read_strv(message, &l);
2213 [ # # ]: 0 : if (r < 0)
2214 : 0 : return r;
2215 : :
2216 [ # # ]: 0 : if (!strv_env_name_is_valid(l))
2217 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
2218 : :
2219 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2220 [ # # ]: 0 : if (strv_isempty(l)) {
2221 : 0 : c->pass_environment = strv_free(c->pass_environment);
2222 : 0 : unit_write_setting(u, flags, name, "PassEnvironment=");
2223 : : } else {
2224 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
2225 : :
2226 : 0 : r = strv_extend_strv(&c->pass_environment, l, true);
2227 [ # # ]: 0 : if (r < 0)
2228 : 0 : return r;
2229 : :
2230 : : /* We write just the new settings out to file, with unresolved specifiers. */
2231 : 0 : joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
2232 [ # # ]: 0 : if (!joined)
2233 : 0 : return -ENOMEM;
2234 : :
2235 : 0 : unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
2236 : : }
2237 : : }
2238 : :
2239 : 0 : return 1;
2240 : :
2241 [ # # ]: 0 : } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
2242 : : "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
2243 : 0 : _cleanup_strv_free_ char **l = NULL;
2244 : : char ***dirs;
2245 : : char **p;
2246 : :
2247 : 0 : r = sd_bus_message_read_strv(message, &l);
2248 [ # # ]: 0 : if (r < 0)
2249 : 0 : return r;
2250 : :
2251 [ # # # # ]: 0 : STRV_FOREACH(p, l) {
2252 : 0 : char *i = *p;
2253 : : size_t offset;
2254 : :
2255 : 0 : offset = i[0] == '-';
2256 : 0 : offset += i[offset] == '+';
2257 [ # # ]: 0 : if (!path_is_absolute(i + offset))
2258 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
2259 : :
2260 : 0 : path_simplify(i + offset, false);
2261 : : }
2262 : :
2263 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2264 [ # # ]: 0 : if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
2265 : 0 : dirs = &c->read_write_paths;
2266 [ # # ]: 0 : else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
2267 : 0 : dirs = &c->read_only_paths;
2268 : : else /* "InaccessiblePaths" */
2269 : 0 : dirs = &c->inaccessible_paths;
2270 : :
2271 [ # # ]: 0 : if (strv_isempty(l)) {
2272 : 0 : *dirs = strv_free(*dirs);
2273 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
2274 : : } else {
2275 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
2276 : :
2277 : 0 : joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
2278 [ # # ]: 0 : if (!joined)
2279 : 0 : return -ENOMEM;
2280 : :
2281 : 0 : r = strv_extend_strv(dirs, l, true);
2282 [ # # ]: 0 : if (r < 0)
2283 : 0 : return -ENOMEM;
2284 : :
2285 : 0 : unit_write_settingf(u, flags, name, "%s=%s", name, joined);
2286 : : }
2287 : : }
2288 : :
2289 : 0 : return 1;
2290 : :
2291 [ # # ]: 0 : } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
2292 : 0 : _cleanup_strv_free_ char **l = NULL;
2293 : : char **p;
2294 : :
2295 : 0 : r = sd_bus_message_read_strv(message, &l);
2296 [ # # ]: 0 : if (r < 0)
2297 : 0 : return r;
2298 : :
2299 [ # # # # ]: 0 : STRV_FOREACH(p, l) {
2300 [ # # ]: 0 : if (!path_is_normalized(*p))
2301 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
2302 : :
2303 [ # # ]: 0 : if (path_is_absolute(*p))
2304 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is absolute: %s", name, *p);
2305 : :
2306 [ # # ]: 0 : if (path_startswith(*p, "private"))
2307 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
2308 : : }
2309 : :
2310 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2311 : : ExecDirectoryType i;
2312 : : ExecDirectory *d;
2313 : :
2314 [ # # ]: 0 : assert_se((i = exec_directory_type_from_string(name)) >= 0);
2315 : 0 : d = c->directories + i;
2316 : :
2317 [ # # ]: 0 : if (strv_isempty(l)) {
2318 : 0 : d->paths = strv_free(d->paths);
2319 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
2320 : : } else {
2321 [ # # ]: 0 : _cleanup_free_ char *joined = NULL;
2322 : :
2323 : 0 : r = strv_extend_strv(&d->paths, l, true);
2324 [ # # ]: 0 : if (r < 0)
2325 : 0 : return r;
2326 : :
2327 : 0 : joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
2328 [ # # ]: 0 : if (!joined)
2329 : 0 : return -ENOMEM;
2330 : :
2331 : 0 : unit_write_settingf(u, flags, name, "%s=%s", name, joined);
2332 : : }
2333 : : }
2334 : :
2335 : 0 : return 1;
2336 : :
2337 [ # # ]: 0 : } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
2338 : : int ignore;
2339 : : const char *s;
2340 : :
2341 : 0 : r = sd_bus_message_read(message, "(bs)", &ignore, &s);
2342 [ # # ]: 0 : if (r < 0)
2343 : 0 : return r;
2344 : :
2345 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2346 : : char **p;
2347 : : bool *b;
2348 : :
2349 [ # # ]: 0 : if (streq(name, "AppArmorProfile")) {
2350 : 0 : p = &c->apparmor_profile;
2351 : 0 : b = &c->apparmor_profile_ignore;
2352 : : } else { /* "SmackProcessLabel" */
2353 : 0 : p = &c->smack_process_label;
2354 : 0 : b = &c->smack_process_label_ignore;
2355 : : }
2356 : :
2357 [ # # ]: 0 : if (isempty(s)) {
2358 : 0 : *p = mfree(*p);
2359 : 0 : *b = false;
2360 : : } else {
2361 [ # # ]: 0 : if (free_and_strdup(p, s) < 0)
2362 : 0 : return -ENOMEM;
2363 : 0 : *b = ignore;
2364 : : }
2365 : :
2366 [ # # ]: 0 : unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
2367 : : }
2368 : :
2369 : 0 : return 1;
2370 : :
2371 [ # # ]: 0 : } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
2372 : : const char *source, *destination;
2373 : : int ignore_enoent;
2374 : : uint64_t mount_flags;
2375 : 0 : bool empty = true;
2376 : :
2377 : 0 : r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
2378 [ # # ]: 0 : if (r < 0)
2379 : 0 : return r;
2380 : :
2381 [ # # ]: 0 : while ((r = sd_bus_message_read(message, "(ssbt)", &source, &destination, &ignore_enoent, &mount_flags)) > 0) {
2382 : :
2383 [ # # ]: 0 : if (!path_is_absolute(source))
2384 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
2385 [ # # ]: 0 : if (!path_is_absolute(destination))
2386 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
2387 [ # # # # ]: 0 : if (!IN_SET(mount_flags, 0, MS_REC))
2388 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
2389 : :
2390 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2391 : 0 : r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
2392 : 0 : &(BindMount) {
2393 : 0 : .source = strdup(source),
2394 : 0 : .destination = strdup(destination),
2395 : 0 : .read_only = !!strstr(name, "ReadOnly"),
2396 : 0 : .recursive = !!(mount_flags & MS_REC),
2397 : : .ignore_enoent = ignore_enoent,
2398 : : });
2399 [ # # ]: 0 : if (r < 0)
2400 : 0 : return r;
2401 : :
2402 : 0 : unit_write_settingf(
2403 : 0 : u, flags|UNIT_ESCAPE_SPECIFIERS, name,
2404 : : "%s=%s%s:%s:%s",
2405 : : name,
2406 [ # # ]: 0 : ignore_enoent ? "-" : "",
2407 : : source,
2408 : : destination,
2409 [ # # ]: 0 : (mount_flags & MS_REC) ? "rbind" : "norbind");
2410 : : }
2411 : :
2412 : 0 : empty = false;
2413 : : }
2414 [ # # ]: 0 : if (r < 0)
2415 : 0 : return r;
2416 : :
2417 : 0 : r = sd_bus_message_exit_container(message);
2418 [ # # ]: 0 : if (r < 0)
2419 : 0 : return r;
2420 : :
2421 [ # # ]: 0 : if (empty) {
2422 : 0 : bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
2423 : 0 : c->bind_mounts = NULL;
2424 : 0 : c->n_bind_mounts = 0;
2425 : :
2426 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
2427 : : }
2428 : :
2429 : 0 : return 1;
2430 : :
2431 [ # # ]: 0 : } else if (streq(name, "TemporaryFileSystem")) {
2432 : : const char *path, *options;
2433 : 0 : bool empty = true;
2434 : :
2435 : 0 : r = sd_bus_message_enter_container(message, 'a', "(ss)");
2436 [ # # ]: 0 : if (r < 0)
2437 : 0 : return r;
2438 : :
2439 [ # # ]: 0 : while ((r = sd_bus_message_read(message, "(ss)", &path, &options)) > 0) {
2440 : :
2441 [ # # ]: 0 : if (!path_is_absolute(path))
2442 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Mount point %s is not absolute.", path);
2443 : :
2444 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2445 : 0 : r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
2446 [ # # ]: 0 : if (r < 0)
2447 : 0 : return r;
2448 : :
2449 : 0 : unit_write_settingf(
2450 : 0 : u, flags|UNIT_ESCAPE_SPECIFIERS, name,
2451 : : "%s=%s:%s",
2452 : : name,
2453 : : path,
2454 : : options);
2455 : : }
2456 : :
2457 : 0 : empty = false;
2458 : : }
2459 [ # # ]: 0 : if (r < 0)
2460 : 0 : return r;
2461 : :
2462 : 0 : r = sd_bus_message_exit_container(message);
2463 [ # # ]: 0 : if (r < 0)
2464 : 0 : return r;
2465 : :
2466 [ # # ]: 0 : if (empty) {
2467 : 0 : temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
2468 : 0 : c->temporary_filesystems = NULL;
2469 : 0 : c->n_temporary_filesystems = 0;
2470 : :
2471 : 0 : unit_write_settingf(u, flags, name, "%s=", name);
2472 : : }
2473 : :
2474 : 0 : return 1;
2475 : :
2476 [ # # ]: 0 : } else if ((suffix = startswith(name, "Limit"))) {
2477 : 0 : const char *soft = NULL;
2478 : : int ri;
2479 : :
2480 : 0 : ri = rlimit_from_string(suffix);
2481 [ # # ]: 0 : if (ri < 0) {
2482 : 0 : soft = endswith(suffix, "Soft");
2483 [ # # ]: 0 : if (soft) {
2484 : : const char *n;
2485 : :
2486 : 0 : n = strndupa(suffix, soft - suffix);
2487 : 0 : ri = rlimit_from_string(n);
2488 [ # # ]: 0 : if (ri >= 0)
2489 [ # # # # : 0 : name = strjoina("Limit", n);
# # # # #
# # # ]
2490 : : }
2491 : : }
2492 : :
2493 [ # # ]: 0 : if (ri >= 0) {
2494 : : uint64_t rl;
2495 : : rlim_t x;
2496 : :
2497 : 0 : r = sd_bus_message_read(message, "t", &rl);
2498 [ # # ]: 0 : if (r < 0)
2499 : 0 : return r;
2500 : :
2501 [ # # ]: 0 : if (rl == (uint64_t) -1)
2502 : 0 : x = RLIM_INFINITY;
2503 : : else {
2504 : 0 : x = (rlim_t) rl;
2505 : :
2506 [ # # ]: 0 : if ((uint64_t) x != rl)
2507 : 0 : return -ERANGE;
2508 : : }
2509 : :
2510 [ # # ]: 0 : if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2511 [ # # ]: 0 : _cleanup_free_ char *f = NULL;
2512 : : struct rlimit nl;
2513 : :
2514 [ # # ]: 0 : if (c->rlimit[ri]) {
2515 : 0 : nl = *c->rlimit[ri];
2516 : :
2517 [ # # ]: 0 : if (soft)
2518 : 0 : nl.rlim_cur = x;
2519 : : else
2520 : 0 : nl.rlim_max = x;
2521 : : } else
2522 : : /* When the resource limit is not initialized yet, then assign the value to both fields */
2523 : 0 : nl = (struct rlimit) {
2524 : : .rlim_cur = x,
2525 : : .rlim_max = x,
2526 : : };
2527 : :
2528 : 0 : r = rlimit_format(&nl, &f);
2529 [ # # ]: 0 : if (r < 0)
2530 : 0 : return r;
2531 : :
2532 [ # # ]: 0 : if (c->rlimit[ri])
2533 : 0 : *c->rlimit[ri] = nl;
2534 : : else {
2535 : 0 : c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
2536 [ # # ]: 0 : if (!c->rlimit[ri])
2537 : 0 : return -ENOMEM;
2538 : : }
2539 : :
2540 : 0 : unit_write_settingf(u, flags, name, "%s=%s", name, f);
2541 : : }
2542 : :
2543 : 0 : return 1;
2544 : : }
2545 : :
2546 : : }
2547 : :
2548 : 0 : return 0;
2549 : : }
|