• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.26
/src/core/dbus-execute.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <sys/mount.h>
4
#include <sys/prctl.h>
5
#include "af-list.h"
6
#include "alloc-util.h"
7
#include "bus-get-properties.h"
8
#include "bus-unit-util.h"
9
#include "bus-util.h"
10
#include "cap-list.h"
11
#include "capability-util.h"
12
#include "cpu-set-util.h"
13
#include "creds-util.h"
14
#include "dbus-execute.h"
15
#include "dbus-util.h"
16
#include "env-util.h"
17
#include "errno-list.h"
18
#include "escape.h"
19
#include "exec-credential.h"
20
#include "execute.h"
21
#include "fd-util.h"
22
#include "fileio.h"
23
#include "hexdecoct.h"
24
#include "hostname-util.h"
25
#include "image-policy.h"
26
#include "ioprio-util.h"
27
#include "iovec-util.h"
28
#include "journal-file.h"
29
#include "load-fragment.h"
30
#include "memstream-util.h"
31
#include "mountpoint-util.h"
32
#include "namespace.h"
33
#include "parse-util.h"
34
#include "path-util.h"
35
#include "pcre2-util.h"
36
#include "process-util.h"
37
#include "rlimit-util.h"
38
#include "seccomp-util.h"
39
#include "securebits-util.h"
40
#include "specifier.h"
41
#include "stat-util.h"
42
#include "strv.h"
43
#include "syslog-util.h"
44
#include "unit-printf.h"
45
#include "user-util.h"
46
#include "utf8.h"
47

48
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
2,554✔
49
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
1,260✔
50
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
1,260✔
51
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
2,340✔
52
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
1,260✔
53
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_proc, protect_proc, ProtectProc);
1,260✔
54
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_proc_subset, proc_subset, ProcSubset);
1,260✔
55
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_home, protect_home, ProtectHome);
1,260✔
56
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
1,260✔
57
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
1,260✔
58
static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
×
59
static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec_context_get_effective_mount_apivfs);
1,260✔
60
static BUS_DEFINE_PROPERTY_GET(property_get_bind_log_sockets, "b", ExecContext, exec_context_get_effective_bind_log_sockets);
1,260✔
61
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_class);
1,260✔
62
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_data);
1,260✔
63
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
×
64
static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_tmp_ex, "s", PrivateTmp, private_tmp_to_string);
1,260✔
65
static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_users_ex, "s", PrivateUsers, private_users_to_string);
1,260✔
66
static BUS_DEFINE_PROPERTY_GET_REF(property_get_protect_control_groups_ex, "s", ProtectControlGroups, protect_control_groups_to_string);
1,260✔
67
static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_pids, "s", PrivatePIDs, private_pids_to_string);
1,260✔
68
static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
1,260✔
69
static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
1,260✔
70
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa);
1,260✔
71
static BUS_DEFINE_PROPERTY_GET(property_get_oom_score_adjust, "i", ExecContext, exec_context_get_oom_score_adjust);
1,260✔
72
static BUS_DEFINE_PROPERTY_GET(property_get_nice, "i", ExecContext, exec_context_get_nice);
1,260✔
73
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_sched_policy, "i", ExecContext, exec_context_get_cpu_sched_policy);
1,260✔
74
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_sched_priority, "i", ExecContext, exec_context_get_cpu_sched_priority);
1,260✔
75
static BUS_DEFINE_PROPERTY_GET(property_get_coredump_filter, "t", ExecContext, exec_context_get_coredump_filter);
1,260✔
76
static BUS_DEFINE_PROPERTY_GET(property_get_timer_slack_nsec, "t", ExecContext, exec_context_get_timer_slack_nsec);
1,260✔
77
static BUS_DEFINE_PROPERTY_GET(property_get_set_login_environment, "b", ExecContext, exec_context_get_set_login_environment);
1,260✔
78

79
static int property_get_environment_files(
1,260✔
80
                sd_bus *bus,
81
                const char *path,
82
                const char *interface,
83
                const char *property,
84
                sd_bus_message *reply,
85
                void *userdata,
86
                sd_bus_error *error) {
87

88
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
89
        int r;
1,260✔
90

91
        assert(bus);
1,260✔
92
        assert(reply);
1,260✔
93

94
        r = sd_bus_message_open_container(reply, 'a', "(sb)");
1,260✔
95
        if (r < 0)
1,260✔
96
                return r;
97

98
        STRV_FOREACH(j, c->environment_files) {
1,264✔
99
                const char *fn = *j;
4✔
100

101
                r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
4✔
102
                if (r < 0)
4✔
103
                        return r;
104
        }
105

106
        return sd_bus_message_close_container(reply);
1,260✔
107
}
108

109
static int property_get_cpu_affinity(
1,260✔
110
                sd_bus *bus,
111
                const char *path,
112
                const char *interface,
113
                const char *property,
114
                sd_bus_message *reply,
115
                void *userdata,
116
                sd_bus_error *error) {
117

118
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
119
        _cleanup_(cpu_set_reset) CPUSet s = {};
×
120
        _cleanup_free_ uint8_t *array = NULL;
1,260✔
121
        size_t allocated;
1,260✔
122

123
        assert(bus);
1,260✔
124
        assert(reply);
1,260✔
125

126
        if (c->cpu_affinity_from_numa) {
1,260✔
127
                int r;
×
128

129
                r = numa_to_cpu_set(&c->numa_policy, &s);
×
130
                if (r < 0)
×
131
                        return r;
132
        }
133

134
        (void) cpu_set_to_dbus(c->cpu_affinity_from_numa ? &s : &c->cpu_set,  &array, &allocated);
1,260✔
135

136
        return sd_bus_message_append_array(reply, 'y', array, allocated);
1,260✔
137
}
138

139
static int property_get_numa_mask(
1,260✔
140
                sd_bus *bus,
141
                const char *path,
142
                const char *interface,
143
                const char *property,
144
                sd_bus_message *reply,
145
                void *userdata,
146
                sd_bus_error *error) {
147

148
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
149
        _cleanup_free_ uint8_t *array = NULL;
1,260✔
150
        size_t allocated;
1,260✔
151

152
        assert(bus);
1,260✔
153
        assert(reply);
1,260✔
154

155
        (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
1,260✔
156

157
        return sd_bus_message_append_array(reply, 'y', array, allocated);
1,260✔
158
}
159

160
static int property_get_numa_policy(
1,260✔
161
                sd_bus *bus,
162
                const char *path,
163
                const char *interface,
164
                const char *property,
165
                sd_bus_message *reply,
166
                void *userdata,
167
                sd_bus_error *error) {
168
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
169
        int32_t policy;
1,260✔
170

171
        assert(bus);
1,260✔
172
        assert(reply);
1,260✔
173

174
        policy = numa_policy_get_type(&c->numa_policy);
1,260✔
175

176
        return sd_bus_message_append_basic(reply, 'i', &policy);
1,260✔
177
}
178

179
static int property_get_syscall_filter(
1,260✔
180
                sd_bus *bus,
181
                const char *path,
182
                const char *interface,
183
                const char *property,
184
                sd_bus_message *reply,
185
                void *userdata,
186
                sd_bus_error *error) {
187

188
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
189
        _cleanup_strv_free_ char **l = NULL;
1,260✔
190
        int r;
1,260✔
191

192
        assert(bus);
1,260✔
193
        assert(reply);
1,260✔
194

195
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,260✔
196
        if (r < 0)
1,260✔
197
                return r;
198

199
        r = sd_bus_message_append(reply, "b", c->syscall_allow_list);
1,260✔
200
        if (r < 0)
1,260✔
201
                return r;
202

203
        l = exec_context_get_syscall_filter(c);
1,260✔
204
        if (!l)
1,260✔
205
                return -ENOMEM;
206

207
        r = sd_bus_message_append_strv(reply, l);
1,260✔
208
        if (r < 0)
1,260✔
209
                return r;
210

211
        return sd_bus_message_close_container(reply);
1,260✔
212
}
213

214
static int property_get_syscall_log(
1,260✔
215
                sd_bus *bus,
216
                const char *path,
217
                const char *interface,
218
                const char *property,
219
                sd_bus_message *reply,
220
                void *userdata,
221
                sd_bus_error *error) {
222

223
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
224
        _cleanup_strv_free_ char **l = NULL;
1,260✔
225
        int r;
1,260✔
226

227
        assert(bus);
1,260✔
228
        assert(reply);
1,260✔
229

230
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,260✔
231
        if (r < 0)
1,260✔
232
                return r;
233

234
        r = sd_bus_message_append(reply, "b", c->syscall_log_allow_list);
1,260✔
235
        if (r < 0)
1,260✔
236
                return r;
237

238
        l = exec_context_get_syscall_log(c);
1,260✔
239
        if (!l)
1,260✔
240
                return -ENOMEM;
241

242
        r = sd_bus_message_append_strv(reply, l);
1,260✔
243
        if (r < 0)
1,260✔
244
                return r;
245

246
        return sd_bus_message_close_container(reply);
1,260✔
247
}
248

249
static int property_get_syscall_archs(
1,260✔
250
                sd_bus *bus,
251
                const char *path,
252
                const char *interface,
253
                const char *property,
254
                sd_bus_message *reply,
255
                void *userdata,
256
                sd_bus_error *error) {
257

258
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
259
        _cleanup_strv_free_ char **l = NULL;
1,260✔
260
        int r;
1,260✔
261

262
        assert(bus);
1,260✔
263
        assert(reply);
1,260✔
264

265
        l = exec_context_get_syscall_archs(c);
1,260✔
266
        if (!l)
1,260✔
267
                return -ENOMEM;
268

269
        r = sd_bus_message_append_strv(reply, l);
1,260✔
270
        if (r < 0)
1,260✔
271
                return r;
×
272

273
        return 0;
274
}
275

276
static int property_get_selinux_context(
1,260✔
277
                sd_bus *bus,
278
                const char *path,
279
                const char *interface,
280
                const char *property,
281
                sd_bus_message *reply,
282
                void *userdata,
283
                sd_bus_error *error) {
284

285
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
286

287
        assert(bus);
1,260✔
288
        assert(reply);
1,260✔
289

290
        return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
1,260✔
291
}
292

293
static int property_get_apparmor_profile(
1,260✔
294
                sd_bus *bus,
295
                const char *path,
296
                const char *interface,
297
                const char *property,
298
                sd_bus_message *reply,
299
                void *userdata,
300
                sd_bus_error *error) {
301

302
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
303

304
        assert(bus);
1,260✔
305
        assert(reply);
1,260✔
306

307
        return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
1,260✔
308
}
309

310
static int property_get_smack_process_label(
1,260✔
311
                sd_bus *bus,
312
                const char *path,
313
                const char *interface,
314
                const char *property,
315
                sd_bus_message *reply,
316
                void *userdata,
317
                sd_bus_error *error) {
318

319
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
320

321
        assert(bus);
1,260✔
322
        assert(reply);
1,260✔
323

324
        return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
1,260✔
325
}
326

327
static int property_get_address_families(
1,260✔
328
                sd_bus *bus,
329
                const char *path,
330
                const char *interface,
331
                const char *property,
332
                sd_bus_message *reply,
333
                void *userdata,
334
                sd_bus_error *error) {
335

336
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
337
        _cleanup_strv_free_ char **l = NULL;
1,260✔
338
        int r;
1,260✔
339

340
        assert(bus);
1,260✔
341
        assert(reply);
1,260✔
342

343
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,260✔
344
        if (r < 0)
1,260✔
345
                return r;
346

347
        r = sd_bus_message_append(reply, "b", c->address_families_allow_list);
1,260✔
348
        if (r < 0)
1,260✔
349
                return r;
350

351
        l = exec_context_get_address_families(c);
1,260✔
352
        if (!l)
1,260✔
353
                return -ENOMEM;
354

355
        r = sd_bus_message_append_strv(reply, l);
1,260✔
356
        if (r < 0)
1,260✔
357
                return r;
358

359
        return sd_bus_message_close_container(reply);
1,260✔
360
}
361

362
static int property_get_working_directory(
1,260✔
363
                sd_bus *bus,
364
                const char *path,
365
                const char *interface,
366
                const char *property,
367
                sd_bus_message *reply,
368
                void *userdata,
369
                sd_bus_error *error) {
370

371
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
372
        const char *wd;
1,260✔
373

374
        assert(bus);
1,260✔
375
        assert(reply);
1,260✔
376

377
        if (c->working_directory_home)
1,260✔
378
                wd = "~";
379
        else
380
                wd = c->working_directory;
1,260✔
381

382
        if (c->working_directory_missing_ok)
1,260✔
383
                wd = strjoina("!", wd);
1,920✔
384

385
        return sd_bus_message_append(reply, "s", wd);
1,260✔
386
}
387

388
static int property_get_stdio_fdname(
3,780✔
389
                sd_bus *bus,
390
                const char *path,
391
                const char *interface,
392
                const char *property,
393
                sd_bus_message *reply,
394
                void *userdata,
395
                sd_bus_error *error) {
396

397
        ExecContext *c = ASSERT_PTR(userdata);
3,780✔
398
        int fileno;
3,780✔
399

400
        assert(bus);
3,780✔
401
        assert(property);
3,780✔
402
        assert(reply);
3,780✔
403

404
        if (streq(property, "StandardInputFileDescriptorName"))
3,780✔
405
                fileno = STDIN_FILENO;
406
        else if (streq(property, "StandardOutputFileDescriptorName"))
2,520✔
407
                fileno = STDOUT_FILENO;
408
        else {
409
                assert(streq(property, "StandardErrorFileDescriptorName"));
1,260✔
410
                fileno = STDERR_FILENO;
411
        }
412

413
        return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
3,780✔
414
}
415

416
static int property_get_input_data(
1,260✔
417
                sd_bus *bus,
418
                const char *path,
419
                const char *interface,
420
                const char *property,
421
                sd_bus_message *reply,
422
                void *userdata,
423
                sd_bus_error *error) {
424

425
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
426

427
        assert(bus);
1,260✔
428
        assert(property);
1,260✔
429
        assert(reply);
1,260✔
430

431
        return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
1,260✔
432
}
433

434
static int property_get_restrict_filesystems(
1,260✔
435
                sd_bus *bus,
436
                const char *path,
437
                const char *interface,
438
                const char *property,
439
                sd_bus_message *reply,
440
                void *userdata,
441
                sd_bus_error *error) {
442

443
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
444
        _cleanup_free_ char **l = NULL; /* Strings are owned by 'c->restrict_filesystems'! */
1,260✔
445
        int r;
1,260✔
446

447
        assert(bus);
1,260✔
448
        assert(reply);
1,260✔
449

450
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,260✔
451
        if (r < 0)
1,260✔
452
                return r;
453

454
        r = sd_bus_message_append(reply, "b", c->restrict_filesystems_allow_list);
1,260✔
455
        if (r < 0)
1,260✔
456
                return r;
457

458
        l = exec_context_get_restrict_filesystems(c);
1,260✔
459
        if (!l)
1,260✔
460
                return -ENOMEM;
461

462
        r = sd_bus_message_append_strv(reply, l);
1,260✔
463
        if (r < 0)
1,260✔
464
                return r;
465

466
        return sd_bus_message_close_container(reply);
1,260✔
467
}
468

469
static int property_get_bind_paths(
2,520✔
470
                sd_bus *bus,
471
                const char *path,
472
                const char *interface,
473
                const char *property,
474
                sd_bus_message *reply,
475
                void *userdata,
476
                sd_bus_error *error) {
477

478
        ExecContext *c = ASSERT_PTR(userdata);
2,520✔
479
        bool ro;
2,520✔
480
        int r;
2,520✔
481

482
        assert(bus);
2,520✔
483
        assert(property);
2,520✔
484
        assert(reply);
2,520✔
485

486
        ro = strstr(property, "ReadOnly");
2,520✔
487

488
        r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
2,520✔
489
        if (r < 0)
2,520✔
490
                return r;
491

492
        FOREACH_ARRAY(i, c->bind_mounts, c->n_bind_mounts) {
2,660✔
493
                if (ro != i->read_only)
140✔
494
                        continue;
70✔
495

496
                r = sd_bus_message_append(
210✔
497
                                reply, "(ssbt)",
498
                                i->source,
499
                                i->destination,
500
                                i->ignore_enoent,
70✔
501
                                i->recursive ? (uint64_t) MS_REC : UINT64_C(0));
70✔
502
                if (r < 0)
70✔
503
                        return r;
504
        }
505

506
        return sd_bus_message_close_container(reply);
2,520✔
507
}
508

509
static int property_get_temporary_filesystems(
1,260✔
510
                sd_bus *bus,
511
                const char *path,
512
                const char *interface,
513
                const char *property,
514
                sd_bus_message *reply,
515
                void *userdata,
516
                sd_bus_error *error) {
517

518
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
519
        int r;
1,260✔
520

521
        assert(bus);
1,260✔
522
        assert(property);
1,260✔
523
        assert(reply);
1,260✔
524

525
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,260✔
526
        if (r < 0)
1,260✔
527
                return r;
528

529
        FOREACH_ARRAY(t, c->temporary_filesystems, c->n_temporary_filesystems) {
1,280✔
530
                r = sd_bus_message_append(
20✔
531
                                reply, "(ss)",
532
                                t->path,
533
                                t->options);
534
                if (r < 0)
20✔
535
                        return r;
536
        }
537

538
        return sd_bus_message_close_container(reply);
1,260✔
539
}
540

541
static int property_get_log_extra_fields(
1,260✔
542
                sd_bus *bus,
543
                const char *path,
544
                const char *interface,
545
                const char *property,
546
                sd_bus_message *reply,
547
                void *userdata,
548
                sd_bus_error *error) {
549

550
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
551
        int r;
1,260✔
552

553
        assert(bus);
1,260✔
554
        assert(property);
1,260✔
555
        assert(reply);
1,260✔
556

557
        r = sd_bus_message_open_container(reply, 'a', "ay");
1,260✔
558
        if (r < 0)
1,260✔
559
                return r;
560

561
        FOREACH_ARRAY(i, c->log_extra_fields, c->n_log_extra_fields) {
1,260✔
562
                r = sd_bus_message_append_array(reply, 'y', i->iov_base, i->iov_len);
×
563
                if (r < 0)
×
564
                        return r;
565
        }
566

567
        return sd_bus_message_close_container(reply);
1,260✔
568
}
569

570
static int sd_bus_message_append_log_filter_patterns(sd_bus_message *reply, Set *patterns, bool is_allowlist) {
2,520✔
571
        const char *pattern;
2,520✔
572
        int r;
2,520✔
573

574
        assert(reply);
2,520✔
575

576
        SET_FOREACH(pattern, patterns) {
2,520✔
577
                r = sd_bus_message_append(reply, "(bs)", is_allowlist, pattern);
×
578
                if (r < 0)
×
579
                        return r;
×
580
        }
581

582
        return 0;
2,520✔
583
}
584

585
static int property_get_log_filter_patterns(
1,260✔
586
                sd_bus *bus,
587
                const char *path,
588
                const char *interface,
589
                const char *property,
590
                sd_bus_message *reply,
591
                void *userdata,
592
                sd_bus_error *error) {
593

594
        ExecContext *c = userdata;
1,260✔
595
        int r;
1,260✔
596

597
        assert(c);
1,260✔
598
        assert(reply);
1,260✔
599

600
        r = sd_bus_message_open_container(reply, 'a', "(bs)");
1,260✔
601
        if (r < 0)
1,260✔
602
                return r;
603

604
        r = sd_bus_message_append_log_filter_patterns(reply, c->log_filter_allowed_patterns,
1,260✔
605
                                                      /* is_allowlist = */ true);
606
        if (r < 0)
1,260✔
607
                return r;
608

609
        r = sd_bus_message_append_log_filter_patterns(reply, c->log_filter_denied_patterns,
1,260✔
610
                                                      /* is_allowlist = */ false);
611
        if (r < 0)
1,260✔
612
                return r;
613

614
        return sd_bus_message_close_container(reply);
1,260✔
615
}
616

617
static int property_get_set_credential(
2,520✔
618
                sd_bus *bus,
619
                const char *path,
620
                const char *interface,
621
                const char *property,
622
                sd_bus_message *reply,
623
                void *userdata,
624
                sd_bus_error *error) {
625

626
        ExecContext *c = ASSERT_PTR(userdata);
2,520✔
627
        ExecSetCredential *sc;
2,520✔
628
        int r;
2,520✔
629

630
        assert(bus);
2,520✔
631
        assert(property);
2,520✔
632
        assert(reply);
2,520✔
633

634
        r = sd_bus_message_open_container(reply, 'a', "(say)");
2,520✔
635
        if (r < 0)
2,520✔
636
                return r;
2,520✔
637

638
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,520✔
639

640
                if (sc->encrypted != streq(property, "SetCredentialEncrypted"))
×
641
                        continue;
×
642

643
                r = sd_bus_message_open_container(reply, 'r', "say");
×
644
                if (r < 0)
×
645
                        return r;
×
646

647
                r = sd_bus_message_append(reply, "s", sc->id);
×
648
                if (r < 0)
×
649
                        return r;
650

651
                r = sd_bus_message_append_array(reply, 'y', sc->data, sc->size);
×
652
                if (r < 0)
×
653
                        return r;
654

655
                r = sd_bus_message_close_container(reply);
×
656
                if (r < 0)
×
657
                        return r;
658
        }
659

660
        return sd_bus_message_close_container(reply);
2,520✔
661
}
662

663
static int property_get_load_credential(
2,520✔
664
                sd_bus *bus,
665
                const char *path,
666
                const char *interface,
667
                const char *property,
668
                sd_bus_message *reply,
669
                void *userdata,
670
                sd_bus_error *error) {
671

672
        ExecContext *c = ASSERT_PTR(userdata);
2,520✔
673
        ExecLoadCredential *lc;
2,520✔
674
        int r;
2,520✔
675

676
        assert(bus);
2,520✔
677
        assert(property);
2,520✔
678
        assert(reply);
2,520✔
679

680
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
2,520✔
681
        if (r < 0)
2,520✔
682
                return r;
2,520✔
683

684
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,536✔
685

686
                if (lc->encrypted != streq(property, "LoadCredentialEncrypted"))
16✔
687
                        continue;
8✔
688

689
                r = sd_bus_message_append(reply, "(ss)", lc->id, lc->path);
8✔
690
                if (r < 0)
8✔
691
                        return r;
×
692
        }
693

694
        return sd_bus_message_close_container(reply);
2,520✔
695
}
696

697
static int property_get_import_credential(
1,260✔
698
                sd_bus *bus,
699
                const char *path,
700
                const char *interface,
701
                const char *property,
702
                sd_bus_message *reply,
703
                void *userdata,
704
                sd_bus_error *error) {
705

706
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
707
        ExecImportCredential *ic;
1,260✔
708
        int r;
1,260✔
709

710
        assert(bus);
1,260✔
711
        assert(property);
1,260✔
712
        assert(reply);
1,260✔
713

714
        r = sd_bus_message_open_container(reply, 'a', "s");
1,260✔
715
        if (r < 0)
1,260✔
716
                return r;
1,260✔
717

718
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
1,385✔
719
                r = sd_bus_message_append(reply, "s", ic->glob);
125✔
720
                if (r < 0)
125✔
721
                        return r;
×
722
        }
723

724
        return sd_bus_message_close_container(reply);
1,260✔
725
}
726

727
static int property_get_import_credential_ex(
1,260✔
728
                sd_bus *bus,
729
                const char *path,
730
                const char *interface,
731
                const char *property,
732
                sd_bus_message *reply,
733
                void *userdata,
734
                sd_bus_error *error) {
735

736
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
737
        ExecImportCredential *ic;
1,260✔
738
        int r;
1,260✔
739

740
        assert(bus);
1,260✔
741
        assert(property);
1,260✔
742
        assert(reply);
1,260✔
743

744
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,260✔
745
        if (r < 0)
1,260✔
746
                return r;
1,260✔
747

748
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
1,385✔
749
                r = sd_bus_message_append(reply, "(ss)", ic->glob, ic->rename);
125✔
750
                if (r < 0)
125✔
751
                        return r;
×
752
        }
753

754
        return sd_bus_message_close_container(reply);
1,260✔
755
}
756

757
static int property_get_root_hash(
1,260✔
758
                sd_bus *bus,
759
                const char *path,
760
                const char *interface,
761
                const char *property,
762
                sd_bus_message *reply,
763
                void *userdata,
764
                sd_bus_error *error) {
765

766
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
767

768
        assert(bus);
1,260✔
769
        assert(property);
1,260✔
770
        assert(reply);
1,260✔
771

772
        return sd_bus_message_append_array(reply, 'y', c->root_hash, c->root_hash_size);
1,260✔
773
}
774

775
static int property_get_root_hash_sig(
1,260✔
776
                sd_bus *bus,
777
                const char *path,
778
                const char *interface,
779
                const char *property,
780
                sd_bus_message *reply,
781
                void *userdata,
782
                sd_bus_error *error) {
783

784
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
785

786
        assert(bus);
1,260✔
787
        assert(property);
1,260✔
788
        assert(reply);
1,260✔
789

790
        return sd_bus_message_append_array(reply, 'y', c->root_hash_sig, c->root_hash_sig_size);
1,260✔
791
}
792

793
static int property_get_root_image_options(
1,260✔
794
                sd_bus *bus,
795
                const char *path,
796
                const char *interface,
797
                const char *property,
798
                sd_bus_message *reply,
799
                void *userdata,
800
                sd_bus_error *error) {
801

802
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
803
        int r;
1,260✔
804

805
        assert(bus);
1,260✔
806
        assert(property);
1,260✔
807
        assert(reply);
1,260✔
808

809
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,260✔
810
        if (r < 0)
1,260✔
811
                return r;
812

813
        LIST_FOREACH(mount_options, m, c->root_image_options) {
1,260✔
814
                r = sd_bus_message_append(reply, "(ss)",
×
815
                                          partition_designator_to_string(m->partition_designator),
816
                                          m->options);
817
                if (r < 0)
×
818
                        return r;
819
        }
820

821
        return sd_bus_message_close_container(reply);
1,260✔
822
}
823

824
static int property_get_mount_images(
1,260✔
825
                sd_bus *bus,
826
                const char *path,
827
                const char *interface,
828
                const char *property,
829
                sd_bus_message *reply,
830
                void *userdata,
831
                sd_bus_error *error) {
832

833
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
834
        int r;
1,260✔
835

836
        assert(bus);
1,260✔
837
        assert(property);
1,260✔
838
        assert(reply);
1,260✔
839

840
        r = sd_bus_message_open_container(reply, 'a', "(ssba(ss))");
1,260✔
841
        if (r < 0)
1,260✔
842
                return r;
843

844
        FOREACH_ARRAY(i, c->mount_images, c->n_mount_images) {
1,260✔
845
                r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "ssba(ss)");
×
846
                if (r < 0)
×
847
                        return r;
848

849
                r = sd_bus_message_append(
×
850
                                reply, "ssb",
851
                                i->source,
852
                                i->destination,
853
                                i->ignore_enoent);
×
854
                if (r < 0)
×
855
                        return r;
856

857
                r = sd_bus_message_open_container(reply, 'a', "(ss)");
×
858
                if (r < 0)
×
859
                        return r;
860

861
                LIST_FOREACH(mount_options, m, i->mount_options) {
×
862
                        r = sd_bus_message_append(reply, "(ss)",
×
863
                                                  partition_designator_to_string(m->partition_designator),
864
                                                  m->options);
865
                        if (r < 0)
×
866
                                return r;
867
                }
868

869
                r = sd_bus_message_close_container(reply);
×
870
                if (r < 0)
×
871
                        return r;
872

873
                r = sd_bus_message_close_container(reply);
×
874
                if (r < 0)
×
875
                        return r;
876
        }
877

878
        return sd_bus_message_close_container(reply);
1,260✔
879
}
880

881
static int property_get_extension_images(
1,260✔
882
                sd_bus *bus,
883
                const char *path,
884
                const char *interface,
885
                const char *property,
886
                sd_bus_message *reply,
887
                void *userdata,
888
                sd_bus_error *error) {
889

890
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
891
        int r;
1,260✔
892

893
        assert(bus);
1,260✔
894
        assert(property);
1,260✔
895
        assert(reply);
1,260✔
896

897
        r = sd_bus_message_open_container(reply, 'a', "(sba(ss))");
1,260✔
898
        if (r < 0)
1,260✔
899
                return r;
900

901
        FOREACH_ARRAY(i, c->extension_images, c->n_extension_images) {
1,260✔
902
                r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "sba(ss)");
×
903
                if (r < 0)
×
904
                        return r;
905

906
                r = sd_bus_message_append(
×
907
                                reply, "sb",
908
                                i->source,
909
                                i->ignore_enoent);
×
910
                if (r < 0)
×
911
                        return r;
912

913
                r = sd_bus_message_open_container(reply, 'a', "(ss)");
×
914
                if (r < 0)
×
915
                        return r;
916

917
                LIST_FOREACH(mount_options, m, i->mount_options) {
×
918
                        r = sd_bus_message_append(reply, "(ss)",
×
919
                                                  partition_designator_to_string(m->partition_designator),
920
                                                  m->options);
921
                        if (r < 0)
×
922
                                return r;
923
                }
924

925
                r = sd_bus_message_close_container(reply);
×
926
                if (r < 0)
×
927
                        return r;
928

929
                r = sd_bus_message_close_container(reply);
×
930
                if (r < 0)
×
931
                        return r;
932
        }
933

934
        return sd_bus_message_close_container(reply);
1,260✔
935
}
936

937
static int property_get_exec_dir(
6,300✔
938
                sd_bus *bus,
939
                const char *path,
940
                const char *interface,
941
                const char *property,
942
                sd_bus_message *reply,
943
                void *userdata,
944
                sd_bus_error *error) {
945

946
        ExecDirectory *d = ASSERT_PTR(userdata);
6,300✔
947
        int r;
6,300✔
948

949
        assert(bus);
6,300✔
950
        assert(property);
6,300✔
951
        assert(reply);
6,300✔
952

953
        r = sd_bus_message_open_container(reply, 'a', "s");
6,300✔
954
        if (r < 0)
6,300✔
955
                return r;
956

957
        FOREACH_ARRAY(i, d->items, d->n_items) {
6,825✔
958
                r = sd_bus_message_append_basic(reply, 's', i->path);
525✔
959
                if (r < 0)
525✔
960
                        return r;
961
        }
962

963
        return sd_bus_message_close_container(reply);
6,300✔
964
}
965

966
static int property_get_exec_dir_symlink(
5,040✔
967
                sd_bus *bus,
968
                const char *path,
969
                const char *interface,
970
                const char *property,
971
                sd_bus_message *reply,
972
                void *userdata,
973
                sd_bus_error *error) {
974

975
        ExecDirectory *d = ASSERT_PTR(userdata);
5,040✔
976
        int r;
5,040✔
977

978
        assert(bus);
5,040✔
979
        assert(property);
5,040✔
980
        assert(reply);
5,040✔
981

982
        r = sd_bus_message_open_container(reply, 'a', "(sst)");
5,040✔
983
        if (r < 0)
5,040✔
984
                return r;
985

986
        FOREACH_ARRAY(i, d->items, d->n_items)
5,417✔
987
                if (strv_isempty(i->symlinks)) {
377✔
988
                        /* The old exec directory properties cannot represent flags, so list them here with no
989
                         * destination */
990
                        r = sd_bus_message_append(reply, "(sst)", i->path, "", (uint64_t) (i->flags & _EXEC_DIRECTORY_FLAGS_PUBLIC));
341✔
991
                        if (r < 0)
341✔
992
                                return r;
993
                } else
994
                        STRV_FOREACH(dst, i->symlinks) {
72✔
995
                                r = sd_bus_message_append(reply, "(sst)", i->path, *dst, (uint64_t) (i->flags & _EXEC_DIRECTORY_FLAGS_PUBLIC));
36✔
996
                                if (r < 0)
36✔
997
                                        return r;
998
                        }
999

1000
        return sd_bus_message_close_container(reply);
5,040✔
1001
}
1002

1003
static int property_get_image_policy(
3,780✔
1004
                sd_bus *bus,
1005
                const char *path,
1006
                const char *interface,
1007
                const char *property,
1008
                sd_bus_message *reply,
1009
                void *userdata,
1010
                sd_bus_error *error) {
1011

1012
        ImagePolicy **pp = ASSERT_PTR(userdata);
3,780✔
1013
        _cleanup_free_ char *s = NULL;
3,780✔
1014
        int r;
3,780✔
1015

1016
        assert(bus);
3,780✔
1017
        assert(property);
3,780✔
1018
        assert(reply);
3,780✔
1019

1020
        r = image_policy_to_string(*pp ?: &image_policy_service, /* simplify= */ true, &s);
7,560✔
1021
        if (r < 0)
3,780✔
1022
                return r;
1023

1024
        return sd_bus_message_append(reply, "s", s);
3,780✔
1025
}
1026

1027
static int property_get_private_tmp(
1,260✔
1028
                sd_bus *bus,
1029
                const char *path,
1030
                const char *interface,
1031
                const char *property,
1032
                sd_bus_message *reply,
1033
                void *userdata,
1034
                sd_bus_error *error) {
1035

1036
        PrivateTmp *p = ASSERT_PTR(userdata);
1,260✔
1037
        int b = *p != PRIVATE_TMP_NO;
1,260✔
1038

1039
        return sd_bus_message_append_basic(reply, 'b', &b);
1,260✔
1040
}
1041

1042
static int property_get_private_users(
1,260✔
1043
                sd_bus *bus,
1044
                const char *path,
1045
                const char *interface,
1046
                const char *property,
1047
                sd_bus_message *reply,
1048
                void *userdata,
1049
                sd_bus_error *error) {
1050

1051
        PrivateUsers *p = ASSERT_PTR(userdata);
1,260✔
1052
        int b = *p != PRIVATE_USERS_NO;
1,260✔
1053

1054
        return sd_bus_message_append_basic(reply, 'b', &b);
1,260✔
1055
}
1056

1057
static int property_get_protect_control_groups(
1,260✔
1058
                sd_bus *bus,
1059
                const char *path,
1060
                const char *interface,
1061
                const char *property,
1062
                sd_bus_message *reply,
1063
                void *userdata,
1064
                sd_bus_error *error) {
1065

1066
        ProtectControlGroups *p = ASSERT_PTR(userdata);
1,260✔
1067
        int b = *p != PROTECT_CONTROL_GROUPS_NO;
1,260✔
1068

1069
        return sd_bus_message_append_basic(reply, 'b', &b);
1,260✔
1070
}
1071

1072
static int property_get_protect_hostname(
1,260✔
1073
                sd_bus *bus,
1074
                const char *path,
1075
                const char *interface,
1076
                const char *property,
1077
                sd_bus_message *reply,
1078
                void *userdata,
1079
                sd_bus_error *error) {
1080

1081
        ProtectHostname *p = ASSERT_PTR(userdata);
1,260✔
1082
        int b = *p != PROTECT_HOSTNAME_NO;
1,260✔
1083

1084
        return sd_bus_message_append_basic(reply, 'b', &b);
1,260✔
1085
}
1086

1087
static int property_get_protect_hostname_ex(
1,260✔
1088
                sd_bus *bus,
1089
                const char *path,
1090
                const char *interface,
1091
                const char *property,
1092
                sd_bus_message *reply,
1093
                void *userdata,
1094
                sd_bus_error *error) {
1095

1096
        ExecContext *c = ASSERT_PTR(userdata);
1,260✔
1097

1098
        return sd_bus_message_append(reply, "(ss)", protect_hostname_to_string(c->protect_hostname), c->private_hostname);
1,260✔
1099
}
1100

1101
static int property_get_unsigned_as_uint16(
2,520✔
1102
                sd_bus *bus,
1103
                const char *path,
1104
                const char *interface,
1105
                const char *property,
1106
                sd_bus_message *reply,
1107
                void *userdata,
1108
                sd_bus_error *error) {
1109

1110
        unsigned *value = ASSERT_PTR(userdata);
2,520✔
1111

1112
        /* Returns an unsigned as a D-Bus "q" type, i.e. as 16-bit value, even if unsigned is 32-bit. We'll saturate if it doesn't fit. */
1113

1114
        uint16_t q = *value >= UINT16_MAX ? UINT16_MAX : (uint16_t) *value;
2,520✔
1115
        return sd_bus_message_append_basic(reply, 'q', &q);
2,520✔
1116
}
1117

1118
const sd_bus_vtable bus_exec_vtable[] = {
1119
        SD_BUS_VTABLE_START(0),
1120
        SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
1121
        SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1122
        SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
1123
        SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
1124
        SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
1125
        SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1126
        SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1127
        SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1128
        SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1129
        SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1130
        SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1131
        SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1132
        SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1133
        SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1134
        SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1135
        SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1136
        SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1137
        SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1138
        SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1139
        SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1140
        SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1141
        SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1142
        SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1143
        SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1144
        SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1145
        SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1146
        SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1147
        SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1148
        SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1149
        SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1150
        SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1151
        SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1152
        SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1153
        SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1154
        SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1155
        SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1156
        SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1157
        SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1158
        SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
1159
        SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
1160
        SD_BUS_PROPERTY("RootImageOptions", "a(ss)", property_get_root_image_options, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1161
        SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1162
        SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
1163
        SD_BUS_PROPERTY("RootHashSignature", "ay", property_get_root_hash_sig, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1164
        SD_BUS_PROPERTY("RootHashSignaturePath", "s", NULL, offsetof(ExecContext, root_hash_sig_path), SD_BUS_VTABLE_PROPERTY_CONST),
1165
        SD_BUS_PROPERTY("RootVerity", "s", NULL, offsetof(ExecContext, root_verity), SD_BUS_VTABLE_PROPERTY_CONST),
1166
        SD_BUS_PROPERTY("RootEphemeral", "b", bus_property_get_bool, offsetof(ExecContext, root_ephemeral), SD_BUS_VTABLE_PROPERTY_CONST),
1167
        SD_BUS_PROPERTY("ExtensionDirectories", "as", NULL, offsetof(ExecContext, extension_directories), SD_BUS_VTABLE_PROPERTY_CONST),
1168
        SD_BUS_PROPERTY("ExtensionImages", "a(sba(ss))", property_get_extension_images, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1169
        SD_BUS_PROPERTY("MountImages", "a(ssba(ss))", property_get_mount_images, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1170
        SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1171
        SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1172
        SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1173
        SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1174
        SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1175
        SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1176
        SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1177
        SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1178
        SD_BUS_PROPERTY("CPUAffinityFromNUMA", "b", property_get_cpu_affinity_from_numa, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1179
        SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1180
        SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1181
        SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1182
        SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
1183
        SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
1184
        SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
1185
        SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1186
        SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1187
        SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1188
        SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1189
        SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
1190
        SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1191
        SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
1192
        SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
1193
        SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
1194
        SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
1195
        SD_BUS_PROPERTY("TTYRows", "q", property_get_unsigned_as_uint16, offsetof(ExecContext, tty_rows), SD_BUS_VTABLE_PROPERTY_CONST),
1196
        SD_BUS_PROPERTY("TTYColumns", "q", property_get_unsigned_as_uint16, offsetof(ExecContext, tty_cols), SD_BUS_VTABLE_PROPERTY_CONST),
1197
        SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1198
        SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
1199
        SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
1200
        SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1201
        SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1202
        SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
1203
        SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
1204
        SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
1205
        SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1206
        SD_BUS_PROPERTY("LogFilterPatterns", "a(bs)", property_get_log_filter_patterns, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1207
        SD_BUS_PROPERTY("LogNamespace", "s", NULL, offsetof(ExecContext, log_namespace), SD_BUS_VTABLE_PROPERTY_CONST),
1208
        SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
1209
        SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
1210
        SD_BUS_PROPERTY("AmbientCapabilities", "t", NULL, offsetof(ExecContext, capability_ambient_set), SD_BUS_VTABLE_PROPERTY_CONST),
1211
        SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
1212
        SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
1213
        SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
1214
        SD_BUS_PROPERTY("SetLoginEnvironment", "b", property_get_set_login_environment, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1215
        SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
1216
        SD_BUS_PROPERTY("SetCredential", "a(say)", property_get_set_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1217
        SD_BUS_PROPERTY("SetCredentialEncrypted", "a(say)", property_get_set_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1218
        SD_BUS_PROPERTY("LoadCredential", "a(ss)", property_get_load_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1219
        SD_BUS_PROPERTY("LoadCredentialEncrypted", "a(ss)", property_get_load_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1220
        SD_BUS_PROPERTY("ImportCredential", "as", property_get_import_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1221
        SD_BUS_PROPERTY("ImportCredentialEx", "a(ss)", property_get_import_credential_ex, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1222
        SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1223
        SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
1224
        SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1225
        SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1226
        SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1227
        SD_BUS_PROPERTY("ExecPaths", "as", NULL, offsetof(ExecContext, exec_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1228
        SD_BUS_PROPERTY("NoExecPaths", "as", NULL, offsetof(ExecContext, no_exec_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1229
        SD_BUS_PROPERTY("ExecSearchPath", "as", NULL, offsetof(ExecContext, exec_search_path), SD_BUS_VTABLE_PROPERTY_CONST),
1230
        SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_propagation_flag), SD_BUS_VTABLE_PROPERTY_CONST),
1231
        SD_BUS_PROPERTY("PrivateTmp", "b", property_get_private_tmp, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
1232
        SD_BUS_PROPERTY("PrivateTmpEx", "s", property_get_private_tmp_ex, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
1233
        SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
1234
        SD_BUS_PROPERTY("ProtectClock", "b", bus_property_get_bool, offsetof(ExecContext, protect_clock), SD_BUS_VTABLE_PROPERTY_CONST),
1235
        SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
1236
        SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
1237
        SD_BUS_PROPERTY("ProtectKernelLogs", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_logs), SD_BUS_VTABLE_PROPERTY_CONST),
1238
        SD_BUS_PROPERTY("ProtectControlGroups", "b", property_get_protect_control_groups, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1239
        SD_BUS_PROPERTY("ProtectControlGroupsEx", "s", property_get_protect_control_groups_ex, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1240
        SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
1241
        SD_BUS_PROPERTY("PrivateUsers", "b", property_get_private_users, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
1242
        SD_BUS_PROPERTY("PrivateUsersEx", "s", property_get_private_users_ex, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
1243
        SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_tristate, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST),
1244
        SD_BUS_PROPERTY("PrivateIPC", "b", bus_property_get_bool, offsetof(ExecContext, private_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
1245
        SD_BUS_PROPERTY("PrivatePIDs", "s", property_get_private_pids, offsetof(ExecContext, private_pids), SD_BUS_VTABLE_PROPERTY_CONST),
1246
        SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
1247
        SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
1248
        SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
1249
        SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
1250
        SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1251
        SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1252
        SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1253
        SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1254
        SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
1255
        SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
1256
        SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1257
        SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1258
        SD_BUS_PROPERTY("SystemCallErrorNumber", "i", bus_property_get_int, offsetof(ExecContext, syscall_errno), SD_BUS_VTABLE_PROPERTY_CONST),
1259
        SD_BUS_PROPERTY("SystemCallLog", "(bas)", property_get_syscall_log, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1260
        SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST),
1261
        SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
1262
        SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1263
        SD_BUS_PROPERTY("RuntimeDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1264
        SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", bus_property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1265
        SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1266
        SD_BUS_PROPERTY("RuntimeDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1267
        SD_BUS_PROPERTY("StateDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
1268
        SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1269
        SD_BUS_PROPERTY("StateDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
1270
        SD_BUS_PROPERTY("CacheDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
1271
        SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1272
        SD_BUS_PROPERTY("CacheDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
1273
        SD_BUS_PROPERTY("LogsDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
1274
        SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1275
        SD_BUS_PROPERTY("LogsDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
1276
        SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1277
        SD_BUS_PROPERTY("ConfigurationDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION]), SD_BUS_VTABLE_PROPERTY_CONST),
1278
        SD_BUS_PROPERTY("TimeoutCleanUSec", "t", bus_property_get_usec, offsetof(ExecContext, timeout_clean_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1279
        SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
1280
        SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
1281
        SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
1282
        SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
1283
        SD_BUS_PROPERTY("DelegateNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, delegate_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
1284
        SD_BUS_PROPERTY("RestrictFileSystems", "(bas)", property_get_restrict_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1285
        SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1286
        SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1287
        SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1288
        SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1289
        SD_BUS_PROPERTY("BindLogSockets", "b", property_get_bind_log_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1290
        SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1291
        SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
1292
        SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
1293
        SD_BUS_PROPERTY("ProtectHostname", "b", property_get_protect_hostname, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
1294
        SD_BUS_PROPERTY("ProtectHostnameEx", "(ss)", property_get_protect_hostname_ex, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1295
        SD_BUS_PROPERTY("MemoryKSM", "b", bus_property_get_tristate, offsetof(ExecContext, memory_ksm), SD_BUS_VTABLE_PROPERTY_CONST),
1296
        SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
1297
        SD_BUS_PROPERTY("IPCNamespacePath", "s", NULL, offsetof(ExecContext, ipc_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
1298
        SD_BUS_PROPERTY("RootImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, root_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1299
        SD_BUS_PROPERTY("MountImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, mount_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1300
        SD_BUS_PROPERTY("ExtensionImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, extension_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1301

1302
        /* Obsolete/redundant properties: */
1303
        SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1304
        SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1305
        SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1306
        SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1307
        SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1308

1309
        SD_BUS_VTABLE_END
1310
};
1311

1312
static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
1,457✔
1313
        int r;
1,457✔
1314

1315
        assert(reply);
1,457✔
1316
        assert(c);
1,457✔
1317

1318
        if (!c->path)
1,457✔
1319
                return 0;
1320

1321
        r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
1,227✔
1322
        if (r < 0)
1,227✔
1323
                return r;
1324

1325
        r = sd_bus_message_append(reply, "s", c->path);
1,227✔
1326
        if (r < 0)
1,227✔
1327
                return r;
1328

1329
        r = sd_bus_message_append_strv(reply, c->argv);
1,227✔
1330
        if (r < 0)
1,227✔
1331
                return r;
1332

1333
        r = sd_bus_message_append(reply, "bttttuii",
2,454✔
1334
                                  !!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
1,227✔
1335
                                  c->exec_status.start_timestamp.realtime,
1336
                                  c->exec_status.start_timestamp.monotonic,
1337
                                  c->exec_status.exit_timestamp.realtime,
1338
                                  c->exec_status.exit_timestamp.monotonic,
1339
                                  (uint32_t) c->exec_status.pid,
1,227✔
1340
                                  (int32_t) c->exec_status.code,
1341
                                  (int32_t) c->exec_status.status);
1342
        if (r < 0)
1,227✔
1343
                return r;
1344

1345
        return sd_bus_message_close_container(reply);
1,227✔
1346
}
1347

1348
static int append_exec_ex_command(sd_bus_message *reply, ExecCommand *c) {
1,223✔
1349
        _cleanup_strv_free_ char **ex_opts = NULL;
1,223✔
1350
        int r;
1,223✔
1351

1352
        assert(reply);
1,223✔
1353
        assert(c);
1,223✔
1354

1355
        if (!c->path)
1,223✔
1356
                return 0;
1357

1358
        r = sd_bus_message_open_container(reply, 'r', "sasasttttuii");
1,223✔
1359
        if (r < 0)
1,223✔
1360
                return r;
1361

1362
        r = sd_bus_message_append(reply, "s", c->path);
1,223✔
1363
        if (r < 0)
1,223✔
1364
                return r;
1365

1366
        r = sd_bus_message_append_strv(reply, c->argv);
1,223✔
1367
        if (r < 0)
1,223✔
1368
                return r;
1369

1370
        r = exec_command_flags_to_strv(c->flags, &ex_opts);
1,223✔
1371
        if (r < 0)
1,223✔
1372
                return r;
1373

1374
        r = sd_bus_message_append_strv(reply, ex_opts);
1,223✔
1375
        if (r < 0)
1,223✔
1376
                return r;
1377

1378
        r = sd_bus_message_append(reply, "ttttuii",
2,446✔
1379
                                  c->exec_status.start_timestamp.realtime,
1380
                                  c->exec_status.start_timestamp.monotonic,
1381
                                  c->exec_status.exit_timestamp.realtime,
1382
                                  c->exec_status.exit_timestamp.monotonic,
1383
                                  (uint32_t) c->exec_status.pid,
1,223✔
1384
                                  (int32_t) c->exec_status.code,
1385
                                  (int32_t) c->exec_status.status);
1386
        if (r < 0)
1,223✔
1387
                return r;
1388

1389
        return sd_bus_message_close_container(reply);
1,223✔
1390
}
1391

1392
int bus_property_get_exec_command(
234✔
1393
                sd_bus *bus,
1394
                const char *path,
1395
                const char *interface,
1396
                const char *property,
1397
                sd_bus_message *reply,
1398
                void *userdata,
1399
                sd_bus_error *ret_error) {
1400

1401
        ExecCommand *c = (ExecCommand*) userdata;
234✔
1402
        int r;
234✔
1403

1404
        assert(bus);
234✔
1405
        assert(reply);
234✔
1406

1407
        r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
234✔
1408
        if (r < 0)
234✔
1409
                return r;
1410

1411
        r = append_exec_command(reply, c);
234✔
1412
        if (r < 0)
234✔
1413
                return r;
1414

1415
        return sd_bus_message_close_container(reply);
234✔
1416
}
1417

1418
int bus_property_get_exec_command_list(
7,968✔
1419
                sd_bus *bus,
1420
                const char *path,
1421
                const char *interface,
1422
                const char *property,
1423
                sd_bus_message *reply,
1424
                void *userdata,
1425
                sd_bus_error *ret_error) {
1426

1427
        ExecCommand *exec_command = *(ExecCommand**) userdata;
7,968✔
1428
        int r;
7,968✔
1429

1430
        assert(bus);
7,968✔
1431
        assert(reply);
7,968✔
1432

1433
        r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
7,968✔
1434
        if (r < 0)
7,968✔
1435
                return r;
1436

1437
        LIST_FOREACH(command, c, exec_command) {
9,191✔
1438
                r = append_exec_command(reply, c);
1,223✔
1439
                if (r < 0)
1,223✔
1440
                        return r;
1441
        }
1442

1443
        return sd_bus_message_close_container(reply);
7,968✔
1444
}
1445

1446
int bus_property_get_exec_ex_command_list(
7,560✔
1447
                sd_bus *bus,
1448
                const char *path,
1449
                const char *interface,
1450
                const char *property,
1451
                sd_bus_message *reply,
1452
                void *userdata,
1453
                sd_bus_error *ret_error) {
1454

1455
        ExecCommand *exec_command = *(ExecCommand**) userdata;
7,560✔
1456
        int r;
7,560✔
1457

1458
        assert(bus);
7,560✔
1459
        assert(reply);
7,560✔
1460

1461
        r = sd_bus_message_open_container(reply, 'a', "(sasasttttuii)");
7,560✔
1462
        if (r < 0)
7,560✔
1463
                return r;
1464

1465
        LIST_FOREACH(command, c, exec_command) {
8,783✔
1466
                r = append_exec_ex_command(reply, c);
1,223✔
1467
                if (r < 0)
1,223✔
1468
                        return r;
1469
        }
1470

1471
        return sd_bus_message_close_container(reply);
7,560✔
1472
}
1473

1474
static char *exec_command_flags_to_exec_chars(ExecCommandFlags flags) {
141✔
1475
        return strjoin(FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE)   ? "-" : "",
704✔
1476
                       FLAGS_SET(flags, EXEC_COMMAND_NO_ENV_EXPAND)    ? ":" : "",
1477
                       FLAGS_SET(flags, EXEC_COMMAND_FULLY_PRIVILEGED) ? "+" : "",
1478
                       FLAGS_SET(flags, EXEC_COMMAND_NO_SETUID)        ? "!" : "");
1479
}
1480

1481
int bus_set_transient_exec_command(
282✔
1482
                Unit *u,
1483
                const char *name,
1484
                ExecCommand **exec_command,
1485
                sd_bus_message *message,
1486
                UnitWriteFlags flags,
1487
                sd_bus_error *error) {
1488

1489
        const char *ex_prop = endswith(ASSERT_PTR(name), "Ex");
282✔
1490
        size_t n = 0;
282✔
1491
        int r;
282✔
1492

1493
        assert(u);
282✔
1494
        assert(exec_command);
282✔
1495
        assert(message);
282✔
1496
        assert(error);
282✔
1497

1498
        /* Drop Ex from the written setting. E.g. ExecStart=, not ExecStartEx=. */
1499
        const char *written_name = ex_prop ? strndupa_safe(name, ex_prop - name) : name;
282✔
1500

1501
        r = sd_bus_message_enter_container(message, 'a', ex_prop ? "(sasas)" : "(sasb)");
282✔
1502
        if (r < 0)
282✔
1503
                return r;
1504

1505
        while ((r = sd_bus_message_enter_container(message, 'r', ex_prop ? "sasas" : "sasb")) > 0) {
1,128✔
1506
                _cleanup_strv_free_ char **argv = NULL, **ex_opts = NULL;
282✔
1507
                const char *path;
282✔
1508
                int b;
282✔
1509

1510
                r = sd_bus_message_read(message, "s", &path);
282✔
1511
                if (r < 0)
282✔
1512
                        return r;
1513

1514
                if (!path_is_absolute(path) && !filename_is_valid(path))
282✔
1515
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1516
                                                 "\"%s\" is neither a valid executable name nor an absolute path",
1517
                                                 path);
1518

1519
                r = sd_bus_message_read_strv(message, &argv);
282✔
1520
                if (r < 0)
282✔
1521
                        return r;
1522

1523
                if (strv_isempty(argv))
282✔
1524
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1525
                                                 "\"%s\" argv cannot be empty", name);
1526

1527
                r = ex_prop ? sd_bus_message_read_strv(message, &ex_opts) : sd_bus_message_read(message, "b", &b);
282✔
1528
                if (r < 0)
282✔
1529
                        return r;
1530

1531
                r = sd_bus_message_exit_container(message);
282✔
1532
                if (r < 0)
282✔
1533
                        return r;
1534

1535
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
282✔
1536
                        _cleanup_(exec_command_freep) ExecCommand *c = NULL;
141✔
1537

1538
                        c = new(ExecCommand, 1);
141✔
1539
                        if (!c)
141✔
1540
                                return -ENOMEM;
1541

1542
                        *c = (ExecCommand) {
141✔
1543
                                .argv = TAKE_PTR(argv),
141✔
1544
                        };
1545

1546
                        r = path_simplify_alloc(path, &c->path);
141✔
1547
                        if (r < 0)
141✔
1548
                                return r;
1549

1550
                        if (ex_prop) {
141✔
1551
                                r = exec_command_flags_from_strv(ex_opts, &c->flags);
×
1552
                                if (r < 0)
×
1553
                                        return r;
1554
                        } else if (b)
141✔
1555
                                c->flags |= EXEC_COMMAND_IGNORE_FAILURE;
1✔
1556

1557
                        exec_command_append_list(exec_command, TAKE_PTR(c));
141✔
1558
                }
1559

1560
                n++;
282✔
1561
        }
1562
        if (r < 0)
282✔
1563
                return r;
1564

1565
        r = sd_bus_message_exit_container(message);
282✔
1566
        if (r < 0)
282✔
1567
                return r;
1568

1569
        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
282✔
1570
                _cleanup_(memstream_done) MemStream m = {};
×
1571
                _cleanup_free_ char *buf = NULL;
141✔
1572
                FILE *f;
141✔
1573

1574
                if (n == 0)
141✔
1575
                        *exec_command = exec_command_free_list(*exec_command);
×
1576

1577
                f = memstream_init(&m);
141✔
1578
                if (!f)
141✔
1579
                        return -ENOMEM;
1580

1581
                fprintf(f, "%s=\n", written_name);
141✔
1582

1583
                LIST_FOREACH(command, c, *exec_command) {
282✔
1584
                        _cleanup_free_ char *a = NULL, *exec_chars = NULL;
141✔
1585
                        UnitWriteFlags esc_flags = UNIT_ESCAPE_SPECIFIERS |
282✔
1586
                                (FLAGS_SET(c->flags, EXEC_COMMAND_NO_ENV_EXPAND) ? UNIT_ESCAPE_EXEC_SYNTAX : UNIT_ESCAPE_EXEC_SYNTAX_ENV);
141✔
1587

1588
                        exec_chars = exec_command_flags_to_exec_chars(c->flags);
141✔
1589
                        if (!exec_chars)
141✔
1590
                                return -ENOMEM;
1591

1592
                        a = unit_concat_strv(c->argv, esc_flags);
141✔
1593
                        if (!a)
141✔
1594
                                return -ENOMEM;
1595

1596
                        if (streq_ptr(c->path, c->argv ? c->argv[0] : NULL))
141✔
1597
                                fprintf(f, "%s=%s%s\n", written_name, exec_chars, a);
141✔
1598
                        else {
1599
                                _cleanup_free_ char *t = NULL;
×
1600
                                const char *p;
×
1601

1602
                                p = unit_escape_setting(c->path, esc_flags, &t);
×
1603
                                if (!p)
×
1604
                                        return -ENOMEM;
×
1605

1606
                                fprintf(f, "%s=%s@%s %s\n", written_name, exec_chars, p, a);
×
1607
                        }
1608
                }
1609

1610
                r = memstream_finalize(&m, &buf, NULL);
141✔
1611
                if (r < 0)
141✔
1612
                        return r;
1613

1614
                unit_write_setting(u, flags, written_name, buf);
141✔
1615
        }
1616

1617
        return 1;
1618
}
1619

1620
static int parse_personality(const char *s, unsigned long *p) {
×
1621
        unsigned long v;
×
1622

1623
        assert(p);
×
1624

1625
        v = personality_from_string(s);
×
1626
        if (v == PERSONALITY_INVALID)
×
1627
                return -EINVAL;
1628

1629
        *p = v;
×
1630
        return 0;
×
1631
}
1632

1633
static const char* mount_propagation_flag_to_string_with_check(unsigned long n) {
2✔
1634
        if (!mount_propagation_flag_is_valid(n))
2✔
1635
                return NULL;
1636

1637
        return mount_propagation_flag_to_string(n);
2✔
1638
}
1639

1640
static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
×
1641
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
×
1642
#if HAVE_SECCOMP
1643
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, seccomp_errno_or_action_is_valid);
×
1644
#endif
1645
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
×
1646
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
60✔
1647
static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
×
1648
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
2✔
1649
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
6✔
1650
static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
×
1651
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string);
10✔
1652
static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string);
6✔
1653
BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
10✔
1654
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
×
1655
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
×
1656
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string);
10✔
1657
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
20✔
1658
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_propagation_flag, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flag_to_string_with_check);
2✔
1659

1660
int bus_exec_context_set_transient_property(
1,114✔
1661
                Unit *u,
1662
                ExecContext *c,
1663
                const char *name,
1664
                sd_bus_message *message,
1665
                UnitWriteFlags flags,
1666
                sd_bus_error *error) {
1667

1668
        const char *suffix;
1,114✔
1669
        int r;
1,114✔
1670

1671
        assert(u);
1,114✔
1672
        assert(c);
1,114✔
1673
        assert(name);
1,114✔
1674
        assert(message);
1,114✔
1675

1676
        flags |= UNIT_PRIVATE;
1,114✔
1677

1678
        if (streq(name, "User"))
1,114✔
1679
                return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error);
26✔
1680

1681
        if (streq(name, "Group"))
1,088✔
1682
                return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error);
4✔
1683

1684
        if (streq(name, "SetLoginEnvironment"))
1,084✔
1685
                return bus_set_transient_tristate(u, name, &c->set_login_environment, message, flags, error);
×
1686

1687
        if (streq(name, "TTYPath"))
1,084✔
1688
                return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
×
1689

1690
        if (streq(name, "RootImage"))
1,084✔
1691
                return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
2✔
1692

1693
        if (streq(name, "RootImageOptions")) {
1,082✔
1694
                _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
1695
                _cleanup_free_ char *format_str = NULL;
×
1696

1697
                r = bus_read_mount_options(message, error, &options, &format_str, " ");
×
1698
                if (r < 0)
×
1699
                        return r;
1700

1701
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1702
                        if (options) {
×
1703
                                LIST_JOIN(mount_options, c->root_image_options, options);
×
1704
                                unit_write_settingf(
×
1705
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
1706
                                                "%s=%s",
1707
                                                name,
1708
                                                format_str);
1709
                        } else {
1710
                                c->root_image_options = mount_options_free_all(c->root_image_options);
×
1711
                                unit_write_settingf(u, flags, name, "%s=", name);
×
1712
                        }
1713
                }
1714

1715
                return 1;
×
1716
        }
1717

1718
        if (streq(name, "RootHash")) {
1,082✔
1719
                const void *roothash_decoded;
×
1720
                size_t roothash_decoded_size;
×
1721

1722
                r = sd_bus_message_read_array(message, 'y', &roothash_decoded, &roothash_decoded_size);
×
1723
                if (r < 0)
×
1724
                        return r;
×
1725

1726
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1727
                        _cleanup_free_ char *encoded = NULL;
×
1728

1729
                        if (roothash_decoded_size == 0) {
×
1730
                                c->root_hash_path = mfree(c->root_hash_path);
×
1731
                                c->root_hash = mfree(c->root_hash);
×
1732
                                c->root_hash_size = 0;
×
1733

1734
                                unit_write_settingf(u, flags, name, "RootHash=");
×
1735
                        } else {
1736
                                _cleanup_free_ void *p = NULL;
×
1737

1738
                                encoded = hexmem(roothash_decoded, roothash_decoded_size);
×
1739
                                if (!encoded)
×
1740
                                        return -ENOMEM;
1741

1742
                                p = memdup(roothash_decoded, roothash_decoded_size);
×
1743
                                if (!p)
×
1744
                                        return -ENOMEM;
1745

1746
                                free_and_replace(c->root_hash, p);
×
1747
                                c->root_hash_size = roothash_decoded_size;
×
1748
                                c->root_hash_path = mfree(c->root_hash_path);
×
1749

1750
                                unit_write_settingf(u, flags, name, "RootHash=%s", encoded);
×
1751
                        }
1752
                }
1753

1754
                return 1;
×
1755
        }
1756

1757
        if (streq(name, "RootHashPath")) {
1,082✔
1758
                c->root_hash_size = 0;
×
1759
                c->root_hash = mfree(c->root_hash);
×
1760

1761
                return bus_set_transient_path(u, "RootHash", &c->root_hash_path, message, flags, error);
×
1762
        }
1763

1764
        if (streq(name, "RootHashSignature")) {
1,082✔
1765
                const void *roothash_sig_decoded;
×
1766
                size_t roothash_sig_decoded_size;
×
1767

1768
                r = sd_bus_message_read_array(message, 'y', &roothash_sig_decoded, &roothash_sig_decoded_size);
×
1769
                if (r < 0)
×
1770
                        return r;
×
1771

1772
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1773
                        _cleanup_free_ char *encoded = NULL;
×
1774

1775
                        if (roothash_sig_decoded_size == 0) {
×
1776
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1777
                                c->root_hash_sig = mfree(c->root_hash_sig);
×
1778
                                c->root_hash_sig_size = 0;
×
1779

1780
                                unit_write_settingf(u, flags, name, "RootHashSignature=");
×
1781
                        } else {
1782
                                _cleanup_free_ void *p = NULL;
×
1783
                                ssize_t len;
×
1784

1785
                                len = base64mem(roothash_sig_decoded, roothash_sig_decoded_size, &encoded);
×
1786
                                if (len < 0)
×
1787
                                        return -ENOMEM;
1788

1789
                                p = memdup(roothash_sig_decoded, roothash_sig_decoded_size);
×
1790
                                if (!p)
×
1791
                                        return -ENOMEM;
1792

1793
                                free_and_replace(c->root_hash_sig, p);
×
1794
                                c->root_hash_sig_size = roothash_sig_decoded_size;
×
1795
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1796

1797
                                unit_write_settingf(u, flags, name, "RootHashSignature=base64:%s", encoded);
×
1798
                        }
1799
                }
1800

1801
                return 1;
×
1802
        }
1803

1804
        if (streq(name, "RootHashSignaturePath")) {
1,082✔
1805
                c->root_hash_sig_size = 0;
×
1806
                c->root_hash_sig = mfree(c->root_hash_sig);
×
1807

1808
                return bus_set_transient_path(u, "RootHashSignature", &c->root_hash_sig_path, message, flags, error);
×
1809
        }
1810

1811
        if (streq(name, "RootVerity"))
1,082✔
1812
                return bus_set_transient_path(u, name, &c->root_verity, message, flags, error);
×
1813

1814
        if (streq(name, "RootDirectory"))
1,082✔
1815
                return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
8✔
1816

1817
        if (streq(name, "RootEphemeral"))
1,074✔
1818
                return bus_set_transient_bool(u, name, &c->root_ephemeral, message, flags, error);
×
1819

1820
        if (streq(name, "SyslogIdentifier"))
1,074✔
1821
                return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
×
1822

1823
        if (streq(name, "LogLevelMax"))
1,074✔
1824
                return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
×
1825

1826
        if (streq(name, "LogRateLimitIntervalUSec"))
1,074✔
1827
                return bus_set_transient_usec(u, name, &c->log_ratelimit.interval, message, flags, error);
×
1828

1829
        if (streq(name, "LogRateLimitBurst"))
1,074✔
1830
                return bus_set_transient_unsigned(u, name, &c->log_ratelimit.burst, message, flags, error);
×
1831

1832
        if (streq(name, "LogFilterPatterns")) {
1,074✔
1833
                /* Use _cleanup_free_, not _cleanup_strv_free_, as we don't want the content of the strv
1834
                 * to be freed. */
1835
                _cleanup_free_ char **allow_list = NULL, **deny_list = NULL;
×
1836
                const char *pattern;
×
1837
                int is_allowlist;
×
1838

1839
                r = sd_bus_message_enter_container(message, 'a', "(bs)");
×
1840
                if (r < 0)
×
1841
                        return r;
1842

1843
                while ((r = sd_bus_message_read(message, "(bs)", &is_allowlist, &pattern)) > 0) {
×
1844
                        _cleanup_(pattern_freep) pcre2_code *compiled_pattern = NULL;
×
1845

1846
                        if (isempty(pattern))
×
1847
                                continue;
×
1848

1849
                        r = pattern_compile_and_log(pattern, 0, &compiled_pattern);
×
1850
                        if (r < 0)
×
1851
                                return r;
1852

1853
                        r = strv_push(is_allowlist ? &allow_list : &deny_list, (char *)pattern);
×
1854
                        if (r < 0)
×
1855
                                return r;
1856
                }
1857
                if (r < 0)
×
1858
                        return r;
1859

1860
                r = sd_bus_message_exit_container(message);
×
1861
                if (r < 0)
×
1862
                        return r;
1863

1864
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1865
                        if (strv_isempty(allow_list) && strv_isempty(deny_list)) {
×
1866
                                c->log_filter_allowed_patterns = set_free(c->log_filter_allowed_patterns);
×
1867
                                c->log_filter_denied_patterns = set_free(c->log_filter_denied_patterns);
×
1868
                                unit_write_settingf(u, flags, name, "%s=", name);
×
1869
                        } else {
1870
                                r = set_put_strdupv(&c->log_filter_allowed_patterns, allow_list);
×
1871
                                if (r < 0)
×
1872
                                        return r;
1873
                                r = set_put_strdupv(&c->log_filter_denied_patterns, deny_list);
×
1874
                                if (r < 0)
×
1875
                                        return r;
1876

1877
                                STRV_FOREACH(unit_pattern, allow_list)
×
1878
                                        unit_write_settingf(u, flags, name, "%s=%s", name, *unit_pattern);
×
1879
                                STRV_FOREACH(unit_pattern, deny_list)
×
1880
                                        unit_write_settingf(u, flags, name, "%s=~%s", name, *unit_pattern);
×
1881
                        }
1882
                }
1883

1884
                return 1;
×
1885
        }
1886

1887
        if (streq(name, "Personality"))
1,074✔
1888
                return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
×
1889

1890
        if (streq(name, "StandardInput"))
1,074✔
1891
                return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
×
1892

1893
        if (streq(name, "StandardOutput"))
1,074✔
1894
                return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
30✔
1895

1896
        if (streq(name, "StandardError"))
1,044✔
1897
                return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
30✔
1898

1899
        if (streq(name, "IgnoreSIGPIPE"))
1,014✔
1900
                return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
×
1901

1902
        if (streq(name, "TTYVHangup"))
1,014✔
1903
                return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
×
1904

1905
        if (streq(name, "TTYReset"))
1,014✔
1906
                return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
×
1907

1908
        if (streq(name, "TTYVTDisallocate"))
1,014✔
1909
                return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
×
1910

1911
        if (streq(name, "TTYRows"))
1,014✔
1912
                return bus_set_transient_unsigned(u, name, &c->tty_rows, message, flags, error);
×
1913

1914
        if (streq(name, "TTYColumns"))
1,014✔
1915
                return bus_set_transient_unsigned(u, name, &c->tty_cols, message, flags, error);
×
1916

1917
        if (streq(name, "PrivateTmp")) {
1,014✔
1918
                int v;
10✔
1919

1920
                r = sd_bus_message_read(message, "b", &v);
10✔
1921
                if (r < 0)
10✔
1922
                        return r;
10✔
1923

1924
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
10✔
1925
                        c->private_tmp = v ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_NO;
5✔
1926
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
5✔
1927
                }
1928

1929
                return 1;
10✔
1930

1931
        } else if (streq(name, "PrivateTmpEx")) {
1,004✔
1932
                const char *s;
×
1933
                PrivateTmp t;
×
1934

1935
                r = sd_bus_message_read(message, "s", &s);
×
1936
                if (r < 0)
×
1937
                        return r;
×
1938

1939
                t = private_tmp_from_string(s);
×
1940
                if (t < 0)
×
1941
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
1942

1943
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1944
                        c->private_tmp = t;
×
1945
                        (void) unit_write_settingf(u, flags, name, "PrivateTmp=%s",
×
1946
                                                   private_tmp_to_string(c->private_tmp));
1947
                }
1948

1949
                return 1;
×
1950
        }
1951

1952
        if (streq(name, "PrivateUsers")) {
1,004✔
1953
                int v;
8✔
1954

1955
                r = sd_bus_message_read(message, "b", &v);
8✔
1956
                if (r < 0)
8✔
1957
                        return r;
8✔
1958

1959
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
1960
                        c->private_users = v ? PRIVATE_USERS_SELF : PRIVATE_USERS_NO;
4✔
1961
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
4✔
1962
                }
1963

1964
                return 1;
8✔
1965

1966
        } else if (streq(name, "PrivateUsersEx")) {
996✔
1967
                const char *s;
18✔
1968
                PrivateUsers t;
18✔
1969

1970
                r = sd_bus_message_read(message, "s", &s);
18✔
1971
                if (r < 0)
18✔
1972
                        return r;
18✔
1973

1974
                t = private_users_from_string(s);
18✔
1975
                if (t < 0)
18✔
1976
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
1977

1978
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
18✔
1979
                        c->private_users = t;
9✔
1980
                        (void) unit_write_settingf(u, flags, name, "PrivateUsers=%s",
9✔
1981
                                                   private_users_to_string(c->private_users));
1982
                }
1983

1984
                return 1;
18✔
1985
        }
1986

1987
        if (streq(name, "ProtectControlGroups")) {
978✔
1988
                int v;
×
1989

1990
                r = sd_bus_message_read(message, "b", &v);
×
1991
                if (r < 0)
×
1992
                        return r;
×
1993

1994
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1995
                        c->protect_control_groups = v ? PROTECT_CONTROL_GROUPS_YES : PROTECT_CONTROL_GROUPS_NO;
×
1996
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
×
1997
                }
1998

1999
                return 1;
×
2000
        }
2001

2002
        if (streq(name, "ProtectControlGroupsEx")) {
978✔
2003
                const char *s;
2✔
2004
                ProtectControlGroups t;
2✔
2005

2006
                r = sd_bus_message_read(message, "s", &s);
2✔
2007
                if (r < 0)
2✔
2008
                        return r;
2✔
2009

2010
                t = protect_control_groups_from_string(s);
2✔
2011
                if (t < 0)
2✔
2012
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2013

2014
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2015
                        c->protect_control_groups = t;
1✔
2016
                        (void) unit_write_settingf(u, flags, name, "ProtectControlGroups=%s",
1✔
2017
                                                   protect_control_groups_to_string(c->protect_control_groups));
2018
                }
2019

2020
                return 1;
2✔
2021
        }
2022

2023
        if (streq(name, "PrivatePIDs")) {
976✔
2024
                const char *s;
8✔
2025
                PrivatePIDs t;
8✔
2026

2027
                r = sd_bus_message_read(message, "s", &s);
8✔
2028
                if (r < 0)
8✔
2029
                        return r;
8✔
2030

2031
                t = private_pids_from_string(s);
8✔
2032
                if (t < 0)
8✔
2033
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2034

2035
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
2036
                        c->private_pids = t;
4✔
2037
                        (void) unit_write_settingf(u, flags, name, "%s=%s",
4✔
2038
                                                   name, private_pids_to_string(c->private_pids));
2039
                }
2040

2041
                return 1;
8✔
2042
        }
2043

2044
        if (streq(name, "ProtectHostname")) {
968✔
2045
                int v;
4✔
2046

2047
                r = sd_bus_message_read(message, "b", &v);
4✔
2048
                if (r < 0)
4✔
2049
                        return r;
4✔
2050

2051
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2052
                        c->protect_hostname = v ? PROTECT_HOSTNAME_YES : PROTECT_HOSTNAME_NO;
2✔
2053
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
2✔
2054
                }
2055

2056
                return 1;
4✔
2057

2058
        }
2059

2060
        if (streq(name, "ProtectHostnameEx")) {
964✔
2061
                const char *s, *h = NULL;
4✔
2062

2063
                r = sd_bus_message_read(message, "(ss)", &s, &h);
4✔
2064
                if (r < 0)
4✔
2065
                        return r;
4✔
2066

2067
                if (!isempty(h) && !hostname_is_valid(h, /* flags = */ 0))
4✔
2068
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname in %s setting: %s", name, h);
×
2069

2070
                ProtectHostname t = protect_hostname_from_string(s);
4✔
2071
                if (t < 0 || (t == PROTECT_HOSTNAME_NO && !isempty(h)))
4✔
2072
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2073

2074
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2075
                        c->protect_hostname = t;
2✔
2076
                        r = free_and_strdup(&c->private_hostname, empty_to_null(h));
4✔
2077
                        if (r < 0)
2✔
2078
                                return r;
2079

2080
                        (void) unit_write_settingf(u, flags, name, "ProtectHostname=%s%s%s",
4✔
2081
                                                   protect_hostname_to_string(c->protect_hostname),
2082
                                                   c->private_hostname ? ":" : "",
2083
                                                   strempty(c->private_hostname));
2✔
2084
                }
2085

2086
                return 1;
4✔
2087
        }
2088

2089
        if (streq(name, "PrivateDevices"))
960✔
2090
                return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
4✔
2091

2092
        if (streq(name, "PrivateMounts"))
956✔
2093
                return bus_set_transient_tristate(u, name, &c->private_mounts, message, flags, error);
20✔
2094

2095
        if (streq(name, "MountAPIVFS"))
936✔
2096
                return bus_set_transient_tristate(u, name, &c->mount_apivfs, message, flags, error);
4✔
2097

2098
        if (streq(name, "BindLogSockets"))
932✔
2099
                return bus_set_transient_tristate(u, name, &c->bind_log_sockets, message, flags, error);
×
2100

2101
        if (streq(name, "PrivateNetwork"))
932✔
2102
                return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
8✔
2103

2104
        if (streq(name, "PrivateIPC"))
924✔
2105
                return bus_set_transient_bool(u, name, &c->private_ipc, message, flags, error);
4✔
2106

2107
        if (streq(name, "NoNewPrivileges"))
920✔
2108
                return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
2✔
2109

2110
        if (streq(name, "SyslogLevelPrefix"))
918✔
2111
                return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
×
2112

2113
        if (streq(name, "MemoryDenyWriteExecute"))
918✔
2114
                return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
×
2115

2116
        if (streq(name, "RestrictRealtime"))
918✔
2117
                return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
×
2118

2119
        if (streq(name, "RestrictSUIDSGID"))
918✔
2120
                return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
×
2121

2122
        if (streq(name, "DynamicUser"))
918✔
2123
                return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
2✔
2124

2125
        if (streq(name, "RemoveIPC"))
916✔
2126
                return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
×
2127

2128
        if (streq(name, "ProtectKernelTunables"))
916✔
2129
                return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
4✔
2130

2131
        if (streq(name, "ProtectKernelModules"))
912✔
2132
                return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
4✔
2133

2134
        if (streq(name, "ProtectKernelLogs"))
908✔
2135
                return bus_set_transient_bool(u, name, &c->protect_kernel_logs, message, flags, error);
2✔
2136

2137
        if (streq(name, "ProtectClock"))
906✔
2138
                return bus_set_transient_bool(u, name, &c->protect_clock, message, flags, error);
4✔
2139

2140
        if (streq(name, "CPUSchedulingResetOnFork"))
902✔
2141
                return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
×
2142

2143
        if (streq(name, "NonBlocking"))
902✔
2144
                return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
×
2145

2146
        if (streq(name, "LockPersonality"))
902✔
2147
                return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
2✔
2148

2149
        if (streq(name, "MemoryKSM"))
900✔
2150
                return bus_set_transient_tristate(u, name, &c->memory_ksm, message, flags, error);
×
2151

2152
        if (streq(name, "UtmpIdentifier"))
900✔
2153
                return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
×
2154

2155
        if (streq(name, "UtmpMode"))
900✔
2156
                return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
×
2157

2158
        if (streq(name, "PAMName"))
900✔
2159
                return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
10✔
2160

2161
        if (streq(name, "TimerSlackNSec"))
890✔
2162
                return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
×
2163

2164
        if (streq(name, "ProtectSystem"))
890✔
2165
                return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
2✔
2166

2167
        if (streq(name, "ProtectHome"))
888✔
2168
                return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
6✔
2169

2170
        if (streq(name, "KeyringMode"))
882✔
2171
                return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
×
2172

2173
        if (streq(name, "ProtectProc"))
882✔
2174
                return bus_set_transient_protect_proc(u, name, &c->protect_proc, message, flags, error);
10✔
2175

2176
        if (streq(name, "ProcSubset"))
872✔
2177
                return bus_set_transient_proc_subset(u, name, &c->proc_subset, message, flags, error);
6✔
2178

2179
        if (streq(name, "RuntimeDirectoryPreserve"))
866✔
2180
                return bus_set_transient_exec_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
10✔
2181

2182
        if (streq(name, "UMask"))
856✔
2183
                return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
×
2184

2185
        if (streq(name, "RuntimeDirectoryMode"))
856✔
2186
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
×
2187

2188
        if (streq(name, "StateDirectoryMode"))
856✔
2189
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
10✔
2190

2191
        if (streq(name, "CacheDirectoryMode"))
846✔
2192
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
20✔
2193

2194
        if (streq(name, "LogsDirectoryMode"))
826✔
2195
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
×
2196

2197
        if (streq(name, "ConfigurationDirectoryMode"))
826✔
2198
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
10✔
2199

2200
        if (streq(name, "SELinuxContext"))
816✔
2201
                return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
×
2202

2203
        if (streq(name, "SecureBits"))
816✔
2204
                return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
×
2205

2206
        if (streq(name, "CapabilityBoundingSet"))
816✔
2207
                return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
2✔
2208

2209
        if (streq(name, "AmbientCapabilities"))
814✔
2210
                return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
8✔
2211

2212
        if (streq(name, "RestrictNamespaces"))
806✔
2213
                return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
×
2214

2215
        if (streq(name, "DelegateNamespaces"))
806✔
2216
                return bus_set_transient_namespace_flag(u, name, &c->delegate_namespaces, message, flags, error);
18✔
2217

2218
        if (streq(name, "RestrictFileSystems")) {
788✔
2219
                int allow_list;
×
2220
                _cleanup_strv_free_ char **l = NULL;
×
2221

2222
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2223
                if (r < 0)
×
2224
                        return r;
2225

2226
                r = sd_bus_message_read(message, "b", &allow_list);
×
2227
                if (r < 0)
×
2228
                        return r;
2229

2230
                r = sd_bus_message_read_strv(message, &l);
×
2231
                if (r < 0)
×
2232
                        return r;
2233

2234
                r = sd_bus_message_exit_container(message);
×
2235
                if (r < 0)
×
2236
                        return r;
2237

2238
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2239
                        _cleanup_free_ char *joined = NULL;
×
2240
                        FilesystemParseFlags invert_flag = allow_list ? 0 : FILESYSTEM_PARSE_INVERT;
×
2241

2242
                        if (strv_isempty(l)) {
×
2243
                                c->restrict_filesystems_allow_list = false;
×
2244
                                c->restrict_filesystems = set_free(c->restrict_filesystems);
×
2245

2246
                                unit_write_setting(u, flags, name, "RestrictFileSystems=");
×
2247
                                return 1;
2248
                        }
2249

2250
                        if (!c->restrict_filesystems)
×
2251
                                c->restrict_filesystems_allow_list = allow_list;
×
2252

2253
                        STRV_FOREACH(s, l) {
×
2254
                                r = bpf_restrict_fs_parse_filesystem(
×
2255
                                              *s,
2256
                                              &c->restrict_filesystems,
2257
                                              FILESYSTEM_PARSE_LOG|
×
2258
                                              (invert_flag ? FILESYSTEM_PARSE_INVERT : 0)|
×
2259
                                              (c->restrict_filesystems_allow_list ? FILESYSTEM_PARSE_ALLOW_LIST : 0),
×
2260
                                              u->id, NULL, 0);
×
2261
                                if (r < 0)
×
2262
                                        return r;
2263
                        }
2264

2265
                        joined = strv_join(l, " ");
×
2266
                        if (!joined)
×
2267
                                return -ENOMEM;
2268

2269
                        unit_write_settingf(u, flags, name, "%s=%s%s", name, allow_list ? "" : "~", joined);
×
2270
                }
2271

2272
                return 1;
×
2273
        }
2274

2275
        if (streq(name, "MountFlags"))
788✔
2276
                return bus_set_transient_mount_propagation_flag(u, name, &c->mount_propagation_flag, message, flags, error);
2✔
2277

2278
        if (streq(name, "NetworkNamespacePath"))
786✔
2279
                return bus_set_transient_path(u, name, &c->network_namespace_path, message, flags, error);
×
2280

2281
        if (streq(name, "IPCNamespacePath"))
786✔
2282
                return bus_set_transient_path(u, name, &c->ipc_namespace_path, message, flags, error);
×
2283

2284
        if (streq(name, "SupplementaryGroups")) {
786✔
2285
                _cleanup_strv_free_ char **l = NULL;
×
2286

2287
                r = sd_bus_message_read_strv(message, &l);
×
2288
                if (r < 0)
×
2289
                        return r;
2290

2291
                STRV_FOREACH(p, l)
×
2292
                        if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN))
×
2293
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
2294
                                                         "Invalid supplementary group names");
2295

2296
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2297
                        if (strv_isempty(l)) {
×
2298
                                c->supplementary_groups = strv_free(c->supplementary_groups);
×
2299
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2300
                        } else {
2301
                                _cleanup_free_ char *joined = NULL;
×
2302

2303
                                r = strv_extend_strv(&c->supplementary_groups, l, true);
×
2304
                                if (r < 0)
×
2305
                                        return r;
2306

2307
                                joined = strv_join(c->supplementary_groups, " ");
×
2308
                                if (!joined)
×
2309
                                        return -ENOMEM;
2310

2311
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
×
2312
                        }
2313
                }
2314

2315
                return 1;
×
2316

2317
        } else if (STR_IN_SET(name, "SetCredential", "SetCredentialEncrypted")) {
786✔
2318
                bool isempty = true;
×
2319

2320
                r = sd_bus_message_enter_container(message, 'a', "(say)");
×
2321
                if (r < 0)
×
2322
                        return r;
4✔
2323

2324
                for (;;) {
×
2325
                        const char *id;
×
2326
                        const void *p;
×
2327
                        size_t sz;
×
2328

2329
                        r = sd_bus_message_enter_container(message, 'r', "say");
×
2330
                        if (r < 0)
×
2331
                                return r;
×
2332
                        if (r == 0)
×
2333
                                break;
2334

2335
                        r = sd_bus_message_read(message, "s", &id);
×
2336
                        if (r < 0)
×
2337
                                return r;
2338

2339
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2340
                        if (r < 0)
×
2341
                                return r;
2342

2343
                        r = sd_bus_message_exit_container(message);
×
2344
                        if (r < 0)
×
2345
                                return r;
2346

2347
                        if (!credential_name_valid(id))
×
2348
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2349

2350
                        isempty = false;
×
2351

2352
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2353
                                bool encrypted = endswith(name, "Encrypted");
×
2354
                                _cleanup_free_ char *a = NULL, *b = NULL;
×
2355
                                _cleanup_free_ void *copy = NULL;
×
2356

2357
                                copy = memdup(p, sz);
×
2358
                                if (!copy)
×
2359
                                        return -ENOMEM;
2360

2361
                                a = specifier_escape(id);
×
2362
                                if (!a)
×
2363
                                        return -ENOMEM;
2364

2365
                                b = cescape_length(p, sz);
×
2366
                                if (!b)
×
2367
                                        return -ENOMEM;
2368

2369
                                r = exec_context_put_set_credential(c, id, TAKE_PTR(copy), sz, encrypted);
×
2370
                                if (r < 0)
×
2371
                                        return r;
2372

2373
                                (void) unit_write_settingf(u, flags, name, "%s=%s:%s", name, a, b);
×
2374
                        }
2375
                }
2376

2377
                r = sd_bus_message_exit_container(message);
×
2378
                if (r < 0)
×
2379
                        return r;
2380

2381
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
×
2382
                        c->set_credentials = hashmap_free(c->set_credentials);
×
2383
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2384
                }
2385

2386
                return 1;
×
2387

2388
        } else if (STR_IN_SET(name, "LoadCredential", "LoadCredentialEncrypted")) {
786✔
2389
                bool isempty = true;
2✔
2390

2391
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
2✔
2392
                if (r < 0)
2✔
2393
                        return r;
4✔
2394

2395
                for (;;) {
2✔
2396
                        const char *id, *source;
4✔
2397

2398
                        r = sd_bus_message_read(message, "(ss)", &id, &source);
4✔
2399
                        if (r < 0)
4✔
2400
                                return r;
×
2401
                        if (r == 0)
4✔
2402
                                break;
2403

2404
                        if (!credential_name_valid(id))
2✔
2405
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2406

2407
                        if (!(path_is_absolute(source) ? path_is_normalized(source) : credential_name_valid(source)))
2✔
2408
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential source is invalid: %s", source);
×
2409

2410
                        isempty = false;
2✔
2411

2412
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2413
                                bool encrypted = endswith(name, "Encrypted");
1✔
2414

2415
                                r = exec_context_put_load_credential(c, id, source, encrypted);
1✔
2416
                                if (r < 0)
1✔
2417
                                        return r;
2418

2419
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s:%s", name, id, source);
1✔
2420
                        }
2421
                }
2422

2423
                r = sd_bus_message_exit_container(message);
2✔
2424
                if (r < 0)
2✔
2425
                        return r;
2426

2427
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
2✔
2428
                        c->load_credentials = hashmap_free(c->load_credentials);
×
2429
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2430
                }
2431

2432
                return 1;
2✔
2433

2434
        } else if (STR_IN_SET(name, "ImportCredential", "ImportCredentialEx")) {
784✔
2435
                bool empty = true, ex = streq(name, "ImportCredentialEx");
2✔
2436

2437
                r = sd_bus_message_enter_container(message, 'a', ex ? "(ss)" : "s");
4✔
2438
                if (r < 0)
2✔
2439
                        return r;
2✔
2440

2441
                for (;;) {
2✔
2442
                        const char *glob, *rename = NULL;
4✔
2443

2444
                        if (ex)
4✔
2445
                                r = sd_bus_message_read(message, "(ss)", &glob, &rename);
×
2446
                        else
2447
                                r = sd_bus_message_read(message, "s", &glob);
4✔
2448
                        if (r < 0)
4✔
2449
                                return r;
×
2450
                        if (r == 0)
4✔
2451
                                break;
2452

2453
                        if (!credential_glob_valid(glob))
2✔
2454
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential name or glob is invalid: %s", glob);
×
2455

2456
                        rename = empty_to_null(rename);
2✔
2457

2458
                        if (rename && !credential_name_valid(rename))
2✔
2459
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential name is invalid: %s", rename);
×
2460

2461
                        empty = false;
2✔
2462

2463
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2464
                                r = exec_context_put_import_credential(c, glob, rename);
1✔
2465
                                if (r < 0)
1✔
2466
                                        return r;
2467

2468
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
3✔
2469
                                                           "ImportCredential=%s%s%s",
2470
                                                           glob, rename ? ":" : "", strempty(rename));
2471
                        }
2472
                }
2473

2474
                r = sd_bus_message_exit_container(message);
2✔
2475
                if (r < 0)
2✔
2476
                        return r;
2477

2478
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
2✔
2479
                        c->import_credentials = ordered_set_free(c->import_credentials);
×
2480
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2481
                }
2482

2483
                return 1;
2✔
2484

2485
        } else if (streq(name, "SyslogLevel")) {
782✔
2486
                int32_t level;
×
2487

2488
                r = sd_bus_message_read(message, "i", &level);
×
2489
                if (r < 0)
×
2490
                        return r;
×
2491

2492
                if (!log_level_is_valid(level))
×
2493
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
×
2494

2495
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2496
                        c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
×
2497
                        unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
×
2498
                }
2499

2500
                return 1;
×
2501

2502
        } else if (streq(name, "SyslogFacility")) {
782✔
2503
                int32_t facility;
×
2504

2505
                r = sd_bus_message_read(message, "i", &facility);
×
2506
                if (r < 0)
×
2507
                        return r;
×
2508

2509
                if (!log_facility_unshifted_is_valid(facility))
×
2510
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
×
2511

2512
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2513
                        c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
×
2514
                        unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
×
2515
                }
2516

2517
                return 1;
×
2518

2519
        } else if (streq(name, "LogNamespace")) {
782✔
2520
                const char *n;
×
2521

2522
                r = sd_bus_message_read(message, "s", &n);
×
2523
                if (r < 0)
×
2524
                        return r;
×
2525

2526
                if (!isempty(n) && !log_namespace_name_valid(n))
×
2527
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log namespace name not valid");
×
2528

2529
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2530

2531
                        if (isempty(n)) {
×
2532
                                c->log_namespace = mfree(c->log_namespace);
×
2533
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2534
                        } else {
2535
                                r = free_and_strdup(&c->log_namespace, n);
×
2536
                                if (r < 0)
×
2537
                                        return r;
2538

2539
                                unit_write_settingf(u, flags, name, "%s=%s", name, n);
×
2540
                        }
2541
                }
2542

2543
                return 1;
×
2544

2545
        } else if (streq(name, "LogExtraFields")) {
782✔
2546
                size_t n = 0;
×
2547

2548
                r = sd_bus_message_enter_container(message, 'a', "ay");
×
2549
                if (r < 0)
×
2550
                        return r;
2551

2552
                for (;;) {
×
2553
                        _cleanup_free_ void *copy = NULL;
×
2554
                        const char *eq;
×
2555
                        const void *p;
×
2556
                        size_t sz;
×
2557

2558
                        /* Note that we expect a byte array for each field, instead of a string. That's because on the
2559
                         * lower-level journal fields can actually contain binary data and are not restricted to text,
2560
                         * and we should not "lose precision" in our types on the way. That said, I am pretty sure
2561
                         * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
2562
                         * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
2563
                         * limitation, should a good, valid use case arise. */
2564

2565
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2566
                        if (r < 0)
×
2567
                                return r;
2568
                        if (r == 0)
×
2569
                                break;
2570

2571
                        if (memchr(p, 0, sz))
×
2572
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
×
2573

2574
                        eq = memchr(p, '=', sz);
×
2575
                        if (!eq)
×
2576
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
×
2577
                        if (!journal_field_valid(p, eq - (const char*) p, false))
×
2578
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
×
2579

2580
                        copy = memdup_suffix0(p, sz);
×
2581
                        if (!copy)
×
2582
                                return -ENOMEM;
2583

2584
                        if (!utf8_is_valid(copy))
×
2585
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
×
2586

2587
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2588
                                if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
×
2589
                                        return -ENOMEM;
2590

2591
                                c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
×
2592
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
×
2593
                                TAKE_PTR(copy);
2594
                        }
2595

2596
                        n++;
×
2597
                }
2598

2599
                r = sd_bus_message_exit_container(message);
×
2600
                if (r < 0)
×
2601
                        return r;
2602

2603
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
×
2604
                        exec_context_free_log_extra_fields(c);
×
2605
                        unit_write_setting(u, flags, name, "LogExtraFields=");
×
2606
                }
2607

2608
                return 1;
×
2609
        }
2610

2611
#if HAVE_SECCOMP
2612

2613
        if (streq(name, "SystemCallErrorNumber"))
782✔
2614
                return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
×
2615

2616
        if (streq(name, "SystemCallFilter")) {
782✔
2617
                int allow_list;
×
2618
                _cleanup_strv_free_ char **l = NULL;
×
2619

2620
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2621
                if (r < 0)
×
2622
                        return r;
2623

2624
                r = sd_bus_message_read(message, "b", &allow_list);
×
2625
                if (r < 0)
×
2626
                        return r;
2627

2628
                r = sd_bus_message_read_strv(message, &l);
×
2629
                if (r < 0)
×
2630
                        return r;
2631

2632
                r = sd_bus_message_exit_container(message);
×
2633
                if (r < 0)
×
2634
                        return r;
2635

2636
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2637
                        _cleanup_free_ char *joined = NULL;
×
2638
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2639

2640
                        if (strv_isempty(l)) {
×
2641
                                c->syscall_allow_list = false;
×
2642
                                c->syscall_filter = hashmap_free(c->syscall_filter);
×
2643

2644
                                unit_write_settingf(u, flags, name, "SystemCallFilter=");
×
2645
                                return 1;
2646
                        }
2647

2648
                        if (!c->syscall_filter) {
×
2649
                                c->syscall_filter = hashmap_new(NULL);
×
2650
                                if (!c->syscall_filter)
×
2651
                                        return log_oom();
×
2652

2653
                                c->syscall_allow_list = allow_list;
×
2654

2655
                                if (c->syscall_allow_list) {
×
2656
                                        r = seccomp_parse_syscall_filter("@default",
×
2657
                                                                         -1,
2658
                                                                         c->syscall_filter,
2659
                                                                         SECCOMP_PARSE_PERMISSIVE |
2660
                                                                         SECCOMP_PARSE_ALLOW_LIST,
2661
                                                                         u->id,
×
2662
                                                                         NULL, 0);
2663
                                        if (r < 0)
×
2664
                                                return r;
2665
                                }
2666
                        }
2667

2668
                        STRV_FOREACH(s, l) {
×
2669
                                _cleanup_free_ char *n = NULL;
×
2670
                                int e;
×
2671

2672
                                r = parse_syscall_and_errno(*s, &n, &e);
×
2673
                                if (r < 0)
×
2674
                                        return r;
2675

2676
                                if (allow_list && e >= 0)
×
2677
                                        return -EINVAL;
2678

2679
                                r = seccomp_parse_syscall_filter(n,
×
2680
                                                                 e,
2681
                                                                 c->syscall_filter,
2682
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2683
                                                                 invert_flag |
×
2684
                                                                 (c->syscall_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2685
                                                                 u->id,
×
2686
                                                                 NULL, 0);
2687
                                if (r < 0)
×
2688
                                        return r;
2689
                        }
2690

2691
                        joined = strv_join(l, " ");
×
2692
                        if (!joined)
×
2693
                                return -ENOMEM;
2694

2695
                        unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", allow_list ? "" : "~", joined);
×
2696
                }
2697

2698
                return 1;
×
2699

2700
        } else if (streq(name, "SystemCallLog")) {
782✔
2701
                int allow_list;
×
2702
                _cleanup_strv_free_ char **l = NULL;
×
2703

2704
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2705
                if (r < 0)
×
2706
                        return r;
2707

2708
                r = sd_bus_message_read(message, "b", &allow_list);
×
2709
                if (r < 0)
×
2710
                        return r;
2711

2712
                r = sd_bus_message_read_strv(message, &l);
×
2713
                if (r < 0)
×
2714
                        return r;
2715

2716
                r = sd_bus_message_exit_container(message);
×
2717
                if (r < 0)
×
2718
                        return r;
2719

2720
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2721
                        _cleanup_free_ char *joined = NULL;
×
2722
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2723

2724
                        if (strv_isempty(l)) {
×
2725
                                c->syscall_log_allow_list = false;
×
2726
                                c->syscall_log = hashmap_free(c->syscall_log);
×
2727

2728
                                unit_write_settingf(u, flags, name, "SystemCallLog=");
×
2729
                                return 1;
2730
                        }
2731

2732
                        if (!c->syscall_log) {
×
2733
                                c->syscall_log = hashmap_new(NULL);
×
2734
                                if (!c->syscall_log)
×
2735
                                        return log_oom();
×
2736

2737
                                c->syscall_log_allow_list = allow_list;
×
2738
                        }
2739

2740
                        STRV_FOREACH(s, l) {
×
2741
                                r = seccomp_parse_syscall_filter(*s,
×
2742
                                                                 -1, /* errno not used */
2743
                                                                 c->syscall_log,
2744
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2745
                                                                 invert_flag |
×
2746
                                                                 (c->syscall_log_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2747
                                                                 u->id,
×
2748
                                                                 NULL, 0);
2749
                                if (r < 0)
×
2750
                                        return r;
2751
                        }
2752

2753
                        joined = strv_join(l, " ");
×
2754
                        if (!joined)
×
2755
                                return -ENOMEM;
2756

2757
                        unit_write_settingf(u, flags, name, "SystemCallLog=%s%s", allow_list ? "" : "~", joined);
×
2758
                }
2759

2760
                return 1;
×
2761

2762
        } else if (streq(name, "SystemCallArchitectures")) {
782✔
2763
                _cleanup_strv_free_ char **l = NULL;
×
2764

2765
                r = sd_bus_message_read_strv(message, &l);
×
2766
                if (r < 0)
×
2767
                        return r;
2768

2769
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2770
                        _cleanup_free_ char *joined = NULL;
×
2771

2772
                        if (strv_isempty(l))
×
2773
                                c->syscall_archs = set_free(c->syscall_archs);
×
2774
                        else
2775
                                STRV_FOREACH(s, l) {
×
2776
                                        uint32_t a;
×
2777

2778
                                        r = seccomp_arch_from_string(*s, &a);
×
2779
                                        if (r < 0)
×
2780
                                                return r;
×
2781

2782
                                        r = set_ensure_put(&c->syscall_archs, NULL, UINT32_TO_PTR(a + 1));
×
2783
                                        if (r < 0)
×
2784
                                                return r;
2785
                                }
2786

2787
                        joined = strv_join(l, " ");
×
2788
                        if (!joined)
×
2789
                                return -ENOMEM;
2790

2791
                        unit_write_settingf(u, flags, name, "%s=%s", name, joined);
×
2792
                }
2793

2794
                return 1;
×
2795

2796
        } else if (streq(name, "RestrictAddressFamilies")) {
782✔
2797
                _cleanup_strv_free_ char **l = NULL;
×
2798
                int allow_list;
×
2799

2800
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2801
                if (r < 0)
×
2802
                        return r;
2803

2804
                r = sd_bus_message_read(message, "b", &allow_list);
×
2805
                if (r < 0)
×
2806
                        return r;
2807

2808
                r = sd_bus_message_read_strv(message, &l);
×
2809
                if (r < 0)
×
2810
                        return r;
2811

2812
                r = sd_bus_message_exit_container(message);
×
2813
                if (r < 0)
×
2814
                        return r;
2815

2816
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2817
                        _cleanup_free_ char *joined = NULL;
×
2818

2819
                        if (strv_isempty(l)) {
×
2820
                                c->address_families_allow_list = allow_list;
×
2821
                                c->address_families = set_free(c->address_families);
×
2822

2823
                                unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s",
×
2824
                                                    allow_list ? "none" : "");
×
2825
                                return 1;
2826
                        }
2827

2828
                        if (!c->address_families) {
×
2829
                                c->address_families = set_new(NULL);
×
2830
                                if (!c->address_families)
×
2831
                                        return log_oom();
×
2832

2833
                                c->address_families_allow_list = allow_list;
×
2834
                        }
2835

2836
                        STRV_FOREACH(s, l) {
×
2837
                                int af;
×
2838

2839
                                af = af_from_name(*s);
×
2840
                                if (af < 0)
×
2841
                                        return af;
2842

2843
                                if (allow_list == c->address_families_allow_list) {
×
2844
                                        r = set_put(c->address_families, INT_TO_PTR(af));
×
2845
                                        if (r < 0)
×
2846
                                                return r;
2847
                                } else
2848
                                        set_remove(c->address_families, INT_TO_PTR(af));
×
2849
                        }
2850

2851
                        joined = strv_join(l, " ");
×
2852
                        if (!joined)
×
2853
                                return -ENOMEM;
2854

2855
                        unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", allow_list ? "" : "~", joined);
×
2856
                }
2857

2858
                return 1;
×
2859
        }
2860
#endif
2861
        if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
782✔
2862
                const void *a;
×
2863
                size_t n;
×
2864
                bool affinity = streq(name, "CPUAffinity");
×
2865
                _cleanup_(cpu_set_reset) CPUSet set = {};
×
2866

2867
                r = sd_bus_message_read_array(message, 'y', &a, &n);
×
2868
                if (r < 0)
×
2869
                        return r;
2870

2871
                r = cpu_set_from_dbus(a, n, &set);
×
2872
                if (r < 0)
×
2873
                        return r;
2874

2875
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2876
                        if (n == 0) {
×
2877
                                cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
×
2878
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2879
                        } else {
2880
                                _cleanup_free_ char *str = NULL;
×
2881

2882
                                str = cpu_set_to_string(&set);
×
2883
                                if (!str)
×
2884
                                        return -ENOMEM;
2885

2886
                                /* We forego any optimizations here, and always create the structure using
2887
                                 * cpu_set_add_all(), because we don't want to care if the existing size we
2888
                                 * got over dbus is appropriate. */
2889
                                r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
×
2890
                                if (r < 0)
×
2891
                                        return r;
2892

2893
                                unit_write_settingf(u, flags, name, "%s=%s", name, str);
×
2894
                        }
2895
                }
2896

2897
                return 1;
×
2898

2899
        } else if (streq(name, "CPUAffinityFromNUMA")) {
782✔
2900
                int q;
×
2901

2902
                r = sd_bus_message_read_basic(message, 'b', &q);
×
2903
                if (r < 0)
×
2904
                        return r;
×
2905

2906
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2907
                        c->cpu_affinity_from_numa = q;
×
2908
                        unit_write_settingf(u, flags, name, "%s=%s", "CPUAffinity", "numa");
×
2909
                }
2910

2911
                return 1;
×
2912

2913
        } else if (streq(name, "NUMAPolicy")) {
782✔
2914
                int32_t type;
×
2915

2916
                r = sd_bus_message_read(message, "i", &type);
×
2917
                if (r < 0)
×
2918
                        return r;
×
2919

2920
                if (!mpol_is_valid(type))
×
2921
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
×
2922

2923
                if (!UNIT_WRITE_FLAGS_NOOP(flags))
×
2924
                        c->numa_policy.type = type;
×
2925

2926
                return 1;
×
2927

2928
        } else if (streq(name, "Nice")) {
782✔
2929
                int32_t q;
×
2930

2931
                r = sd_bus_message_read(message, "i", &q);
×
2932
                if (r < 0)
×
2933
                        return r;
×
2934

2935
                if (!nice_is_valid(q))
×
2936
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
×
2937

2938
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2939
                        c->nice = q;
×
2940
                        c->nice_set = true;
×
2941

2942
                        unit_write_settingf(u, flags, name, "Nice=%i", q);
×
2943
                }
2944

2945
                return 1;
×
2946

2947
        } else if (streq(name, "CPUSchedulingPolicy")) {
782✔
2948
                int32_t q;
×
2949

2950
                r = sd_bus_message_read(message, "i", &q);
×
2951
                if (r < 0)
×
2952
                        return r;
×
2953

2954
                if (!sched_policy_is_valid(q))
×
2955
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
×
2956

2957
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2958
                        _cleanup_free_ char *s = NULL;
×
2959

2960
                        r = sched_policy_to_string_alloc(q, &s);
×
2961
                        if (r < 0)
×
2962
                                return r;
×
2963

2964
                        c->cpu_sched_policy = q;
×
2965
                        c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
×
2966
                        c->cpu_sched_set = true;
×
2967

2968
                        unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
×
2969
                }
2970

2971
                return 1;
×
2972

2973
        } else if (streq(name, "CPUSchedulingPriority")) {
782✔
2974
                int32_t p;
×
2975

2976
                r = sd_bus_message_read(message, "i", &p);
×
2977
                if (r < 0)
×
2978
                        return r;
×
2979

2980
                /* On Linux RR/FIFO range from 1 to 99 and OTHER/BATCH may only be 0. Policy might be set
2981
                 * later so we do not check the precise range, but only the generic outer bounds. */
2982
                if (p < 0 || p > 99)
×
2983
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority: %i", p);
×
2984

2985
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2986
                        c->cpu_sched_priority = p;
×
2987
                        c->cpu_sched_set = true;
×
2988

2989
                        unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
×
2990
                }
2991

2992
                return 1;
×
2993

2994
        } else if (streq(name, "IOSchedulingClass")) {
782✔
2995
                int32_t q;
×
2996

2997
                r = sd_bus_message_read(message, "i", &q);
×
2998
                if (r < 0)
×
2999
                        return r;
×
3000

3001
                if (!ioprio_class_is_valid(q))
×
3002
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
×
3003

3004
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3005
                        _cleanup_free_ char *s = NULL;
×
3006

3007
                        r = ioprio_class_to_string_alloc(q, &s);
×
3008
                        if (r < 0)
×
3009
                                return r;
×
3010

3011
                        c->ioprio = ioprio_normalize(ioprio_prio_value(q, ioprio_prio_data(c->ioprio)));
×
3012
                        c->ioprio_set = true;
×
3013

3014
                        unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
×
3015
                }
3016

3017
                return 1;
×
3018

3019
        } else if (streq(name, "IOSchedulingPriority")) {
782✔
3020
                int32_t p;
×
3021

3022
                r = sd_bus_message_read(message, "i", &p);
×
3023
                if (r < 0)
×
3024
                        return r;
×
3025

3026
                if (!ioprio_priority_is_valid(p))
×
3027
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
×
3028

3029
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3030
                        c->ioprio = ioprio_normalize(ioprio_prio_value(ioprio_prio_class(c->ioprio), p));
×
3031
                        c->ioprio_set = true;
×
3032

3033
                        unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
×
3034
                }
3035

3036
                return 1;
×
3037

3038
        } else if (streq(name, "WorkingDirectory")) {
782✔
3039
                _cleanup_free_ char *simplified = NULL;
×
3040
                bool missing_ok = false, is_home = false;
×
3041
                const char *s;
×
3042

3043
                r = sd_bus_message_read(message, "s", &s);
×
3044
                if (r < 0)
×
3045
                        return r;
3046

3047
                if (!isempty(s)) {
×
3048
                        if (s[0] == '-') {
×
3049
                                missing_ok = true;
×
3050
                                s++;
×
3051
                        }
3052

3053
                        if (streq(s, "~"))
×
3054
                                is_home = true;
3055
                        else {
3056
                                if (!path_is_absolute(s))
×
3057
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3058
                                                                "WorkingDirectory= expects an absolute path or '~'");
3059

3060
                                r = path_simplify_alloc(s, &simplified);
×
3061
                                if (r < 0)
×
3062
                                        return r;
3063

3064
                                if (!path_is_normalized(simplified))
×
3065
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3066
                                                                "WorkingDirectory= expects a normalized path or '~'");
3067
                        }
3068
                }
3069

3070
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3071
                        free_and_replace(c->working_directory, simplified);
×
3072
                        c->working_directory_home = is_home;
×
3073
                        c->working_directory_missing_ok = missing_ok;
×
3074

3075
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
3076
                                            "WorkingDirectory=%s%s",
3077
                                            c->working_directory_missing_ok ? "-" : "",
×
3078
                                            c->working_directory_home ? "~" : strempty(c->working_directory));
×
3079
                }
3080

3081
                return 1;
×
3082

3083
        } else if (STR_IN_SET(name,
782✔
3084
                              "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
3085
                const char *s;
×
3086

3087
                r = sd_bus_message_read(message, "s", &s);
×
3088
                if (r < 0)
×
3089
                        return r;
×
3090

3091
                if (!isempty(s) && !fdname_is_valid(s))
×
3092
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
×
3093

3094
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3095

3096
                        if (streq(name, "StandardInputFileDescriptorName")) {
×
3097
                                r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s));
×
3098
                                if (r < 0)
×
3099
                                        return r;
3100

3101
                                c->std_input = EXEC_INPUT_NAMED_FD;
×
3102
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO));
×
3103

3104
                        } else if (streq(name, "StandardOutputFileDescriptorName")) {
×
3105
                                r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s));
×
3106
                                if (r < 0)
×
3107
                                        return r;
3108

3109
                                c->std_output = EXEC_OUTPUT_NAMED_FD;
×
3110
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO));
×
3111

3112
                        } else {
3113
                                assert(streq(name, "StandardErrorFileDescriptorName"));
×
3114

3115
                                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s));
×
3116
                                if (r < 0)
×
3117
                                        return r;
3118

3119
                                c->std_error = EXEC_OUTPUT_NAMED_FD;
×
3120
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
×
3121
                        }
3122
                }
3123

3124
                return 1;
×
3125

3126
        } else if (STR_IN_SET(name,
782✔
3127
                              "StandardInputFile",
3128
                              "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate",
3129
                              "StandardErrorFile", "StandardErrorFileToAppend", "StandardErrorFileToTruncate")) {
3130
                const char *s;
×
3131

3132
                r = sd_bus_message_read(message, "s", &s);
×
3133
                if (r < 0)
×
3134
                        return r;
×
3135

3136
                if (!isempty(s)) {
×
3137
                        if (!path_is_absolute(s))
×
3138
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
×
3139
                        if (!path_is_normalized(s))
×
3140
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
×
3141
                }
3142

3143
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3144

3145
                        if (streq(name, "StandardInputFile")) {
×
3146
                                r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s));
×
3147
                                if (r < 0)
×
3148
                                        return r;
3149

3150
                                c->std_input = EXEC_INPUT_FILE;
×
3151
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
×
3152

3153
                        } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate")) {
×
3154
                                r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
×
3155
                                if (r < 0)
×
3156
                                        return r;
×
3157

3158
                                if (streq(name, "StandardOutputFile")) {
×
3159
                                        c->std_output = EXEC_OUTPUT_FILE;
×
3160
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
×
3161
                                } else if (streq(name, "StandardOutputFileToAppend")) {
×
3162
                                        c->std_output = EXEC_OUTPUT_FILE_APPEND;
×
3163
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s);
×
3164
                                } else {
3165
                                        assert(streq(name, "StandardOutputFileToTruncate"));
×
3166
                                        c->std_output = EXEC_OUTPUT_FILE_TRUNCATE;
×
3167
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=truncate:%s", s);
×
3168
                                }
3169
                        } else {
3170
                                assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend", "StandardErrorFileToTruncate"));
×
3171

3172
                                r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
×
3173
                                if (r < 0)
×
3174
                                        return r;
3175

3176
                                if (streq(name, "StandardErrorFile")) {
×
3177
                                        c->std_error = EXEC_OUTPUT_FILE;
×
3178
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
×
3179
                                } else if (streq(name, "StandardErrorFileToAppend")) {
×
3180
                                        c->std_error = EXEC_OUTPUT_FILE_APPEND;
×
3181
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
×
3182
                                } else {
3183
                                        assert(streq(name, "StandardErrorFileToTruncate"));
×
3184
                                        c->std_error = EXEC_OUTPUT_FILE_TRUNCATE;
×
3185
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=truncate:%s", s);
×
3186
                                }
3187
                        }
3188
                }
3189

3190
                return 1;
×
3191

3192
        } else if (streq(name, "StandardInputData")) {
782✔
3193
                const void *p;
×
3194
                size_t sz;
×
3195

3196
                r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
3197
                if (r < 0)
×
3198
                        return r;
×
3199

3200
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3201
                        _cleanup_free_ char *encoded = NULL;
×
3202

3203
                        if (sz == 0) {
×
3204
                                c->stdin_data = mfree(c->stdin_data);
×
3205
                                c->stdin_data_size = 0;
×
3206

3207
                                unit_write_settingf(u, flags, name, "StandardInputData=");
×
3208
                        } else {
3209
                                void *q;
×
3210
                                ssize_t n;
×
3211

3212
                                if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
×
3213
                                    c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
3214
                                        return -E2BIG;
3215

3216
                                n = base64mem(p, sz, &encoded);
×
3217
                                if (n < 0)
×
3218
                                        return (int) n;
×
3219

3220
                                q = realloc(c->stdin_data, c->stdin_data_size + sz);
×
3221
                                if (!q)
×
3222
                                        return -ENOMEM;
3223

3224
                                memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
×
3225

3226
                                c->stdin_data = q;
×
3227
                                c->stdin_data_size += sz;
×
3228

3229
                                unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
×
3230
                        }
3231
                }
3232

3233
                return 1;
×
3234

3235
        } else if (streq(name, "Environment")) {
782✔
3236

3237
                _cleanup_strv_free_ char **l = NULL;
14✔
3238

3239
                r = sd_bus_message_read_strv(message, &l);
14✔
3240
                if (r < 0)
14✔
3241
                        return r;
3242

3243
                if (!strv_env_is_valid(l))
14✔
3244
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
×
3245

3246
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
3247
                        if (strv_isempty(l)) {
7✔
3248
                                c->environment = strv_free(c->environment);
×
3249
                                unit_write_setting(u, flags, name, "Environment=");
×
3250
                        } else {
3251
                                _cleanup_free_ char *joined = NULL;
7✔
3252
                                char **e;
7✔
3253

3254
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
7✔
3255
                                if (!joined)
7✔
3256
                                        return -ENOMEM;
3257

3258
                                e = strv_env_merge(c->environment, l);
7✔
3259
                                if (!e)
7✔
3260
                                        return -ENOMEM;
3261

3262
                                strv_free_and_replace(c->environment, e);
7✔
3263
                                unit_write_settingf(u, flags, name, "Environment=%s", joined);
7✔
3264
                        }
3265
                }
3266

3267
                return 1;
14✔
3268

3269
        } else if (streq(name, "UnsetEnvironment")) {
768✔
3270

3271
                _cleanup_strv_free_ char **l = NULL;
×
3272

3273
                r = sd_bus_message_read_strv(message, &l);
×
3274
                if (r < 0)
×
3275
                        return r;
3276

3277
                if (!strv_env_name_or_assignment_is_valid(l))
×
3278
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
×
3279

3280
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3281
                        if (strv_isempty(l)) {
×
3282
                                c->unset_environment = strv_free(c->unset_environment);
×
3283
                                unit_write_setting(u, flags, name, "UnsetEnvironment=");
×
3284
                        } else {
3285
                                _cleanup_free_ char *joined = NULL;
×
3286
                                char **e;
×
3287

3288
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
×
3289
                                if (!joined)
×
3290
                                        return -ENOMEM;
3291

3292
                                e = strv_env_merge(c->unset_environment, l);
×
3293
                                if (!e)
×
3294
                                        return -ENOMEM;
3295

3296
                                strv_free_and_replace(c->unset_environment, e);
×
3297
                                unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
×
3298
                        }
3299
                }
3300

3301
                return 1;
×
3302

3303
        } else if (streq(name, "OOMScoreAdjust")) {
768✔
3304
                int oa;
×
3305

3306
                r = sd_bus_message_read(message, "i", &oa);
×
3307
                if (r < 0)
×
3308
                        return r;
×
3309

3310
                if (!oom_score_adjust_is_valid(oa))
×
3311
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
×
3312

3313
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3314
                        c->oom_score_adjust = oa;
×
3315
                        c->oom_score_adjust_set = true;
×
3316
                        unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
×
3317
                }
3318

3319
                return 1;
×
3320

3321
        } else if (streq(name, "CoredumpFilter")) {
768✔
3322
                uint64_t f;
×
3323

3324
                r = sd_bus_message_read(message, "t", &f);
×
3325
                if (r < 0)
×
3326
                        return r;
×
3327

3328
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3329
                        c->coredump_filter = f;
×
3330
                        c->coredump_filter_set = true;
×
3331
                        unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f);
×
3332
                }
3333

3334
                return 1;
×
3335

3336
        } else if (streq(name, "EnvironmentFiles")) {
768✔
3337
                _cleanup_(memstream_done) MemStream m = {};
×
3338
                _cleanup_free_ char *joined = NULL;
4✔
3339
                _cleanup_strv_free_ char **l = NULL;
4✔
3340
                FILE *f;
4✔
3341

3342
                r = sd_bus_message_enter_container(message, 'a', "(sb)");
4✔
3343
                if (r < 0)
4✔
3344
                        return r;
3345

3346
                f = memstream_init(&m);
4✔
3347
                if (!f)
4✔
3348
                        return -ENOMEM;
3349

3350
                fputs("EnvironmentFile=\n", f);
4✔
3351

3352
                STRV_FOREACH(i, c->environment_files) {
4✔
3353
                        _cleanup_free_ char *q = NULL;
×
3354

3355
                        q = specifier_escape(*i);
×
3356
                        if (!q)
×
3357
                                return -ENOMEM;
×
3358

3359
                        fprintf(f, "EnvironmentFile=%s\n", q);
×
3360
                }
3361

3362
                while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
8✔
3363
                        const char *path;
4✔
3364
                        int b;
4✔
3365

3366
                        r = sd_bus_message_read(message, "sb", &path, &b);
4✔
3367
                        if (r < 0)
4✔
3368
                                return r;
×
3369

3370
                        r = sd_bus_message_exit_container(message);
4✔
3371
                        if (r < 0)
4✔
3372
                                return r;
3373

3374
                        if (!path_is_absolute(path))
4✔
3375
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
×
3376

3377
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3378
                                _cleanup_free_ char *q = NULL, *buf = NULL;
2✔
3379

3380
                                buf = strjoin(b ? "-" : "", path);
3✔
3381
                                if (!buf)
2✔
3382
                                        return -ENOMEM;
3383

3384
                                q = specifier_escape(buf);
2✔
3385
                                if (!q)
2✔
3386
                                        return -ENOMEM;
3387

3388
                                fprintf(f, "EnvironmentFile=%s\n", q);
2✔
3389

3390
                                r = strv_consume(&l, TAKE_PTR(buf));
2✔
3391
                                if (r < 0)
2✔
3392
                                        return r;
3393
                        }
3394
                }
3395
                if (r < 0)
4✔
3396
                        return r;
3397

3398
                r = sd_bus_message_exit_container(message);
4✔
3399
                if (r < 0)
4✔
3400
                        return r;
3401

3402
                r = memstream_finalize(&m, &joined, NULL);
4✔
3403
                if (r < 0)
4✔
3404
                        return r;
3405

3406
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3407
                        if (strv_isempty(l)) {
2✔
3408
                                c->environment_files = strv_free(c->environment_files);
×
3409
                                unit_write_setting(u, flags, name, "EnvironmentFile=");
×
3410
                        } else {
3411
                                r = strv_extend_strv(&c->environment_files, l, true);
2✔
3412
                                if (r < 0)
2✔
3413
                                        return r;
3414

3415
                                unit_write_setting(u, flags, name, joined);
2✔
3416
                        }
3417
                }
3418

3419
                return 1;
4✔
3420

3421
        } else if (streq(name, "PassEnvironment")) {
764✔
3422

3423
                _cleanup_strv_free_ char **l = NULL;
×
3424

3425
                r = sd_bus_message_read_strv(message, &l);
×
3426
                if (r < 0)
×
3427
                        return r;
3428

3429
                if (!strv_env_name_is_valid(l))
×
3430
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
×
3431

3432
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3433
                        if (strv_isempty(l)) {
×
3434
                                c->pass_environment = strv_free(c->pass_environment);
×
3435
                                unit_write_setting(u, flags, name, "PassEnvironment=");
×
3436
                        } else {
3437
                                _cleanup_free_ char *joined = NULL;
×
3438

3439
                                r = strv_extend_strv(&c->pass_environment, l, true);
×
3440
                                if (r < 0)
×
3441
                                        return r;
3442

3443
                                /* We write just the new settings out to file, with unresolved specifiers. */
3444
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
×
3445
                                if (!joined)
×
3446
                                        return -ENOMEM;
3447

3448
                                unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
×
3449
                        }
3450
                }
3451

3452
                return 1;
×
3453

3454
        } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
764✔
3455
                              "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths", "ExecPaths", "NoExecPaths",
3456
                              "ExtensionDirectories")) {
3457
                _cleanup_strv_free_ char **l = NULL;
14✔
3458
                char ***dirs;
14✔
3459

3460
                r = sd_bus_message_read_strv(message, &l);
14✔
3461
                if (r < 0)
14✔
3462
                        return r;
3463

3464
                STRV_FOREACH(p, l) {
32✔
3465
                        char *i = *p;
18✔
3466
                        size_t offset;
18✔
3467

3468
                        offset = i[0] == '-';
18✔
3469
                        offset += i[offset] == '+';
18✔
3470
                        if (!path_is_absolute(i + offset))
18✔
3471
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3472

3473
                        path_simplify(i + offset);
18✔
3474
                }
3475

3476
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
3477
                        if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
7✔
3478
                                dirs = &c->read_write_paths;
1✔
3479
                        else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
6✔
3480
                                dirs = &c->read_only_paths;
2✔
3481
                        else if (streq(name, "ExecPaths"))
4✔
3482
                                dirs = &c->exec_paths;
1✔
3483
                        else if (streq(name, "NoExecPaths"))
3✔
3484
                                dirs = &c->no_exec_paths;
1✔
3485
                        else if (streq(name, "ExtensionDirectories"))
2✔
3486
                                dirs = &c->extension_directories;
1✔
3487
                        else /* "InaccessiblePaths" */
3488
                                dirs = &c->inaccessible_paths;
1✔
3489

3490
                        if (strv_isempty(l)) {
7✔
3491
                                *dirs = strv_free(*dirs);
×
3492
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3493
                        } else {
3494
                                _cleanup_free_ char *joined = NULL;
7✔
3495

3496
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
7✔
3497
                                if (!joined)
7✔
3498
                                        return -ENOMEM;
3499

3500
                                r = strv_extend_strv(dirs, l, true);
7✔
3501
                                if (r < 0)
7✔
3502
                                        return r;
3503

3504
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
7✔
3505
                        }
3506
                }
3507

3508
                return 1;
14✔
3509

3510
        } else if (streq(name, "ExecSearchPath")) {
750✔
3511
                _cleanup_strv_free_ char **l = NULL;
×
3512

3513
                r = sd_bus_message_read_strv(message, &l);
×
3514
                if (r < 0)
×
3515
                        return r;
3516

3517
                STRV_FOREACH(p, l)
×
3518
                        if (!path_is_absolute(*p) || !path_is_normalized(*p) || strchr(*p, ':'))
×
3519
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3520

3521
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3522
                        if (strv_isempty(l)) {
×
3523
                                c->exec_search_path = strv_free(c->exec_search_path);
×
3524
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=");
×
3525
                        } else {
3526
                                _cleanup_free_ char *joined = NULL;
×
3527
                                r = strv_extend_strv(&c->exec_search_path, l, true);
×
3528
                                if (r < 0)
×
3529
                                        return r;
3530
                                joined = strv_join(c->exec_search_path, ":");
×
3531
                                if (!joined)
×
3532
                                        return log_oom();
×
3533
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=%s", joined);
×
3534
                        }
3535
                }
3536

3537
                return 1;
×
3538

3539
        } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
750✔
3540
                _cleanup_strv_free_ char **l = NULL;
114✔
3541

3542
                r = sd_bus_message_read_strv(message, &l);
114✔
3543
                if (r < 0)
114✔
3544
                        return r;
3545

3546
                STRV_FOREACH(p, l) {
288✔
3547
                        if (!path_is_normalized(*p))
174✔
3548
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
×
3549

3550
                        if (path_is_absolute(*p))
174✔
3551
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is absolute: %s", name, *p);
×
3552

3553
                        if (path_startswith(*p, "private"))
174✔
3554
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
×
3555
                }
3556

3557
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
114✔
3558
                        ExecDirectoryType i;
57✔
3559
                        ExecDirectory *d;
57✔
3560

3561
                        assert_se((i = exec_directory_type_from_string(name)) >= 0);
57✔
3562
                        d = c->directories + i;
57✔
3563

3564
                        if (strv_isempty(l)) {
57✔
3565
                                exec_directory_done(d);
×
3566
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3567
                        } else {
3568
                                _cleanup_free_ char *joined = NULL;
57✔
3569

3570
                                STRV_FOREACH(source, l) {
144✔
3571
                                        r = exec_directory_add(d, *source, /* symlink= */ NULL, /* flags= */ 0);
87✔
3572
                                        if (r < 0)
87✔
3573
                                                return log_oom();
×
3574
                                }
3575
                                exec_directory_sort(d);
57✔
3576

3577
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
57✔
3578
                                if (!joined)
57✔
3579
                                        return -ENOMEM;
3580

3581
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
57✔
3582
                        }
3583
                }
3584

3585
                return 1;
114✔
3586

3587
        } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
636✔
3588
                int ignore;
×
3589
                const char *s;
×
3590

3591
                r = sd_bus_message_read(message, "(bs)", &ignore, &s);
×
3592
                if (r < 0)
×
3593
                        return r;
×
3594

3595
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3596
                        char **p;
×
3597
                        bool *b;
×
3598

3599
                        if (streq(name, "AppArmorProfile")) {
×
3600
                                p = &c->apparmor_profile;
×
3601
                                b = &c->apparmor_profile_ignore;
×
3602
                        } else { /* "SmackProcessLabel" */
3603
                                p = &c->smack_process_label;
×
3604
                                b = &c->smack_process_label_ignore;
×
3605
                        }
3606

3607
                        if (isempty(s)) {
×
3608
                                *p = mfree(*p);
×
3609
                                *b = false;
×
3610
                        } else {
3611
                                if (free_and_strdup(p, s) < 0)
×
3612
                                        return -ENOMEM;
3613
                                *b = ignore;
×
3614
                        }
3615

3616
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
×
3617
                }
3618

3619
                return 1;
×
3620

3621
        } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
636✔
3622
                char *source, *destination;
14✔
3623
                int ignore_enoent;
14✔
3624
                uint64_t mount_flags;
14✔
3625
                bool empty = true;
14✔
3626

3627
                r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
14✔
3628
                if (r < 0)
14✔
3629
                        return r;
14✔
3630

3631
                while ((r = sd_bus_message_read(message, "(ssbt)", &source, &destination, &ignore_enoent, &mount_flags)) > 0) {
44✔
3632

3633
                        if (!path_is_absolute(source))
30✔
3634
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3635
                        if (!path_is_absolute(destination))
30✔
3636
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
3637
                        if (!IN_SET(mount_flags, 0, MS_REC))
30✔
3638
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
×
3639

3640
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
30✔
3641
                                r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
30✔
3642
                                                   &(BindMount) {
15✔
3643
                                                           .source = source,
3644
                                                           .destination = destination,
3645
                                                           .read_only = !!strstr(name, "ReadOnly"),
15✔
3646
                                                           .recursive = !!(mount_flags & MS_REC),
15✔
3647
                                                           .ignore_enoent = ignore_enoent,
15✔
3648
                                                   });
3649
                                if (r < 0)
15✔
3650
                                        return r;
×
3651

3652
                                unit_write_settingf(
45✔
3653
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
15✔
3654
                                                "%s=%s%s:%s:%s",
3655
                                                name,
3656
                                                ignore_enoent ? "-" : "",
15✔
3657
                                                source,
3658
                                                destination,
3659
                                                (mount_flags & MS_REC) ? "rbind" : "norbind");
15✔
3660
                        }
3661

3662
                        empty = false;
3663
                }
3664
                if (r < 0)
14✔
3665
                        return r;
3666

3667
                r = sd_bus_message_exit_container(message);
14✔
3668
                if (r < 0)
14✔
3669
                        return r;
3670

3671
                if (empty) {
14✔
3672
                        bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
×
3673
                        c->bind_mounts = NULL;
×
3674
                        c->n_bind_mounts = 0;
×
3675

3676
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3677
                }
3678

3679
                return 1;
14✔
3680

3681
        } else if (streq(name, "TemporaryFileSystem")) {
622✔
3682
                const char *path, *options;
8✔
3683
                bool empty = true;
8✔
3684

3685
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
8✔
3686
                if (r < 0)
8✔
3687
                        return r;
8✔
3688

3689
                while ((r = sd_bus_message_read(message, "(ss)", &path, &options)) > 0) {
16✔
3690

3691
                        if (!path_is_absolute(path))
8✔
3692
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Mount point %s is not absolute.", path);
×
3693

3694
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
3695
                                r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
4✔
3696
                                if (r < 0)
4✔
3697
                                        return r;
3698

3699
                                unit_write_settingf(
4✔
3700
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
4✔
3701
                                                "%s=%s:%s",
3702
                                                name,
3703
                                                path,
3704
                                                options);
3705
                        }
3706

3707
                        empty = false;
3708
                }
3709
                if (r < 0)
8✔
3710
                        return r;
3711

3712
                r = sd_bus_message_exit_container(message);
8✔
3713
                if (r < 0)
8✔
3714
                        return r;
3715

3716
                if (empty) {
8✔
3717
                        temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
×
3718
                        c->temporary_filesystems = NULL;
×
3719
                        c->n_temporary_filesystems = 0;
×
3720

3721
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3722
                }
3723

3724
                return 1;
8✔
3725

3726
        } else if ((suffix = startswith(name, "Limit"))) {
614✔
3727
                const char *soft = NULL;
88✔
3728
                int ri;
88✔
3729

3730
                ri = rlimit_from_string(suffix);
88✔
3731
                if (ri < 0) {
88✔
3732
                        soft = endswith(suffix, "Soft");
44✔
3733
                        if (soft) {
44✔
3734
                                const char *n;
44✔
3735

3736
                                n = strndupa_safe(suffix, soft - suffix);
44✔
3737
                                ri = rlimit_from_string(n);
44✔
3738
                                if (ri >= 0)
44✔
3739
                                        name = strjoina("Limit", n);
220✔
3740
                        }
3741
                }
3742

3743
                if (ri >= 0) {
44✔
3744
                        uint64_t rl;
88✔
3745
                        rlim_t x;
88✔
3746

3747
                        r = sd_bus_message_read(message, "t", &rl);
88✔
3748
                        if (r < 0)
88✔
3749
                                return r;
88✔
3750

3751
                        if (rl == UINT64_MAX)
88✔
3752
                                x = RLIM_INFINITY;
3753
                        else {
3754
                                x = (rlim_t) rl;
72✔
3755

3756
                                if ((uint64_t) x != rl)
72✔
3757
                                        return -ERANGE;
3758
                        }
3759

3760
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
88✔
3761
                                _cleanup_free_ char *f = NULL;
44✔
3762
                                struct rlimit nl;
44✔
3763

3764
                                if (c->rlimit[ri]) {
44✔
3765
                                        nl = *c->rlimit[ri];
27✔
3766

3767
                                        if (soft)
27✔
3768
                                                nl.rlim_cur = x;
22✔
3769
                                        else
3770
                                                nl.rlim_max = x;
5✔
3771
                                } else
3772
                                        /* When the resource limit is not initialized yet, then assign the value to both fields */
3773
                                        nl = (struct rlimit) {
17✔
3774
                                                .rlim_cur = x,
3775
                                                .rlim_max = x,
3776
                                        };
3777

3778
                                r = rlimit_format(&nl, &f);
44✔
3779
                                if (r < 0)
44✔
3780
                                        return r;
3781

3782
                                if (c->rlimit[ri])
44✔
3783
                                        *c->rlimit[ri] = nl;
27✔
3784
                                else {
3785
                                        c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
17✔
3786
                                        if (!c->rlimit[ri])
17✔
3787
                                                return -ENOMEM;
3788
                                }
3789

3790
                                unit_write_settingf(u, flags, name, "%s=%s", name, f);
44✔
3791
                        }
3792

3793
                        return 1;
88✔
3794
                }
3795

3796
        } else if (streq(name, "MountImages")) {
526✔
3797
                _cleanup_free_ char *format_str = NULL;
×
3798
                MountImage *mount_images = NULL;
×
3799
                size_t n_mount_images = 0;
×
3800
                char *source, *destination;
×
3801
                int permissive;
×
3802

3803
                r = sd_bus_message_enter_container(message, 'a', "(ssba(ss))");
×
3804
                if (r < 0)
×
3805
                        return r;
3806

3807
                for (;;) {
×
3808
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3809
                        _cleanup_free_ char *source_escaped = NULL, *destination_escaped = NULL;
×
3810
                        char *tuple;
×
3811

3812
                        r = sd_bus_message_enter_container(message, 'r', "ssba(ss)");
×
3813
                        if (r < 0)
×
3814
                                return r;
3815

3816
                        r = sd_bus_message_read(message, "ssb", &source, &destination, &permissive);
×
3817
                        if (r <= 0)
×
3818
                                break;
3819

3820
                        if (!path_is_absolute(source))
×
3821
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3822
                        if (!path_is_normalized(source))
×
3823
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
3824
                        if (!path_is_absolute(destination))
×
3825
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
3826
                        if (!path_is_normalized(destination))
×
3827
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
3828

3829
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
3830
                        source_escaped = shell_escape(source, ":");
×
3831
                        if (!source_escaped)
×
3832
                                return -ENOMEM;
3833
                        destination_escaped = shell_escape(destination, ":");
×
3834
                        if (!destination_escaped)
×
3835
                                return -ENOMEM;
3836

3837
                        tuple = strjoin(format_str,
×
3838
                                        format_str ? " " : "",
3839
                                        permissive ? "-" : "",
3840
                                        source_escaped,
3841
                                        ":",
3842
                                        destination_escaped);
3843
                        if (!tuple)
×
3844
                                return -ENOMEM;
3845
                        free_and_replace(format_str, tuple);
×
3846

3847
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
3848
                        if (r < 0)
×
3849
                                return r;
3850

3851
                        r = sd_bus_message_exit_container(message);
×
3852
                        if (r < 0)
×
3853
                                return r;
3854

3855
                        r = mount_image_add(&mount_images, &n_mount_images,
×
3856
                                            &(MountImage) {
×
3857
                                                    .source = source,
3858
                                                    .destination = destination,
3859
                                                    .mount_options = options,
3860
                                                    .ignore_enoent = permissive,
×
3861
                                                    .type = MOUNT_IMAGE_DISCRETE,
3862
                                            });
3863
                        if (r < 0)
×
3864
                                return r;
3865
                }
3866
                if (r < 0)
×
3867
                        return r;
3868

3869
                r = sd_bus_message_exit_container(message);
×
3870
                if (r < 0)
×
3871
                        return r;
3872

3873
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3874
                        if (n_mount_images == 0) {
×
3875
                                c->mount_images = mount_image_free_many(c->mount_images, &c->n_mount_images);
×
3876

3877
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3878
                        } else {
3879
                                for (size_t i = 0; i < n_mount_images; ++i) {
×
3880
                                        r = mount_image_add(&c->mount_images, &c->n_mount_images, &mount_images[i]);
×
3881
                                        if (r < 0)
×
3882
                                                return r;
3883
                                }
3884

3885
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
3886
                                                    name,
3887
                                                    "%s=%s",
3888
                                                    name,
3889
                                                    format_str);
3890
                        }
3891
                }
3892

3893
                mount_images = mount_image_free_many(mount_images, &n_mount_images);
×
3894

3895
                return 1;
×
3896
        } else if (streq(name, "ExtensionImages")) {
526✔
3897
                _cleanup_free_ char *format_str = NULL;
×
3898
                MountImage *extension_images = NULL;
×
3899
                size_t n_extension_images = 0;
×
3900

3901
                r = sd_bus_message_enter_container(message, 'a', "(sba(ss))");
×
3902
                if (r < 0)
×
3903
                        return r;
3904

3905
                for (;;) {
×
3906
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3907
                        _cleanup_free_ char *source_escaped = NULL;
×
3908
                        char *source, *tuple;
×
3909
                        int permissive;
×
3910

3911
                        r = sd_bus_message_enter_container(message, 'r', "sba(ss)");
×
3912
                        if (r < 0)
×
3913
                                return r;
3914

3915
                        r = sd_bus_message_read(message, "sb", &source, &permissive);
×
3916
                        if (r <= 0)
×
3917
                                break;
3918

3919
                        if (!path_is_absolute(source))
×
3920
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3921
                        if (!path_is_normalized(source))
×
3922
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
3923

3924
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
3925
                        source_escaped = shell_escape(source, ":");
×
3926
                        if (!source_escaped)
×
3927
                                return -ENOMEM;
3928

3929
                        tuple = strjoin(format_str,
×
3930
                                        format_str ? " " : "",
3931
                                        permissive ? "-" : "",
3932
                                        source_escaped);
3933
                        if (!tuple)
×
3934
                                return -ENOMEM;
3935
                        free_and_replace(format_str, tuple);
×
3936

3937
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
3938
                        if (r < 0)
×
3939
                                return r;
3940

3941
                        r = sd_bus_message_exit_container(message);
×
3942
                        if (r < 0)
×
3943
                                return r;
3944

3945
                        r = mount_image_add(&extension_images, &n_extension_images,
×
3946
                                            &(MountImage) {
×
3947
                                                    .source = source,
3948
                                                    .mount_options = options,
3949
                                                    .ignore_enoent = permissive,
×
3950
                                                    .type = MOUNT_IMAGE_EXTENSION,
3951
                                            });
3952
                        if (r < 0)
×
3953
                                return r;
3954
                }
3955
                if (r < 0)
×
3956
                        return r;
3957

3958
                r = sd_bus_message_exit_container(message);
×
3959
                if (r < 0)
×
3960
                        return r;
3961

3962
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3963
                        if (n_extension_images == 0) {
×
3964
                                c->extension_images = mount_image_free_many(c->extension_images, &c->n_extension_images);
×
3965

3966
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3967
                        } else {
3968
                                for (size_t i = 0; i < n_extension_images; ++i) {
×
3969
                                        r = mount_image_add(&c->extension_images, &c->n_extension_images, &extension_images[i]);
×
3970
                                        if (r < 0)
×
3971
                                                return r;
3972
                                }
3973

3974
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
3975
                                                    name,
3976
                                                    "%s=%s",
3977
                                                    name,
3978
                                                    format_str);
3979
                        }
3980
                }
3981

3982
                extension_images = mount_image_free_many(extension_images, &n_extension_images);
×
3983

3984
                return 1;
×
3985

3986
        } else if (STR_IN_SET(name, "StateDirectorySymlink", "RuntimeDirectorySymlink", "CacheDirectorySymlink", "LogsDirectorySymlink")) {
526✔
3987
                char *source, *destination;
14✔
3988
                ExecDirectory *directory;
14✔
3989
                uint64_t symlink_flags;
14✔
3990
                ExecDirectoryType i;
14✔
3991

3992
                assert_se((i = exec_directory_type_symlink_from_string(name)) >= 0);
14✔
3993
                directory = c->directories + i;
14✔
3994

3995
                r = sd_bus_message_enter_container(message, 'a', "(sst)");
14✔
3996
                if (r < 0)
14✔
3997
                        return r;
14✔
3998

3999
                while ((r = sd_bus_message_read(message, "(sst)", &source, &destination, &symlink_flags)) > 0) {
28✔
4000
                        if ((symlink_flags & ~_EXEC_DIRECTORY_FLAGS_PUBLIC) != 0)
14✔
4001
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid 'flags' parameter '%" PRIu64 "'", symlink_flags);
×
4002
                        if (!path_is_valid(source))
14✔
4003
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not valid.", source);
×
4004
                        if (path_is_absolute(source))
14✔
4005
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is absolute.", source);
×
4006
                        if (!path_is_normalized(source))
14✔
4007
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
4008
                        if (isempty(destination))
14✔
4009
                                destination = NULL;
2✔
4010
                        else {
4011
                                if (!path_is_valid(destination))
12✔
4012
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not valid.", destination);
×
4013
                                if (path_is_absolute(destination))
12✔
4014
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is absolute.", destination);
×
4015
                                if (!path_is_normalized(destination))
12✔
4016
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
4017
                        }
4018

4019
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
4020
                                _cleanup_free_ char *destination_escaped = NULL, *source_escaped = NULL;
7✔
4021

4022
                                r = exec_directory_add(directory, source, destination, symlink_flags);
7✔
4023
                                if (r < 0)
7✔
4024
                                        return r;
4025

4026
                                /* Need to store them in the unit with the escapes, so that they can be parsed again */
4027
                                source_escaped = xescape(source, ":");
7✔
4028
                                if (!source_escaped)
7✔
4029
                                        return -ENOMEM;
4030
                                if (destination) {
7✔
4031
                                        destination_escaped = xescape(destination, ":");
6✔
4032
                                        if (!destination_escaped)
6✔
4033
                                                return -ENOMEM;
4034
                                }
4035

4036
                                unit_write_settingf(
8✔
4037
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, exec_directory_type_to_string(i),
7✔
4038
                                                "%s=%s%s%s%s",
4039
                                                exec_directory_type_to_string(i),
4040
                                                source_escaped,
4041
                                                destination_escaped || FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":" : "",
1✔
4042
                                                destination_escaped,
4043
                                                FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":ro" : "");
7✔
4044
                        }
4045
                }
4046
                if (r < 0)
14✔
4047
                        return r;
4048

4049
                exec_directory_sort(directory);
14✔
4050

4051
                r = sd_bus_message_exit_container(message);
14✔
4052
                if (r < 0)
14✔
4053
                        return r;
4054

4055
                return 1;
14✔
4056

4057
        } else if (STR_IN_SET(name, "RootImagePolicy", "MountImagePolicy", "ExtensionImagePolicy")) {
512✔
4058
                _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
×
4059
                const char *s;
×
4060

4061
                r = sd_bus_message_read(message, "s", &s);
×
4062
                if (r < 0)
×
4063
                        return r;
4064

4065
                r = image_policy_from_string(s, &p);
×
4066
                if (r < 0)
×
4067
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse image policy string: %s", s);
×
4068

4069
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
4070
                        _cleanup_free_ char *t = NULL;
×
4071
                        ImagePolicy **pp =
×
4072
                                streq(name, "RootImagePolicy")  ? &c->root_image_policy :
×
4073
                                streq(name, "MountImagePolicy") ? &c->mount_image_policy :
×
4074
                                                                  &c->extension_image_policy;
4075

4076
                        r = image_policy_to_string(p, /* simplify= */ true, &t);
×
4077
                        if (r < 0)
×
4078
                                return r;
×
4079

4080
                        image_policy_free(*pp);
×
4081
                        *pp = TAKE_PTR(p);
×
4082

4083
                        unit_write_settingf(
×
4084
                                        u, flags, name,
4085
                                        "%s=%s",
4086
                                        name,
4087
                                        t); /* no escaping necessary */
4088
                }
4089

4090
                return 1;
×
4091
        }
4092

4093
        return 0;
512✔
4094
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc