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

systemd / systemd / 15199265962

22 May 2025 09:40PM UTC coverage: 72.061% (-0.02%) from 72.079%
15199265962

push

github

bluca
tests: fix TEST-74-AUX-UTILS.varlinkctl.sh (#37562)

per Daan's explanation:
other subtests running as testuser apparently use systemd-run --user
--machine testuser@.host which turns user tracking in logind into "by
pin" mode. when the last pinning session exits it terminates the user.

299156 of 415145 relevant lines covered (72.06%)

703915.84 hits per line

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

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

3
#include <syslog.h>
4
#include <sys/mount.h>
5

6
#include "af-list.h"
7
#include "alloc-util.h"
8
#include "bpf-restrict-fs.h"
9
#include "bus-get-properties.h"
10
#include "bus-unit-util.h"
11
#include "cap-list.h"
12
#include "cpu-set-util.h"
13
#include "creds-util.h"
14
#include "dbus-execute.h"
15
#include "dbus-util.h"
16
#include "dissect-image.h"
17
#include "env-util.h"
18
#include "escape.h"
19
#include "exec-credential.h"
20
#include "execute.h"
21
#include "fd-util.h"
22
#include "hexdecoct.h"
23
#include "hostname-util.h"
24
#include "image-policy.h"
25
#include "ioprio-util.h"
26
#include "iovec-util.h"
27
#include "journal-file.h"
28
#include "memstream-util.h"
29
#include "mountpoint-util.h"
30
#include "namespace.h"
31
#include "nsflags.h"
32
#include "ordered-set.h"
33
#include "path-util.h"
34
#include "pcre2-util.h"
35
#include "process-util.h"
36
#include "rlimit-util.h"
37
#include "seccomp-util.h"
38
#include "securebits-util.h"
39
#include "set.h"
40
#include "specifier.h"
41
#include "strv.h"
42
#include "syslog-util.h"
43
#include "unit.h"
44
#include "user-util.h"
45
#include "utf8.h"
46

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

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

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

90
        assert(bus);
1,281✔
91
        assert(reply);
1,281✔
92

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

97
        STRV_FOREACH(j, c->environment_files) {
1,289✔
98
                const char *fn = *j;
8✔
99

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

105
        return sd_bus_message_close_container(reply);
1,281✔
106
}
107

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

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

122
        assert(bus);
1,281✔
123
        assert(reply);
1,281✔
124

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

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

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

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

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

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

151
        assert(bus);
1,281✔
152
        assert(reply);
1,281✔
153

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

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

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

170
        assert(bus);
1,281✔
171
        assert(reply);
1,281✔
172

173
        policy = numa_policy_get_type(&c->numa_policy);
1,281✔
174

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

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

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

191
        assert(bus);
1,281✔
192
        assert(reply);
1,281✔
193

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

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

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

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

210
        return sd_bus_message_close_container(reply);
1,281✔
211
}
212

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

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

226
        assert(bus);
1,281✔
227
        assert(reply);
1,281✔
228

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

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

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

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

245
        return sd_bus_message_close_container(reply);
1,281✔
246
}
247

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

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

261
        assert(bus);
1,281✔
262
        assert(reply);
1,281✔
263

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

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

272
        return 0;
273
}
274

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

284
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
285

286
        assert(bus);
1,281✔
287
        assert(reply);
1,281✔
288

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

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

301
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
302

303
        assert(bus);
1,281✔
304
        assert(reply);
1,281✔
305

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

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

318
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
319

320
        assert(bus);
1,281✔
321
        assert(reply);
1,281✔
322

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

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

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

339
        assert(bus);
1,281✔
340
        assert(reply);
1,281✔
341

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

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

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

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

358
        return sd_bus_message_close_container(reply);
1,281✔
359
}
360

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

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

373
        assert(bus);
1,281✔
374
        assert(reply);
1,281✔
375

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

381
        if (c->working_directory_missing_ok)
1,281✔
382
                wd = strjoina("!", wd);
1,890✔
383

384
        return sd_bus_message_append(reply, "s", wd);
1,281✔
385
}
386

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

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

399
        assert(bus);
3,843✔
400
        assert(property);
3,843✔
401
        assert(reply);
3,843✔
402

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

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

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

424
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
425

426
        assert(bus);
1,281✔
427
        assert(property);
1,281✔
428
        assert(reply);
1,281✔
429

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

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

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

446
        assert(bus);
1,281✔
447
        assert(reply);
1,281✔
448

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

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

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

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

465
        return sd_bus_message_close_container(reply);
1,281✔
466
}
467

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

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

481
        assert(bus);
2,562✔
482
        assert(property);
2,562✔
483
        assert(reply);
2,562✔
484

485
        ro = strstr(property, "ReadOnly");
2,562✔
486

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

491
        FOREACH_ARRAY(i, c->bind_mounts, c->n_bind_mounts) {
2,808✔
492
                if (ro != i->read_only)
246✔
493
                        continue;
123✔
494

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

505
        return sd_bus_message_close_container(reply);
2,562✔
506
}
507

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

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

520
        assert(bus);
1,281✔
521
        assert(property);
1,281✔
522
        assert(reply);
1,281✔
523

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

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

537
        return sd_bus_message_close_container(reply);
1,281✔
538
}
539

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

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

552
        assert(bus);
1,281✔
553
        assert(property);
1,281✔
554
        assert(reply);
1,281✔
555

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

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

566
        return sd_bus_message_close_container(reply);
1,281✔
567
}
568

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

573
        assert(reply);
2,562✔
574

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

581
        return 0;
2,562✔
582
}
583

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

593
        ExecContext *c = userdata;
1,281✔
594
        int r;
1,281✔
595

596
        assert(c);
1,281✔
597
        assert(reply);
1,281✔
598

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

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

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

613
        return sd_bus_message_close_container(reply);
1,281✔
614
}
615

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

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

629
        assert(bus);
2,562✔
630
        assert(property);
2,562✔
631
        assert(reply);
2,562✔
632

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

637
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,562✔
638

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

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

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

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

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

659
        return sd_bus_message_close_container(reply);
2,562✔
660
}
661

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

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

675
        assert(bus);
2,562✔
676
        assert(property);
2,562✔
677
        assert(reply);
2,562✔
678

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

683
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,580✔
684

685
                if (lc->encrypted != streq(property, "LoadCredentialEncrypted"))
18✔
686
                        continue;
9✔
687

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

693
        return sd_bus_message_close_container(reply);
2,562✔
694
}
695

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

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

709
        assert(bus);
1,281✔
710
        assert(property);
1,281✔
711
        assert(reply);
1,281✔
712

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

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

723
        return sd_bus_message_close_container(reply);
1,281✔
724
}
725

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

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

739
        assert(bus);
1,281✔
740
        assert(property);
1,281✔
741
        assert(reply);
1,281✔
742

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

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

753
        return sd_bus_message_close_container(reply);
1,281✔
754
}
755

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

765
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
766

767
        assert(bus);
1,281✔
768
        assert(property);
1,281✔
769
        assert(reply);
1,281✔
770

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

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

783
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
784

785
        assert(bus);
1,281✔
786
        assert(property);
1,281✔
787
        assert(reply);
1,281✔
788

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

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

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

804
        assert(bus);
1,281✔
805
        assert(property);
1,281✔
806
        assert(reply);
1,281✔
807

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

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

820
        return sd_bus_message_close_container(reply);
1,281✔
821
}
822

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

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

835
        assert(bus);
1,281✔
836
        assert(property);
1,281✔
837
        assert(reply);
1,281✔
838

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

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

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

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

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

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

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

877
        return sd_bus_message_close_container(reply);
1,281✔
878
}
879

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

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

892
        assert(bus);
1,281✔
893
        assert(property);
1,281✔
894
        assert(reply);
1,281✔
895

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

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

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

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

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

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

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

933
        return sd_bus_message_close_container(reply);
1,281✔
934
}
935

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

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

948
        assert(bus);
6,405✔
949
        assert(property);
6,405✔
950
        assert(reply);
6,405✔
951

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

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

962
        return sd_bus_message_close_container(reply);
6,405✔
963
}
964

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

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

977
        assert(bus);
5,124✔
978
        assert(property);
5,124✔
979
        assert(reply);
5,124✔
980

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

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

999
        return sd_bus_message_close_container(reply);
5,124✔
1000
}
1001

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

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

1015
        assert(bus);
3,843✔
1016
        assert(property);
3,843✔
1017
        assert(reply);
3,843✔
1018

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

1023
        return sd_bus_message_append(reply, "s", s);
3,843✔
1024
}
1025

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

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

1038
        return sd_bus_message_append_basic(reply, 'b', &b);
1,281✔
1039
}
1040

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

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

1053
        return sd_bus_message_append_basic(reply, 'b', &b);
1,281✔
1054
}
1055

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

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

1068
        return sd_bus_message_append_basic(reply, 'b', &b);
1,281✔
1069
}
1070

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

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

1083
        return sd_bus_message_append_basic(reply, 'b', &b);
1,281✔
1084
}
1085

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

1095
        ExecContext *c = ASSERT_PTR(userdata);
1,281✔
1096

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

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

1109
        unsigned *value = ASSERT_PTR(userdata);
2,562✔
1110

1111
        /* 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. */
1112

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

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

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

1308
        SD_BUS_VTABLE_END
1309
};
1310

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

1314
        assert(reply);
1,475✔
1315
        assert(c);
1,475✔
1316

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

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

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

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

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

1344
        return sd_bus_message_close_container(reply);
1,248✔
1345
}
1346

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

1351
        assert(reply);
1,244✔
1352
        assert(c);
1,244✔
1353

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

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

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

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

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

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

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

1388
        return sd_bus_message_close_container(reply);
1,244✔
1389
}
1390

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

1400
        ExecCommand *c = (ExecCommand*) userdata;
231✔
1401
        int r;
231✔
1402

1403
        assert(bus);
231✔
1404
        assert(reply);
231✔
1405

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

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

1414
        return sd_bus_message_close_container(reply);
231✔
1415
}
1416

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

1426
        ExecCommand *exec_command = *(ExecCommand**) userdata;
8,104✔
1427
        int r;
8,104✔
1428

1429
        assert(bus);
8,104✔
1430
        assert(reply);
8,104✔
1431

1432
        r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
8,104✔
1433
        if (r < 0)
8,104✔
1434
                return r;
1435

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

1442
        return sd_bus_message_close_container(reply);
8,104✔
1443
}
1444

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

1454
        ExecCommand *exec_command = *(ExecCommand**) userdata;
7,672✔
1455
        int r;
7,672✔
1456

1457
        assert(bus);
7,672✔
1458
        assert(reply);
7,672✔
1459

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

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

1470
        return sd_bus_message_close_container(reply);
7,672✔
1471
}
1472

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

1481
int bus_set_transient_exec_command(
288✔
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");
288✔
1490
        size_t n = 0;
288✔
1491
        int r;
288✔
1492

1493
        assert(u);
288✔
1494
        assert(exec_command);
288✔
1495
        assert(message);
288✔
1496
        assert(error);
288✔
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;
288✔
1500

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

1505
        while ((r = sd_bus_message_enter_container(message, 'r', ex_prop ? "sasas" : "sasb")) > 0) {
1,152✔
1506
                _cleanup_strv_free_ char **argv = NULL;
×
1507
                const char *path;
288✔
1508
                ExecCommandFlags command_flags;
288✔
1509

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

1514
                r = sd_bus_message_read_strv(message, &argv);
288✔
1515
                if (r < 0)
288✔
1516
                        return r;
1517

1518
                if (ex_prop) {
288✔
1519
                        _cleanup_strv_free_ char **ex_opts = NULL;
×
1520

1521
                        r = sd_bus_message_read_strv(message, &ex_opts);
×
1522
                        if (r < 0)
×
1523
                                return r;
1524

1525
                        r = exec_command_flags_from_strv(ex_opts, &command_flags);
×
1526
                        if (r < 0)
×
1527
                                return r;
1528
                } else {
1529
                        int b;
288✔
1530

1531
                        r = sd_bus_message_read(message, "b", &b);
288✔
1532
                        if (r < 0)
288✔
1533
                                return r;
×
1534

1535
                        command_flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
288✔
1536
                }
1537

1538
                if (!FLAGS_SET(command_flags, EXEC_COMMAND_VIA_SHELL)) {
288✔
1539
                        if (!filename_or_absolute_path_is_valid(path))
288✔
1540
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1541
                                                         "\"%s\" is neither a valid executable name nor an absolute path",
1542
                                                         path);
1543

1544
                        if (strv_isempty(argv))
288✔
1545
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1546
                                                         "\"%s\" argv cannot be empty", name);
1547
                } else {
1548
                        /* Always normalize path and argv0 to be "sh" */
1549
                        path = _PATH_BSHELL;
×
1550

1551
                        if (strv_isempty(argv))
×
1552
                                r = strv_extend(&argv, "sh");
×
1553
                        else
1554
                                r = free_and_strdup(&argv[0], argv[0][0] == '-' ? "-sh" : "sh");
×
1555
                        if (r < 0)
×
1556
                                return r;
1557
                }
1558

1559
                r = sd_bus_message_exit_container(message);
288✔
1560
                if (r < 0)
288✔
1561
                        return r;
1562

1563
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
288✔
1564
                        _cleanup_(exec_command_freep) ExecCommand *c = NULL;
144✔
1565

1566
                        c = new(ExecCommand, 1);
144✔
1567
                        if (!c)
144✔
1568
                                return -ENOMEM;
1569

1570
                        *c = (ExecCommand) {
144✔
1571
                                .argv = TAKE_PTR(argv),
144✔
1572
                                .flags = command_flags,
1573
                        };
1574

1575
                        r = path_simplify_alloc(path, &c->path);
144✔
1576
                        if (r < 0)
144✔
1577
                                return r;
1578

1579
                        exec_command_append_list(exec_command, TAKE_PTR(c));
144✔
1580
                }
1581

1582
                n++;
288✔
1583
        }
1584
        if (r < 0)
288✔
1585
                return r;
1586

1587
        r = sd_bus_message_exit_container(message);
288✔
1588
        if (r < 0)
288✔
1589
                return r;
1590

1591
        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
288✔
1592
                _cleanup_(memstream_done) MemStream m = {};
×
1593
                _cleanup_free_ char *buf = NULL;
144✔
1594
                FILE *f;
144✔
1595

1596
                if (n == 0)
144✔
1597
                        *exec_command = exec_command_free_list(*exec_command);
×
1598

1599
                f = memstream_init(&m);
144✔
1600
                if (!f)
144✔
1601
                        return -ENOMEM;
1602

1603
                fprintf(f, "%s=\n", written_name);
144✔
1604

1605
                LIST_FOREACH(command, c, *exec_command) {
288✔
1606
                        _cleanup_free_ char *a = NULL, *exec_chars = NULL;
144✔
1607
                        UnitWriteFlags esc_flags = UNIT_ESCAPE_SPECIFIERS |
144✔
1608
                                (FLAGS_SET(c->flags, EXEC_COMMAND_NO_ENV_EXPAND) ? UNIT_ESCAPE_EXEC_SYNTAX : UNIT_ESCAPE_EXEC_SYNTAX_ENV);
144✔
1609
                        bool via_shell = FLAGS_SET(c->flags, EXEC_COMMAND_VIA_SHELL);
144✔
1610

1611
                        exec_chars = exec_command_flags_to_exec_chars(c->flags);
144✔
1612
                        if (!exec_chars)
144✔
1613
                                return -ENOMEM;
1614

1615
                        a = unit_concat_strv(via_shell ? strv_skip(c->argv, 1) : c->argv, esc_flags);
144✔
1616
                        if (!a)
144✔
1617
                                return -ENOMEM;
1618

1619
                        if (via_shell || streq(c->path, c->argv[0]))
144✔
1620
                                fprintf(f, "%s=%s%s%s\n",
144✔
1621
                                        written_name, exec_chars, via_shell && c->argv[0][0] == '-' ? "@" : "", a);
×
1622
                        else {
1623
                                _cleanup_free_ char *t = NULL;
×
1624
                                const char *p;
×
1625

1626
                                p = unit_escape_setting(c->path, esc_flags, &t);
×
1627
                                if (!p)
×
1628
                                        return -ENOMEM;
×
1629

1630
                                fprintf(f, "%s=%s@%s %s\n", written_name, exec_chars, p, a);
×
1631
                        }
1632
                }
1633

1634
                r = memstream_finalize(&m, &buf, NULL);
144✔
1635
                if (r < 0)
144✔
1636
                        return r;
1637

1638
                unit_write_setting(u, flags, written_name, buf);
144✔
1639
        }
1640

1641
        return 1;
1642
}
1643

1644
static int parse_personality(const char *s, unsigned long *p) {
×
1645
        unsigned long v;
×
1646

1647
        assert(p);
×
1648

1649
        v = personality_from_string(s);
×
1650
        if (v == PERSONALITY_INVALID)
×
1651
                return -EINVAL;
1652

1653
        *p = v;
×
1654
        return 0;
×
1655
}
1656

1657
static const char* mount_propagation_flag_to_string_with_check(unsigned long n) {
2✔
1658
        if (!mount_propagation_flag_is_valid(n))
2✔
1659
                return NULL;
1660

1661
        return mount_propagation_flag_to_string(n);
2✔
1662
}
1663

1664
static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
×
1665
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
×
1666
#if HAVE_SECCOMP
1667
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, seccomp_errno_or_action_is_valid);
×
1668
#endif
1669
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
×
1670
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
60✔
1671
static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
×
1672
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
2✔
1673
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
6✔
1674
static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
×
1675
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string);
10✔
1676
static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string);
6✔
1677
BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
10✔
1678
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
×
1679
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
×
1680
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string);
10✔
1681
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
20✔
1682
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_propagation_flag, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flag_to_string_with_check);
2✔
1683

1684
int bus_exec_context_set_transient_property(
1,126✔
1685
                Unit *u,
1686
                ExecContext *c,
1687
                const char *name,
1688
                sd_bus_message *message,
1689
                UnitWriteFlags flags,
1690
                sd_bus_error *error) {
1691

1692
        const char *suffix;
1,126✔
1693
        int r;
1,126✔
1694

1695
        assert(u);
1,126✔
1696
        assert(c);
1,126✔
1697
        assert(name);
1,126✔
1698
        assert(message);
1,126✔
1699

1700
        flags |= UNIT_PRIVATE;
1,126✔
1701

1702
        if (streq(name, "User"))
1,126✔
1703
                return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error);
26✔
1704

1705
        if (streq(name, "Group"))
1,100✔
1706
                return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error);
4✔
1707

1708
        if (streq(name, "SetLoginEnvironment"))
1,096✔
1709
                return bus_set_transient_tristate(u, name, &c->set_login_environment, message, flags, error);
×
1710

1711
        if (streq(name, "TTYPath"))
1,096✔
1712
                return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
×
1713

1714
        if (streq(name, "RootImage"))
1,096✔
1715
                return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
2✔
1716

1717
        if (streq(name, "RootImageOptions")) {
1,094✔
1718
                _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
1719
                _cleanup_free_ char *format_str = NULL;
×
1720

1721
                r = bus_read_mount_options(message, error, &options, &format_str, " ");
×
1722
                if (r < 0)
×
1723
                        return r;
1724

1725
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1726
                        if (options) {
×
1727
                                LIST_JOIN(mount_options, c->root_image_options, options);
×
1728
                                unit_write_settingf(
×
1729
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
1730
                                                "%s=%s",
1731
                                                name,
1732
                                                format_str);
1733
                        } else {
1734
                                c->root_image_options = mount_options_free_all(c->root_image_options);
×
1735
                                unit_write_settingf(u, flags, name, "%s=", name);
×
1736
                        }
1737
                }
1738

1739
                return 1;
×
1740
        }
1741

1742
        if (streq(name, "RootHash")) {
1,094✔
1743
                const void *roothash_decoded;
×
1744
                size_t roothash_decoded_size;
×
1745

1746
                r = sd_bus_message_read_array(message, 'y', &roothash_decoded, &roothash_decoded_size);
×
1747
                if (r < 0)
×
1748
                        return r;
×
1749

1750
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1751
                        _cleanup_free_ char *encoded = NULL;
×
1752

1753
                        if (roothash_decoded_size == 0) {
×
1754
                                c->root_hash_path = mfree(c->root_hash_path);
×
1755
                                c->root_hash = mfree(c->root_hash);
×
1756
                                c->root_hash_size = 0;
×
1757

1758
                                unit_write_settingf(u, flags, name, "RootHash=");
×
1759
                        } else {
1760
                                _cleanup_free_ void *p = NULL;
×
1761

1762
                                encoded = hexmem(roothash_decoded, roothash_decoded_size);
×
1763
                                if (!encoded)
×
1764
                                        return -ENOMEM;
1765

1766
                                p = memdup(roothash_decoded, roothash_decoded_size);
×
1767
                                if (!p)
×
1768
                                        return -ENOMEM;
1769

1770
                                free_and_replace(c->root_hash, p);
×
1771
                                c->root_hash_size = roothash_decoded_size;
×
1772
                                c->root_hash_path = mfree(c->root_hash_path);
×
1773

1774
                                unit_write_settingf(u, flags, name, "RootHash=%s", encoded);
×
1775
                        }
1776
                }
1777

1778
                return 1;
×
1779
        }
1780

1781
        if (streq(name, "RootHashPath")) {
1,094✔
1782
                c->root_hash_size = 0;
×
1783
                c->root_hash = mfree(c->root_hash);
×
1784

1785
                return bus_set_transient_path(u, "RootHash", &c->root_hash_path, message, flags, error);
×
1786
        }
1787

1788
        if (streq(name, "RootHashSignature")) {
1,094✔
1789
                const void *roothash_sig_decoded;
×
1790
                size_t roothash_sig_decoded_size;
×
1791

1792
                r = sd_bus_message_read_array(message, 'y', &roothash_sig_decoded, &roothash_sig_decoded_size);
×
1793
                if (r < 0)
×
1794
                        return r;
×
1795

1796
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1797
                        _cleanup_free_ char *encoded = NULL;
×
1798

1799
                        if (roothash_sig_decoded_size == 0) {
×
1800
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1801
                                c->root_hash_sig = mfree(c->root_hash_sig);
×
1802
                                c->root_hash_sig_size = 0;
×
1803

1804
                                unit_write_settingf(u, flags, name, "RootHashSignature=");
×
1805
                        } else {
1806
                                _cleanup_free_ void *p = NULL;
×
1807
                                ssize_t len;
×
1808

1809
                                len = base64mem(roothash_sig_decoded, roothash_sig_decoded_size, &encoded);
×
1810
                                if (len < 0)
×
1811
                                        return -ENOMEM;
1812

1813
                                p = memdup(roothash_sig_decoded, roothash_sig_decoded_size);
×
1814
                                if (!p)
×
1815
                                        return -ENOMEM;
1816

1817
                                free_and_replace(c->root_hash_sig, p);
×
1818
                                c->root_hash_sig_size = roothash_sig_decoded_size;
×
1819
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1820

1821
                                unit_write_settingf(u, flags, name, "RootHashSignature=base64:%s", encoded);
×
1822
                        }
1823
                }
1824

1825
                return 1;
×
1826
        }
1827

1828
        if (streq(name, "RootHashSignaturePath")) {
1,094✔
1829
                c->root_hash_sig_size = 0;
×
1830
                c->root_hash_sig = mfree(c->root_hash_sig);
×
1831

1832
                return bus_set_transient_path(u, "RootHashSignature", &c->root_hash_sig_path, message, flags, error);
×
1833
        }
1834

1835
        if (streq(name, "RootVerity"))
1,094✔
1836
                return bus_set_transient_path(u, name, &c->root_verity, message, flags, error);
×
1837

1838
        if (streq(name, "RootDirectory"))
1,094✔
1839
                return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
8✔
1840

1841
        if (streq(name, "RootEphemeral"))
1,086✔
1842
                return bus_set_transient_bool(u, name, &c->root_ephemeral, message, flags, error);
×
1843

1844
        if (streq(name, "SyslogIdentifier"))
1,086✔
1845
                return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
×
1846

1847
        if (streq(name, "LogLevelMax"))
1,086✔
1848
                return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
×
1849

1850
        if (streq(name, "LogRateLimitIntervalUSec"))
1,086✔
1851
                return bus_set_transient_usec(u, name, &c->log_ratelimit.interval, message, flags, error);
×
1852

1853
        if (streq(name, "LogRateLimitBurst"))
1,086✔
1854
                return bus_set_transient_unsigned(u, name, &c->log_ratelimit.burst, message, flags, error);
×
1855

1856
        if (streq(name, "LogFilterPatterns")) {
1,086✔
1857
                /* Use _cleanup_free_, not _cleanup_strv_free_, as we don't want the content of the strv
1858
                 * to be freed. */
1859
                _cleanup_free_ char **allow_list = NULL, **deny_list = NULL;
×
1860
                const char *pattern;
×
1861
                int is_allowlist;
×
1862

1863
                r = sd_bus_message_enter_container(message, 'a', "(bs)");
×
1864
                if (r < 0)
×
1865
                        return r;
1866

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

1870
                        if (isempty(pattern))
×
1871
                                continue;
×
1872

1873
                        r = pattern_compile_and_log(pattern, 0, &compiled_pattern);
×
1874
                        if (r < 0)
×
1875
                                return r;
1876

1877
                        r = strv_push(is_allowlist ? &allow_list : &deny_list, (char *)pattern);
×
1878
                        if (r < 0)
×
1879
                                return r;
1880
                }
1881
                if (r < 0)
×
1882
                        return r;
1883

1884
                r = sd_bus_message_exit_container(message);
×
1885
                if (r < 0)
×
1886
                        return r;
1887

1888
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1889
                        if (strv_isempty(allow_list) && strv_isempty(deny_list)) {
×
1890
                                c->log_filter_allowed_patterns = set_free(c->log_filter_allowed_patterns);
×
1891
                                c->log_filter_denied_patterns = set_free(c->log_filter_denied_patterns);
×
1892
                                unit_write_settingf(u, flags, name, "%s=", name);
×
1893
                        } else {
1894
                                r = set_put_strdupv(&c->log_filter_allowed_patterns, allow_list);
×
1895
                                if (r < 0)
×
1896
                                        return r;
1897
                                r = set_put_strdupv(&c->log_filter_denied_patterns, deny_list);
×
1898
                                if (r < 0)
×
1899
                                        return r;
1900

1901
                                STRV_FOREACH(unit_pattern, allow_list)
×
1902
                                        unit_write_settingf(u, flags, name, "%s=%s", name, *unit_pattern);
×
1903
                                STRV_FOREACH(unit_pattern, deny_list)
×
1904
                                        unit_write_settingf(u, flags, name, "%s=~%s", name, *unit_pattern);
×
1905
                        }
1906
                }
1907

1908
                return 1;
×
1909
        }
1910

1911
        if (streq(name, "Personality"))
1,086✔
1912
                return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
×
1913

1914
        if (streq(name, "StandardInput"))
1,086✔
1915
                return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
×
1916

1917
        if (streq(name, "StandardOutput"))
1,086✔
1918
                return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
30✔
1919

1920
        if (streq(name, "StandardError"))
1,056✔
1921
                return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
30✔
1922

1923
        if (streq(name, "IgnoreSIGPIPE"))
1,026✔
1924
                return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
×
1925

1926
        if (streq(name, "TTYVHangup"))
1,026✔
1927
                return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
×
1928

1929
        if (streq(name, "TTYReset"))
1,026✔
1930
                return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
×
1931

1932
        if (streq(name, "TTYVTDisallocate"))
1,026✔
1933
                return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
×
1934

1935
        if (streq(name, "TTYRows"))
1,026✔
1936
                return bus_set_transient_unsigned(u, name, &c->tty_rows, message, flags, error);
×
1937

1938
        if (streq(name, "TTYColumns"))
1,026✔
1939
                return bus_set_transient_unsigned(u, name, &c->tty_cols, message, flags, error);
×
1940

1941
        if (streq(name, "PrivateTmp")) {
1,026✔
1942
                int v;
10✔
1943

1944
                r = sd_bus_message_read(message, "b", &v);
10✔
1945
                if (r < 0)
10✔
1946
                        return r;
10✔
1947

1948
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
10✔
1949
                        c->private_tmp = v ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_NO;
5✔
1950
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
5✔
1951
                }
1952

1953
                return 1;
10✔
1954

1955
        } else if (streq(name, "PrivateTmpEx")) {
1,016✔
1956
                const char *s;
×
1957
                PrivateTmp t;
×
1958

1959
                r = sd_bus_message_read(message, "s", &s);
×
1960
                if (r < 0)
×
1961
                        return r;
×
1962

1963
                t = private_tmp_from_string(s);
×
1964
                if (t < 0)
×
1965
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
1966

1967
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1968
                        c->private_tmp = t;
×
1969
                        (void) unit_write_settingf(u, flags, name, "PrivateTmp=%s",
×
1970
                                                   private_tmp_to_string(c->private_tmp));
1971
                }
1972

1973
                return 1;
×
1974
        }
1975

1976
        if (streq(name, "PrivateUsers")) {
1,016✔
1977
                int v;
8✔
1978

1979
                r = sd_bus_message_read(message, "b", &v);
8✔
1980
                if (r < 0)
8✔
1981
                        return r;
8✔
1982

1983
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
1984
                        c->private_users = v ? PRIVATE_USERS_SELF : PRIVATE_USERS_NO;
4✔
1985
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
4✔
1986
                }
1987

1988
                return 1;
8✔
1989

1990
        } else if (streq(name, "PrivateUsersEx")) {
1,008✔
1991
                const char *s;
18✔
1992
                PrivateUsers t;
18✔
1993

1994
                r = sd_bus_message_read(message, "s", &s);
18✔
1995
                if (r < 0)
18✔
1996
                        return r;
18✔
1997

1998
                t = private_users_from_string(s);
18✔
1999
                if (t < 0)
18✔
2000
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2001

2002
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
18✔
2003
                        c->private_users = t;
9✔
2004
                        (void) unit_write_settingf(u, flags, name, "PrivateUsers=%s",
9✔
2005
                                                   private_users_to_string(c->private_users));
2006
                }
2007

2008
                return 1;
18✔
2009
        }
2010

2011
        if (streq(name, "ProtectControlGroups")) {
990✔
2012
                int v;
×
2013

2014
                r = sd_bus_message_read(message, "b", &v);
×
2015
                if (r < 0)
×
2016
                        return r;
×
2017

2018
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2019
                        c->protect_control_groups = v ? PROTECT_CONTROL_GROUPS_YES : PROTECT_CONTROL_GROUPS_NO;
×
2020
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
×
2021
                }
2022

2023
                return 1;
×
2024
        }
2025

2026
        if (streq(name, "ProtectControlGroupsEx")) {
990✔
2027
                const char *s;
2✔
2028
                ProtectControlGroups t;
2✔
2029

2030
                r = sd_bus_message_read(message, "s", &s);
2✔
2031
                if (r < 0)
2✔
2032
                        return r;
2✔
2033

2034
                t = protect_control_groups_from_string(s);
2✔
2035
                if (t < 0)
2✔
2036
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2037

2038
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2039
                        c->protect_control_groups = t;
1✔
2040
                        (void) unit_write_settingf(u, flags, name, "ProtectControlGroups=%s",
1✔
2041
                                                   protect_control_groups_to_string(c->protect_control_groups));
2042
                }
2043

2044
                return 1;
2✔
2045
        }
2046

2047
        if (streq(name, "PrivatePIDs")) {
988✔
2048
                const char *s;
8✔
2049
                PrivatePIDs t;
8✔
2050

2051
                r = sd_bus_message_read(message, "s", &s);
8✔
2052
                if (r < 0)
8✔
2053
                        return r;
8✔
2054

2055
                t = private_pids_from_string(s);
8✔
2056
                if (t < 0)
8✔
2057
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2058

2059
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
2060
                        c->private_pids = t;
4✔
2061
                        (void) unit_write_settingf(u, flags, name, "%s=%s",
4✔
2062
                                                   name, private_pids_to_string(c->private_pids));
2063
                }
2064

2065
                return 1;
8✔
2066
        }
2067

2068
        if (streq(name, "ProtectHostname")) {
980✔
2069
                int v;
4✔
2070

2071
                r = sd_bus_message_read(message, "b", &v);
4✔
2072
                if (r < 0)
4✔
2073
                        return r;
4✔
2074

2075
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2076
                        c->protect_hostname = v ? PROTECT_HOSTNAME_YES : PROTECT_HOSTNAME_NO;
2✔
2077
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
2✔
2078
                }
2079

2080
                return 1;
4✔
2081

2082
        }
2083

2084
        if (streq(name, "ProtectHostnameEx")) {
976✔
2085
                const char *s, *h = NULL;
4✔
2086

2087
                r = sd_bus_message_read(message, "(ss)", &s, &h);
4✔
2088
                if (r < 0)
4✔
2089
                        return r;
4✔
2090

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

2094
                ProtectHostname t = protect_hostname_from_string(s);
4✔
2095
                if (t < 0 || (t == PROTECT_HOSTNAME_NO && !isempty(h)))
4✔
2096
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2097

2098
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2099
                        c->protect_hostname = t;
2✔
2100
                        r = free_and_strdup(&c->private_hostname, empty_to_null(h));
4✔
2101
                        if (r < 0)
2✔
2102
                                return r;
2103

2104
                        (void) unit_write_settingf(u, flags, name, "ProtectHostname=%s%s%s",
4✔
2105
                                                   protect_hostname_to_string(c->protect_hostname),
2106
                                                   c->private_hostname ? ":" : "",
2107
                                                   strempty(c->private_hostname));
2✔
2108
                }
2109

2110
                return 1;
4✔
2111
        }
2112

2113
        if (streq(name, "PrivateDevices"))
972✔
2114
                return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
4✔
2115

2116
        if (streq(name, "PrivateMounts"))
968✔
2117
                return bus_set_transient_tristate(u, name, &c->private_mounts, message, flags, error);
20✔
2118

2119
        if (streq(name, "MountAPIVFS"))
948✔
2120
                return bus_set_transient_tristate(u, name, &c->mount_apivfs, message, flags, error);
4✔
2121

2122
        if (streq(name, "BindLogSockets"))
944✔
2123
                return bus_set_transient_tristate(u, name, &c->bind_log_sockets, message, flags, error);
×
2124

2125
        if (streq(name, "PrivateNetwork"))
944✔
2126
                return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
8✔
2127

2128
        if (streq(name, "PrivateIPC"))
936✔
2129
                return bus_set_transient_bool(u, name, &c->private_ipc, message, flags, error);
4✔
2130

2131
        if (streq(name, "NoNewPrivileges"))
932✔
2132
                return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
2✔
2133

2134
        if (streq(name, "SyslogLevelPrefix"))
930✔
2135
                return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
×
2136

2137
        if (streq(name, "MemoryDenyWriteExecute"))
930✔
2138
                return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
×
2139

2140
        if (streq(name, "RestrictRealtime"))
930✔
2141
                return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
×
2142

2143
        if (streq(name, "RestrictSUIDSGID"))
930✔
2144
                return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
×
2145

2146
        if (streq(name, "DynamicUser"))
930✔
2147
                return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
2✔
2148

2149
        if (streq(name, "RemoveIPC"))
928✔
2150
                return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
×
2151

2152
        if (streq(name, "ProtectKernelTunables"))
928✔
2153
                return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
4✔
2154

2155
        if (streq(name, "ProtectKernelModules"))
924✔
2156
                return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
4✔
2157

2158
        if (streq(name, "ProtectKernelLogs"))
920✔
2159
                return bus_set_transient_bool(u, name, &c->protect_kernel_logs, message, flags, error);
2✔
2160

2161
        if (streq(name, "ProtectClock"))
918✔
2162
                return bus_set_transient_bool(u, name, &c->protect_clock, message, flags, error);
4✔
2163

2164
        if (streq(name, "CPUSchedulingResetOnFork"))
914✔
2165
                return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
×
2166

2167
        if (streq(name, "NonBlocking"))
914✔
2168
                return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
×
2169

2170
        if (streq(name, "LockPersonality"))
914✔
2171
                return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
2✔
2172

2173
        if (streq(name, "MemoryKSM"))
912✔
2174
                return bus_set_transient_tristate(u, name, &c->memory_ksm, message, flags, error);
×
2175

2176
        if (streq(name, "UtmpIdentifier"))
912✔
2177
                return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
×
2178

2179
        if (streq(name, "UtmpMode"))
912✔
2180
                return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
×
2181

2182
        if (streq(name, "PAMName"))
912✔
2183
                return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
10✔
2184

2185
        if (streq(name, "TimerSlackNSec"))
902✔
2186
                return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
×
2187

2188
        if (streq(name, "ProtectSystem"))
902✔
2189
                return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
2✔
2190

2191
        if (streq(name, "ProtectHome"))
900✔
2192
                return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
6✔
2193

2194
        if (streq(name, "KeyringMode"))
894✔
2195
                return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
×
2196

2197
        if (streq(name, "ProtectProc"))
894✔
2198
                return bus_set_transient_protect_proc(u, name, &c->protect_proc, message, flags, error);
10✔
2199

2200
        if (streq(name, "ProcSubset"))
884✔
2201
                return bus_set_transient_proc_subset(u, name, &c->proc_subset, message, flags, error);
6✔
2202

2203
        if (streq(name, "RuntimeDirectoryPreserve"))
878✔
2204
                return bus_set_transient_exec_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
10✔
2205

2206
        if (streq(name, "UMask"))
868✔
2207
                return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
×
2208

2209
        if (streq(name, "RuntimeDirectoryMode"))
868✔
2210
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
×
2211

2212
        if (streq(name, "StateDirectoryMode"))
868✔
2213
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
10✔
2214

2215
        if (streq(name, "CacheDirectoryMode"))
858✔
2216
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
20✔
2217

2218
        if (streq(name, "LogsDirectoryMode"))
838✔
2219
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
×
2220

2221
        if (streq(name, "ConfigurationDirectoryMode"))
838✔
2222
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
10✔
2223

2224
        if (streq(name, "SELinuxContext"))
828✔
2225
                return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
×
2226

2227
        if (streq(name, "SecureBits"))
828✔
2228
                return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
×
2229

2230
        if (streq(name, "CapabilityBoundingSet"))
828✔
2231
                return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
2✔
2232

2233
        if (streq(name, "AmbientCapabilities"))
826✔
2234
                return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
8✔
2235

2236
        if (streq(name, "RestrictNamespaces"))
818✔
2237
                return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
×
2238

2239
        if (streq(name, "DelegateNamespaces"))
818✔
2240
                return bus_set_transient_namespace_flag(u, name, &c->delegate_namespaces, message, flags, error);
18✔
2241

2242
        if (streq(name, "RestrictFileSystems")) {
800✔
2243
                int allow_list;
×
2244
                _cleanup_strv_free_ char **l = NULL;
×
2245

2246
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2247
                if (r < 0)
×
2248
                        return r;
2249

2250
                r = sd_bus_message_read(message, "b", &allow_list);
×
2251
                if (r < 0)
×
2252
                        return r;
2253

2254
                r = sd_bus_message_read_strv(message, &l);
×
2255
                if (r < 0)
×
2256
                        return r;
2257

2258
                r = sd_bus_message_exit_container(message);
×
2259
                if (r < 0)
×
2260
                        return r;
2261

2262
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2263
                        _cleanup_free_ char *joined = NULL;
×
2264
                        FilesystemParseFlags invert_flag = allow_list ? 0 : FILESYSTEM_PARSE_INVERT;
×
2265

2266
                        if (strv_isempty(l)) {
×
2267
                                c->restrict_filesystems_allow_list = false;
×
2268
                                c->restrict_filesystems = set_free(c->restrict_filesystems);
×
2269

2270
                                unit_write_setting(u, flags, name, "RestrictFileSystems=");
×
2271
                                return 1;
2272
                        }
2273

2274
                        if (!c->restrict_filesystems)
×
2275
                                c->restrict_filesystems_allow_list = allow_list;
×
2276

2277
                        STRV_FOREACH(s, l) {
×
2278
                                r = bpf_restrict_fs_parse_filesystem(
×
2279
                                              *s,
2280
                                              &c->restrict_filesystems,
2281
                                              FILESYSTEM_PARSE_LOG|
×
2282
                                              (invert_flag ? FILESYSTEM_PARSE_INVERT : 0)|
×
2283
                                              (c->restrict_filesystems_allow_list ? FILESYSTEM_PARSE_ALLOW_LIST : 0),
×
2284
                                              u->id, NULL, 0);
×
2285
                                if (r < 0)
×
2286
                                        return r;
2287
                        }
2288

2289
                        joined = strv_join(l, " ");
×
2290
                        if (!joined)
×
2291
                                return -ENOMEM;
2292

2293
                        unit_write_settingf(u, flags, name, "%s=%s%s", name, allow_list ? "" : "~", joined);
×
2294
                }
2295

2296
                return 1;
×
2297
        }
2298

2299
        if (streq(name, "MountFlags"))
800✔
2300
                return bus_set_transient_mount_propagation_flag(u, name, &c->mount_propagation_flag, message, flags, error);
2✔
2301

2302
        if (streq(name, "NetworkNamespacePath"))
798✔
2303
                return bus_set_transient_path(u, name, &c->network_namespace_path, message, flags, error);
×
2304

2305
        if (streq(name, "IPCNamespacePath"))
798✔
2306
                return bus_set_transient_path(u, name, &c->ipc_namespace_path, message, flags, error);
×
2307

2308
        if (streq(name, "SupplementaryGroups")) {
798✔
2309
                _cleanup_strv_free_ char **l = NULL;
×
2310

2311
                r = sd_bus_message_read_strv(message, &l);
×
2312
                if (r < 0)
×
2313
                        return r;
2314

2315
                STRV_FOREACH(p, l)
×
2316
                        if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN))
×
2317
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
2318
                                                         "Invalid supplementary group names");
2319

2320
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2321
                        if (strv_isempty(l)) {
×
2322
                                c->supplementary_groups = strv_free(c->supplementary_groups);
×
2323
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2324
                        } else {
2325
                                _cleanup_free_ char *joined = NULL;
×
2326

2327
                                r = strv_extend_strv(&c->supplementary_groups, l, true);
×
2328
                                if (r < 0)
×
2329
                                        return r;
2330

2331
                                joined = strv_join(c->supplementary_groups, " ");
×
2332
                                if (!joined)
×
2333
                                        return -ENOMEM;
2334

2335
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
×
2336
                        }
2337
                }
2338

2339
                return 1;
×
2340

2341
        } else if (STR_IN_SET(name, "SetCredential", "SetCredentialEncrypted")) {
798✔
2342
                bool isempty = true;
×
2343

2344
                r = sd_bus_message_enter_container(message, 'a', "(say)");
×
2345
                if (r < 0)
×
2346
                        return r;
4✔
2347

2348
                for (;;) {
×
2349
                        const char *id;
×
2350
                        const void *p;
×
2351
                        size_t sz;
×
2352

2353
                        r = sd_bus_message_enter_container(message, 'r', "say");
×
2354
                        if (r < 0)
×
2355
                                return r;
×
2356
                        if (r == 0)
×
2357
                                break;
2358

2359
                        r = sd_bus_message_read(message, "s", &id);
×
2360
                        if (r < 0)
×
2361
                                return r;
2362

2363
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2364
                        if (r < 0)
×
2365
                                return r;
2366

2367
                        r = sd_bus_message_exit_container(message);
×
2368
                        if (r < 0)
×
2369
                                return r;
2370

2371
                        if (!credential_name_valid(id))
×
2372
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2373

2374
                        isempty = false;
×
2375

2376
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2377
                                bool encrypted = endswith(name, "Encrypted");
×
2378
                                _cleanup_free_ char *a = NULL, *b = NULL;
×
2379
                                _cleanup_free_ void *copy = NULL;
×
2380

2381
                                copy = memdup(p, sz);
×
2382
                                if (!copy)
×
2383
                                        return -ENOMEM;
2384

2385
                                a = specifier_escape(id);
×
2386
                                if (!a)
×
2387
                                        return -ENOMEM;
2388

2389
                                b = cescape_length(p, sz);
×
2390
                                if (!b)
×
2391
                                        return -ENOMEM;
2392

2393
                                r = exec_context_put_set_credential(c, id, TAKE_PTR(copy), sz, encrypted);
×
2394
                                if (r < 0)
×
2395
                                        return r;
2396

2397
                                (void) unit_write_settingf(u, flags, name, "%s=%s:%s", name, a, b);
×
2398
                        }
2399
                }
2400

2401
                r = sd_bus_message_exit_container(message);
×
2402
                if (r < 0)
×
2403
                        return r;
2404

2405
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
×
2406
                        c->set_credentials = hashmap_free(c->set_credentials);
×
2407
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2408
                }
2409

2410
                return 1;
×
2411

2412
        } else if (STR_IN_SET(name, "LoadCredential", "LoadCredentialEncrypted")) {
798✔
2413
                bool isempty = true;
2✔
2414

2415
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
2✔
2416
                if (r < 0)
2✔
2417
                        return r;
4✔
2418

2419
                for (;;) {
2✔
2420
                        const char *id, *source;
4✔
2421

2422
                        r = sd_bus_message_read(message, "(ss)", &id, &source);
4✔
2423
                        if (r < 0)
4✔
2424
                                return r;
×
2425
                        if (r == 0)
4✔
2426
                                break;
2427

2428
                        if (!credential_name_valid(id))
2✔
2429
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2430

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

2434
                        isempty = false;
2✔
2435

2436
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2437
                                bool encrypted = endswith(name, "Encrypted");
1✔
2438

2439
                                r = exec_context_put_load_credential(c, id, source, encrypted);
1✔
2440
                                if (r < 0)
1✔
2441
                                        return r;
2442

2443
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s:%s", name, id, source);
1✔
2444
                        }
2445
                }
2446

2447
                r = sd_bus_message_exit_container(message);
2✔
2448
                if (r < 0)
2✔
2449
                        return r;
2450

2451
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
2✔
2452
                        c->load_credentials = hashmap_free(c->load_credentials);
×
2453
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2454
                }
2455

2456
                return 1;
2✔
2457

2458
        } else if (STR_IN_SET(name, "ImportCredential", "ImportCredentialEx")) {
796✔
2459
                bool empty = true, ex = streq(name, "ImportCredentialEx");
2✔
2460

2461
                r = sd_bus_message_enter_container(message, 'a', ex ? "(ss)" : "s");
4✔
2462
                if (r < 0)
2✔
2463
                        return r;
2✔
2464

2465
                for (;;) {
2✔
2466
                        const char *glob, *rename = NULL;
4✔
2467

2468
                        if (ex)
4✔
2469
                                r = sd_bus_message_read(message, "(ss)", &glob, &rename);
×
2470
                        else
2471
                                r = sd_bus_message_read(message, "s", &glob);
4✔
2472
                        if (r < 0)
4✔
2473
                                return r;
×
2474
                        if (r == 0)
4✔
2475
                                break;
2476

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

2480
                        rename = empty_to_null(rename);
2✔
2481

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

2485
                        empty = false;
2✔
2486

2487
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2488
                                r = exec_context_put_import_credential(c, glob, rename);
1✔
2489
                                if (r < 0)
1✔
2490
                                        return r;
2491

2492
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
3✔
2493
                                                           "ImportCredential=%s%s%s",
2494
                                                           glob, rename ? ":" : "", strempty(rename));
2495
                        }
2496
                }
2497

2498
                r = sd_bus_message_exit_container(message);
2✔
2499
                if (r < 0)
2✔
2500
                        return r;
2501

2502
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
2✔
2503
                        c->import_credentials = ordered_set_free(c->import_credentials);
×
2504
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2505
                }
2506

2507
                return 1;
2✔
2508

2509
        } else if (streq(name, "SyslogLevel")) {
794✔
2510
                int32_t level;
×
2511

2512
                r = sd_bus_message_read(message, "i", &level);
×
2513
                if (r < 0)
×
2514
                        return r;
×
2515

2516
                if (!log_level_is_valid(level))
×
2517
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
×
2518

2519
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2520
                        c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
×
2521
                        unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
×
2522
                }
2523

2524
                return 1;
×
2525

2526
        } else if (streq(name, "SyslogFacility")) {
794✔
2527
                int32_t facility;
×
2528

2529
                r = sd_bus_message_read(message, "i", &facility);
×
2530
                if (r < 0)
×
2531
                        return r;
×
2532

2533
                if (!log_facility_unshifted_is_valid(facility))
×
2534
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
×
2535

2536
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2537
                        c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
×
2538
                        unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
×
2539
                }
2540

2541
                return 1;
×
2542

2543
        } else if (streq(name, "LogNamespace")) {
794✔
2544
                const char *n;
×
2545

2546
                r = sd_bus_message_read(message, "s", &n);
×
2547
                if (r < 0)
×
2548
                        return r;
×
2549

2550
                if (!isempty(n) && !log_namespace_name_valid(n))
×
2551
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log namespace name not valid");
×
2552

2553
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2554

2555
                        if (isempty(n)) {
×
2556
                                c->log_namespace = mfree(c->log_namespace);
×
2557
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2558
                        } else {
2559
                                r = free_and_strdup(&c->log_namespace, n);
×
2560
                                if (r < 0)
×
2561
                                        return r;
2562

2563
                                unit_write_settingf(u, flags, name, "%s=%s", name, n);
×
2564
                        }
2565
                }
2566

2567
                return 1;
×
2568

2569
        } else if (streq(name, "LogExtraFields")) {
794✔
2570
                size_t n = 0;
×
2571

2572
                r = sd_bus_message_enter_container(message, 'a', "ay");
×
2573
                if (r < 0)
×
2574
                        return r;
2575

2576
                for (;;) {
×
2577
                        _cleanup_free_ void *copy = NULL;
×
2578
                        const char *eq;
×
2579
                        const void *p;
×
2580
                        size_t sz;
×
2581

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

2589
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2590
                        if (r < 0)
×
2591
                                return r;
2592
                        if (r == 0)
×
2593
                                break;
2594

2595
                        if (memchr(p, 0, sz))
×
2596
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
×
2597

2598
                        eq = memchr(p, '=', sz);
×
2599
                        if (!eq)
×
2600
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
×
2601
                        if (!journal_field_valid(p, eq - (const char*) p, false))
×
2602
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
×
2603

2604
                        copy = memdup_suffix0(p, sz);
×
2605
                        if (!copy)
×
2606
                                return -ENOMEM;
2607

2608
                        if (!utf8_is_valid(copy))
×
2609
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
×
2610

2611
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2612
                                if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
×
2613
                                        return -ENOMEM;
2614

2615
                                c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
×
2616
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
×
2617
                                TAKE_PTR(copy);
2618
                        }
2619

2620
                        n++;
×
2621
                }
2622

2623
                r = sd_bus_message_exit_container(message);
×
2624
                if (r < 0)
×
2625
                        return r;
2626

2627
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
×
2628
                        exec_context_free_log_extra_fields(c);
×
2629
                        unit_write_setting(u, flags, name, "LogExtraFields=");
×
2630
                }
2631

2632
                return 1;
×
2633
        }
2634

2635
#if HAVE_SECCOMP
2636

2637
        if (streq(name, "SystemCallErrorNumber"))
794✔
2638
                return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
×
2639

2640
        if (streq(name, "SystemCallFilter")) {
794✔
2641
                int allow_list;
×
2642
                _cleanup_strv_free_ char **l = NULL;
×
2643

2644
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2645
                if (r < 0)
×
2646
                        return r;
2647

2648
                r = sd_bus_message_read(message, "b", &allow_list);
×
2649
                if (r < 0)
×
2650
                        return r;
2651

2652
                r = sd_bus_message_read_strv(message, &l);
×
2653
                if (r < 0)
×
2654
                        return r;
2655

2656
                r = sd_bus_message_exit_container(message);
×
2657
                if (r < 0)
×
2658
                        return r;
2659

2660
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2661
                        _cleanup_free_ char *joined = NULL;
×
2662
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2663

2664
                        if (strv_isempty(l)) {
×
2665
                                c->syscall_allow_list = false;
×
2666
                                c->syscall_filter = hashmap_free(c->syscall_filter);
×
2667

2668
                                unit_write_settingf(u, flags, name, "SystemCallFilter=");
×
2669
                                return 1;
2670
                        }
2671

2672
                        if (!c->syscall_filter) {
×
2673
                                c->syscall_filter = hashmap_new(NULL);
×
2674
                                if (!c->syscall_filter)
×
2675
                                        return log_oom();
×
2676

2677
                                c->syscall_allow_list = allow_list;
×
2678

2679
                                if (c->syscall_allow_list) {
×
2680
                                        r = seccomp_parse_syscall_filter("@default",
×
2681
                                                                         -1,
2682
                                                                         c->syscall_filter,
2683
                                                                         SECCOMP_PARSE_PERMISSIVE |
2684
                                                                         SECCOMP_PARSE_ALLOW_LIST,
2685
                                                                         u->id,
×
2686
                                                                         NULL, 0);
2687
                                        if (r < 0)
×
2688
                                                return r;
2689
                                }
2690
                        }
2691

2692
                        STRV_FOREACH(s, l) {
×
2693
                                _cleanup_free_ char *n = NULL;
×
2694
                                int e;
×
2695

2696
                                r = parse_syscall_and_errno(*s, &n, &e);
×
2697
                                if (r < 0)
×
2698
                                        return r;
2699

2700
                                if (allow_list && e >= 0)
×
2701
                                        return -EINVAL;
2702

2703
                                r = seccomp_parse_syscall_filter(n,
×
2704
                                                                 e,
2705
                                                                 c->syscall_filter,
2706
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2707
                                                                 invert_flag |
×
2708
                                                                 (c->syscall_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2709
                                                                 u->id,
×
2710
                                                                 NULL, 0);
2711
                                if (r < 0)
×
2712
                                        return r;
2713
                        }
2714

2715
                        joined = strv_join(l, " ");
×
2716
                        if (!joined)
×
2717
                                return -ENOMEM;
2718

2719
                        unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", allow_list ? "" : "~", joined);
×
2720
                }
2721

2722
                return 1;
×
2723

2724
        } else if (streq(name, "SystemCallLog")) {
794✔
2725
                int allow_list;
×
2726
                _cleanup_strv_free_ char **l = NULL;
×
2727

2728
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2729
                if (r < 0)
×
2730
                        return r;
2731

2732
                r = sd_bus_message_read(message, "b", &allow_list);
×
2733
                if (r < 0)
×
2734
                        return r;
2735

2736
                r = sd_bus_message_read_strv(message, &l);
×
2737
                if (r < 0)
×
2738
                        return r;
2739

2740
                r = sd_bus_message_exit_container(message);
×
2741
                if (r < 0)
×
2742
                        return r;
2743

2744
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2745
                        _cleanup_free_ char *joined = NULL;
×
2746
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2747

2748
                        if (strv_isempty(l)) {
×
2749
                                c->syscall_log_allow_list = false;
×
2750
                                c->syscall_log = hashmap_free(c->syscall_log);
×
2751

2752
                                unit_write_settingf(u, flags, name, "SystemCallLog=");
×
2753
                                return 1;
2754
                        }
2755

2756
                        if (!c->syscall_log) {
×
2757
                                c->syscall_log = hashmap_new(NULL);
×
2758
                                if (!c->syscall_log)
×
2759
                                        return log_oom();
×
2760

2761
                                c->syscall_log_allow_list = allow_list;
×
2762
                        }
2763

2764
                        STRV_FOREACH(s, l) {
×
2765
                                r = seccomp_parse_syscall_filter(*s,
×
2766
                                                                 -1, /* errno not used */
2767
                                                                 c->syscall_log,
2768
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2769
                                                                 invert_flag |
×
2770
                                                                 (c->syscall_log_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2771
                                                                 u->id,
×
2772
                                                                 NULL, 0);
2773
                                if (r < 0)
×
2774
                                        return r;
2775
                        }
2776

2777
                        joined = strv_join(l, " ");
×
2778
                        if (!joined)
×
2779
                                return -ENOMEM;
2780

2781
                        unit_write_settingf(u, flags, name, "SystemCallLog=%s%s", allow_list ? "" : "~", joined);
×
2782
                }
2783

2784
                return 1;
×
2785

2786
        } else if (streq(name, "SystemCallArchitectures")) {
794✔
2787
                _cleanup_strv_free_ char **l = NULL;
×
2788

2789
                r = sd_bus_message_read_strv(message, &l);
×
2790
                if (r < 0)
×
2791
                        return r;
2792

2793
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2794
                        _cleanup_free_ char *joined = NULL;
×
2795

2796
                        if (strv_isempty(l))
×
2797
                                c->syscall_archs = set_free(c->syscall_archs);
×
2798
                        else {
2799
                                r = parse_syscall_archs(l, &c->syscall_archs);
×
2800
                                if (r < 0)
×
2801
                                        return r;
2802
                        }
2803

2804
                        joined = strv_join(l, " ");
×
2805
                        if (!joined)
×
2806
                                return -ENOMEM;
2807

2808
                        unit_write_settingf(u, flags, name, "%s=%s", name, joined);
×
2809
                }
2810

2811
                return 1;
×
2812

2813
        } else if (streq(name, "RestrictAddressFamilies")) {
794✔
2814
                _cleanup_strv_free_ char **l = NULL;
×
2815
                int allow_list;
×
2816

2817
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2818
                if (r < 0)
×
2819
                        return r;
2820

2821
                r = sd_bus_message_read(message, "b", &allow_list);
×
2822
                if (r < 0)
×
2823
                        return r;
2824

2825
                r = sd_bus_message_read_strv(message, &l);
×
2826
                if (r < 0)
×
2827
                        return r;
2828

2829
                r = sd_bus_message_exit_container(message);
×
2830
                if (r < 0)
×
2831
                        return r;
2832

2833
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2834
                        _cleanup_free_ char *joined = NULL;
×
2835

2836
                        if (strv_isempty(l)) {
×
2837
                                c->address_families_allow_list = allow_list;
×
2838
                                c->address_families = set_free(c->address_families);
×
2839

2840
                                unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s",
×
2841
                                                    allow_list ? "none" : "");
×
2842
                                return 1;
2843
                        }
2844

2845
                        if (!c->address_families) {
×
2846
                                c->address_families = set_new(NULL);
×
2847
                                if (!c->address_families)
×
2848
                                        return log_oom();
×
2849

2850
                                c->address_families_allow_list = allow_list;
×
2851
                        }
2852

2853
                        STRV_FOREACH(s, l) {
×
2854
                                int af;
×
2855

2856
                                af = af_from_name(*s);
×
2857
                                if (af < 0)
×
2858
                                        return af;
2859

2860
                                if (allow_list == c->address_families_allow_list) {
×
2861
                                        r = set_put(c->address_families, INT_TO_PTR(af));
×
2862
                                        if (r < 0)
×
2863
                                                return r;
2864
                                } else
2865
                                        set_remove(c->address_families, INT_TO_PTR(af));
×
2866
                        }
2867

2868
                        joined = strv_join(l, " ");
×
2869
                        if (!joined)
×
2870
                                return -ENOMEM;
2871

2872
                        unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", allow_list ? "" : "~", joined);
×
2873
                }
2874

2875
                return 1;
×
2876
        }
2877
#endif
2878
        if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
794✔
2879
                const void *a;
×
2880
                size_t n;
×
2881
                bool affinity = streq(name, "CPUAffinity");
×
2882
                _cleanup_(cpu_set_reset) CPUSet set = {};
×
2883

2884
                r = sd_bus_message_read_array(message, 'y', &a, &n);
×
2885
                if (r < 0)
×
2886
                        return r;
2887

2888
                r = cpu_set_from_dbus(a, n, &set);
×
2889
                if (r < 0)
×
2890
                        return r;
2891

2892
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2893
                        if (n == 0) {
×
2894
                                cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
×
2895
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2896
                        } else {
2897
                                _cleanup_free_ char *str = NULL;
×
2898

2899
                                str = cpu_set_to_string(&set);
×
2900
                                if (!str)
×
2901
                                        return -ENOMEM;
2902

2903
                                /* We forego any optimizations here, and always create the structure using
2904
                                 * cpu_set_add_all(), because we don't want to care if the existing size we
2905
                                 * got over dbus is appropriate. */
2906
                                r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
×
2907
                                if (r < 0)
×
2908
                                        return r;
2909

2910
                                unit_write_settingf(u, flags, name, "%s=%s", name, str);
×
2911
                        }
2912
                }
2913

2914
                return 1;
×
2915

2916
        } else if (streq(name, "CPUAffinityFromNUMA")) {
794✔
2917
                int q;
×
2918

2919
                r = sd_bus_message_read_basic(message, 'b', &q);
×
2920
                if (r < 0)
×
2921
                        return r;
×
2922

2923
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2924
                        c->cpu_affinity_from_numa = q;
×
2925
                        unit_write_settingf(u, flags, name, "%s=%s", "CPUAffinity", "numa");
×
2926
                }
2927

2928
                return 1;
×
2929

2930
        } else if (streq(name, "NUMAPolicy")) {
794✔
2931
                int32_t type;
×
2932

2933
                r = sd_bus_message_read(message, "i", &type);
×
2934
                if (r < 0)
×
2935
                        return r;
×
2936

2937
                if (!mpol_is_valid(type))
×
2938
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
×
2939

2940
                if (!UNIT_WRITE_FLAGS_NOOP(flags))
×
2941
                        c->numa_policy.type = type;
×
2942

2943
                return 1;
×
2944

2945
        } else if (streq(name, "Nice")) {
794✔
2946
                int32_t q;
×
2947

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

2952
                if (!nice_is_valid(q))
×
2953
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
×
2954

2955
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2956
                        c->nice = q;
×
2957
                        c->nice_set = true;
×
2958

2959
                        unit_write_settingf(u, flags, name, "Nice=%i", q);
×
2960
                }
2961

2962
                return 1;
×
2963

2964
        } else if (streq(name, "CPUSchedulingPolicy")) {
794✔
2965
                int32_t q;
×
2966

2967
                r = sd_bus_message_read(message, "i", &q);
×
2968
                if (r < 0)
×
2969
                        return r;
×
2970

2971
                if (!sched_policy_is_valid(q))
×
2972
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
×
2973

2974
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2975
                        _cleanup_free_ char *s = NULL;
×
2976

2977
                        r = sched_policy_to_string_alloc(q, &s);
×
2978
                        if (r < 0)
×
2979
                                return r;
×
2980

2981
                        c->cpu_sched_policy = q;
×
2982
                        c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
×
2983
                        c->cpu_sched_set = true;
×
2984

2985
                        unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
×
2986
                }
2987

2988
                return 1;
×
2989

2990
        } else if (streq(name, "CPUSchedulingPriority")) {
794✔
2991
                int32_t p;
×
2992

2993
                r = sd_bus_message_read(message, "i", &p);
×
2994
                if (r < 0)
×
2995
                        return r;
×
2996

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

3002
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3003
                        c->cpu_sched_priority = p;
×
3004
                        c->cpu_sched_set = true;
×
3005

3006
                        unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
×
3007
                }
3008

3009
                return 1;
×
3010

3011
        } else if (streq(name, "IOSchedulingClass")) {
794✔
3012
                int32_t q;
×
3013

3014
                r = sd_bus_message_read(message, "i", &q);
×
3015
                if (r < 0)
×
3016
                        return r;
×
3017

3018
                if (!ioprio_class_is_valid(q))
×
3019
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
×
3020

3021
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3022
                        _cleanup_free_ char *s = NULL;
×
3023

3024
                        r = ioprio_class_to_string_alloc(q, &s);
×
3025
                        if (r < 0)
×
3026
                                return r;
×
3027

3028
                        c->ioprio = ioprio_normalize(ioprio_prio_value(q, ioprio_prio_data(c->ioprio)));
×
3029
                        c->ioprio_set = true;
×
3030

3031
                        unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
×
3032
                }
3033

3034
                return 1;
×
3035

3036
        } else if (streq(name, "IOSchedulingPriority")) {
794✔
3037
                int32_t p;
×
3038

3039
                r = sd_bus_message_read(message, "i", &p);
×
3040
                if (r < 0)
×
3041
                        return r;
×
3042

3043
                if (!ioprio_priority_is_valid(p))
×
3044
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
×
3045

3046
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3047
                        c->ioprio = ioprio_normalize(ioprio_prio_value(ioprio_prio_class(c->ioprio), p));
×
3048
                        c->ioprio_set = true;
×
3049

3050
                        unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
×
3051
                }
3052

3053
                return 1;
×
3054

3055
        } else if (streq(name, "WorkingDirectory")) {
794✔
3056
                _cleanup_free_ char *simplified = NULL;
×
3057
                bool missing_ok = false, is_home = false;
×
3058
                const char *s;
×
3059

3060
                r = sd_bus_message_read(message, "s", &s);
×
3061
                if (r < 0)
×
3062
                        return r;
3063

3064
                if (!isempty(s)) {
×
3065
                        if (s[0] == '-') {
×
3066
                                missing_ok = true;
×
3067
                                s++;
×
3068
                        }
3069

3070
                        if (streq(s, "~"))
×
3071
                                is_home = true;
3072
                        else {
3073
                                if (!path_is_absolute(s))
×
3074
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3075
                                                                "WorkingDirectory= expects an absolute path or '~'");
3076

3077
                                r = path_simplify_alloc(s, &simplified);
×
3078
                                if (r < 0)
×
3079
                                        return r;
3080

3081
                                if (!path_is_normalized(simplified))
×
3082
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3083
                                                                "WorkingDirectory= expects a normalized path or '~'");
3084
                        }
3085
                }
3086

3087
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3088
                        free_and_replace(c->working_directory, simplified);
×
3089
                        c->working_directory_home = is_home;
×
3090
                        c->working_directory_missing_ok = missing_ok;
×
3091

3092
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
3093
                                            "WorkingDirectory=%s%s",
3094
                                            c->working_directory_missing_ok ? "-" : "",
×
3095
                                            c->working_directory_home ? "~" : strempty(c->working_directory));
×
3096
                }
3097

3098
                return 1;
×
3099

3100
        } else if (STR_IN_SET(name,
794✔
3101
                              "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
3102
                const char *s;
×
3103

3104
                r = sd_bus_message_read(message, "s", &s);
×
3105
                if (r < 0)
×
3106
                        return r;
×
3107

3108
                if (!isempty(s) && !fdname_is_valid(s))
×
3109
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
×
3110

3111
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3112

3113
                        if (streq(name, "StandardInputFileDescriptorName")) {
×
3114
                                r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s));
×
3115
                                if (r < 0)
×
3116
                                        return r;
3117

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

3121
                        } else if (streq(name, "StandardOutputFileDescriptorName")) {
×
3122
                                r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s));
×
3123
                                if (r < 0)
×
3124
                                        return r;
3125

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

3129
                        } else {
3130
                                assert(streq(name, "StandardErrorFileDescriptorName"));
×
3131

3132
                                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s));
×
3133
                                if (r < 0)
×
3134
                                        return r;
3135

3136
                                c->std_error = EXEC_OUTPUT_NAMED_FD;
×
3137
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
×
3138
                        }
3139
                }
3140

3141
                return 1;
×
3142

3143
        } else if (STR_IN_SET(name,
794✔
3144
                              "StandardInputFile",
3145
                              "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate",
3146
                              "StandardErrorFile", "StandardErrorFileToAppend", "StandardErrorFileToTruncate")) {
3147
                const char *s;
×
3148

3149
                r = sd_bus_message_read(message, "s", &s);
×
3150
                if (r < 0)
×
3151
                        return r;
×
3152

3153
                if (!isempty(s)) {
×
3154
                        if (!path_is_absolute(s))
×
3155
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
×
3156
                        if (!path_is_normalized(s))
×
3157
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
×
3158
                }
3159

3160
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3161

3162
                        if (streq(name, "StandardInputFile")) {
×
3163
                                r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s));
×
3164
                                if (r < 0)
×
3165
                                        return r;
3166

3167
                                c->std_input = EXEC_INPUT_FILE;
×
3168
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
×
3169

3170
                        } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate")) {
×
3171
                                r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
×
3172
                                if (r < 0)
×
3173
                                        return r;
×
3174

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

3189
                                r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
×
3190
                                if (r < 0)
×
3191
                                        return r;
3192

3193
                                if (streq(name, "StandardErrorFile")) {
×
3194
                                        c->std_error = EXEC_OUTPUT_FILE;
×
3195
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
×
3196
                                } else if (streq(name, "StandardErrorFileToAppend")) {
×
3197
                                        c->std_error = EXEC_OUTPUT_FILE_APPEND;
×
3198
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
×
3199
                                } else {
3200
                                        assert(streq(name, "StandardErrorFileToTruncate"));
×
3201
                                        c->std_error = EXEC_OUTPUT_FILE_TRUNCATE;
×
3202
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=truncate:%s", s);
×
3203
                                }
3204
                        }
3205
                }
3206

3207
                return 1;
×
3208

3209
        } else if (streq(name, "StandardInputData")) {
794✔
3210
                const void *p;
×
3211
                size_t sz;
×
3212

3213
                r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
3214
                if (r < 0)
×
3215
                        return r;
×
3216

3217
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3218
                        _cleanup_free_ char *encoded = NULL;
×
3219

3220
                        if (sz == 0) {
×
3221
                                c->stdin_data = mfree(c->stdin_data);
×
3222
                                c->stdin_data_size = 0;
×
3223

3224
                                unit_write_settingf(u, flags, name, "StandardInputData=");
×
3225
                        } else {
3226
                                void *q;
×
3227
                                ssize_t n;
×
3228

3229
                                if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
×
3230
                                    c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
3231
                                        return -E2BIG;
3232

3233
                                n = base64mem(p, sz, &encoded);
×
3234
                                if (n < 0)
×
3235
                                        return (int) n;
×
3236

3237
                                q = realloc(c->stdin_data, c->stdin_data_size + sz);
×
3238
                                if (!q)
×
3239
                                        return -ENOMEM;
3240

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

3243
                                c->stdin_data = q;
×
3244
                                c->stdin_data_size += sz;
×
3245

3246
                                unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
×
3247
                        }
3248
                }
3249

3250
                return 1;
×
3251

3252
        } else if (streq(name, "Environment")) {
794✔
3253

3254
                _cleanup_strv_free_ char **l = NULL;
14✔
3255

3256
                r = sd_bus_message_read_strv(message, &l);
14✔
3257
                if (r < 0)
14✔
3258
                        return r;
3259

3260
                if (!strv_env_is_valid(l))
14✔
3261
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
×
3262

3263
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
3264
                        if (strv_isempty(l)) {
7✔
3265
                                c->environment = strv_free(c->environment);
×
3266
                                unit_write_setting(u, flags, name, "Environment=");
×
3267
                        } else {
3268
                                _cleanup_free_ char *joined = NULL;
7✔
3269
                                char **e;
7✔
3270

3271
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
7✔
3272
                                if (!joined)
7✔
3273
                                        return -ENOMEM;
3274

3275
                                e = strv_env_merge(c->environment, l);
7✔
3276
                                if (!e)
7✔
3277
                                        return -ENOMEM;
3278

3279
                                strv_free_and_replace(c->environment, e);
7✔
3280
                                unit_write_settingf(u, flags, name, "Environment=%s", joined);
7✔
3281
                        }
3282
                }
3283

3284
                return 1;
14✔
3285

3286
        } else if (streq(name, "UnsetEnvironment")) {
780✔
3287

3288
                _cleanup_strv_free_ char **l = NULL;
×
3289

3290
                r = sd_bus_message_read_strv(message, &l);
×
3291
                if (r < 0)
×
3292
                        return r;
3293

3294
                if (!strv_env_name_or_assignment_is_valid(l))
×
3295
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
×
3296

3297
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3298
                        if (strv_isempty(l)) {
×
3299
                                c->unset_environment = strv_free(c->unset_environment);
×
3300
                                unit_write_setting(u, flags, name, "UnsetEnvironment=");
×
3301
                        } else {
3302
                                _cleanup_free_ char *joined = NULL;
×
3303
                                char **e;
×
3304

3305
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
×
3306
                                if (!joined)
×
3307
                                        return -ENOMEM;
3308

3309
                                e = strv_env_merge(c->unset_environment, l);
×
3310
                                if (!e)
×
3311
                                        return -ENOMEM;
3312

3313
                                strv_free_and_replace(c->unset_environment, e);
×
3314
                                unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
×
3315
                        }
3316
                }
3317

3318
                return 1;
×
3319

3320
        } else if (streq(name, "OOMScoreAdjust")) {
780✔
3321
                int oa;
×
3322

3323
                r = sd_bus_message_read(message, "i", &oa);
×
3324
                if (r < 0)
×
3325
                        return r;
×
3326

3327
                if (!oom_score_adjust_is_valid(oa))
×
3328
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
×
3329

3330
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3331
                        c->oom_score_adjust = oa;
×
3332
                        c->oom_score_adjust_set = true;
×
3333
                        unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
×
3334
                }
3335

3336
                return 1;
×
3337

3338
        } else if (streq(name, "CoredumpFilter")) {
780✔
3339
                uint64_t f;
×
3340

3341
                r = sd_bus_message_read(message, "t", &f);
×
3342
                if (r < 0)
×
3343
                        return r;
×
3344

3345
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3346
                        c->coredump_filter = f;
×
3347
                        c->coredump_filter_set = true;
×
3348
                        unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f);
×
3349
                }
3350

3351
                return 1;
×
3352

3353
        } else if (streq(name, "EnvironmentFiles")) {
780✔
3354
                _cleanup_(memstream_done) MemStream m = {};
×
3355
                _cleanup_free_ char *joined = NULL;
4✔
3356
                _cleanup_strv_free_ char **l = NULL;
4✔
3357
                FILE *f;
4✔
3358

3359
                r = sd_bus_message_enter_container(message, 'a', "(sb)");
4✔
3360
                if (r < 0)
4✔
3361
                        return r;
3362

3363
                f = memstream_init(&m);
4✔
3364
                if (!f)
4✔
3365
                        return -ENOMEM;
3366

3367
                fputs("EnvironmentFile=\n", f);
4✔
3368

3369
                STRV_FOREACH(i, c->environment_files) {
4✔
3370
                        _cleanup_free_ char *q = NULL;
×
3371

3372
                        q = specifier_escape(*i);
×
3373
                        if (!q)
×
3374
                                return -ENOMEM;
×
3375

3376
                        fprintf(f, "EnvironmentFile=%s\n", q);
×
3377
                }
3378

3379
                while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
8✔
3380
                        const char *path;
4✔
3381
                        int b;
4✔
3382

3383
                        r = sd_bus_message_read(message, "sb", &path, &b);
4✔
3384
                        if (r < 0)
4✔
3385
                                return r;
×
3386

3387
                        r = sd_bus_message_exit_container(message);
4✔
3388
                        if (r < 0)
4✔
3389
                                return r;
3390

3391
                        if (!path_is_absolute(path))
4✔
3392
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
×
3393

3394
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3395
                                _cleanup_free_ char *q = NULL, *buf = NULL;
2✔
3396

3397
                                buf = strjoin(b ? "-" : "", path);
3✔
3398
                                if (!buf)
2✔
3399
                                        return -ENOMEM;
3400

3401
                                q = specifier_escape(buf);
2✔
3402
                                if (!q)
2✔
3403
                                        return -ENOMEM;
3404

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

3407
                                r = strv_consume(&l, TAKE_PTR(buf));
2✔
3408
                                if (r < 0)
2✔
3409
                                        return r;
3410
                        }
3411
                }
3412
                if (r < 0)
4✔
3413
                        return r;
3414

3415
                r = sd_bus_message_exit_container(message);
4✔
3416
                if (r < 0)
4✔
3417
                        return r;
3418

3419
                r = memstream_finalize(&m, &joined, NULL);
4✔
3420
                if (r < 0)
4✔
3421
                        return r;
3422

3423
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3424
                        if (strv_isempty(l)) {
2✔
3425
                                c->environment_files = strv_free(c->environment_files);
×
3426
                                unit_write_setting(u, flags, name, "EnvironmentFile=");
×
3427
                        } else {
3428
                                r = strv_extend_strv(&c->environment_files, l, true);
2✔
3429
                                if (r < 0)
2✔
3430
                                        return r;
3431

3432
                                unit_write_setting(u, flags, name, joined);
2✔
3433
                        }
3434
                }
3435

3436
                return 1;
4✔
3437

3438
        } else if (streq(name, "PassEnvironment")) {
776✔
3439

3440
                _cleanup_strv_free_ char **l = NULL;
×
3441

3442
                r = sd_bus_message_read_strv(message, &l);
×
3443
                if (r < 0)
×
3444
                        return r;
3445

3446
                if (!strv_env_name_is_valid(l))
×
3447
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
×
3448

3449
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3450
                        if (strv_isempty(l)) {
×
3451
                                c->pass_environment = strv_free(c->pass_environment);
×
3452
                                unit_write_setting(u, flags, name, "PassEnvironment=");
×
3453
                        } else {
3454
                                _cleanup_free_ char *joined = NULL;
×
3455

3456
                                r = strv_extend_strv(&c->pass_environment, l, true);
×
3457
                                if (r < 0)
×
3458
                                        return r;
3459

3460
                                /* We write just the new settings out to file, with unresolved specifiers. */
3461
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
×
3462
                                if (!joined)
×
3463
                                        return -ENOMEM;
3464

3465
                                unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
×
3466
                        }
3467
                }
3468

3469
                return 1;
×
3470

3471
        } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
776✔
3472
                              "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths", "ExecPaths", "NoExecPaths",
3473
                              "ExtensionDirectories")) {
3474
                _cleanup_strv_free_ char **l = NULL;
14✔
3475
                char ***dirs;
14✔
3476

3477
                r = sd_bus_message_read_strv(message, &l);
14✔
3478
                if (r < 0)
14✔
3479
                        return r;
3480

3481
                STRV_FOREACH(p, l) {
32✔
3482
                        char *i = *p;
18✔
3483
                        size_t offset;
18✔
3484

3485
                        offset = i[0] == '-';
18✔
3486
                        offset += i[offset] == '+';
18✔
3487
                        if (!path_is_absolute(i + offset))
18✔
3488
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3489

3490
                        path_simplify(i + offset);
18✔
3491
                }
3492

3493
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
3494
                        if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
7✔
3495
                                dirs = &c->read_write_paths;
1✔
3496
                        else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
6✔
3497
                                dirs = &c->read_only_paths;
2✔
3498
                        else if (streq(name, "ExecPaths"))
4✔
3499
                                dirs = &c->exec_paths;
1✔
3500
                        else if (streq(name, "NoExecPaths"))
3✔
3501
                                dirs = &c->no_exec_paths;
1✔
3502
                        else if (streq(name, "ExtensionDirectories"))
2✔
3503
                                dirs = &c->extension_directories;
1✔
3504
                        else /* "InaccessiblePaths" */
3505
                                dirs = &c->inaccessible_paths;
1✔
3506

3507
                        if (strv_isempty(l)) {
7✔
3508
                                *dirs = strv_free(*dirs);
×
3509
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3510
                        } else {
3511
                                _cleanup_free_ char *joined = NULL;
7✔
3512

3513
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
7✔
3514
                                if (!joined)
7✔
3515
                                        return -ENOMEM;
3516

3517
                                r = strv_extend_strv(dirs, l, true);
7✔
3518
                                if (r < 0)
7✔
3519
                                        return r;
3520

3521
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
7✔
3522
                        }
3523
                }
3524

3525
                return 1;
14✔
3526

3527
        } else if (streq(name, "ExecSearchPath")) {
762✔
3528
                _cleanup_strv_free_ char **l = NULL;
×
3529

3530
                r = sd_bus_message_read_strv(message, &l);
×
3531
                if (r < 0)
×
3532
                        return r;
3533

3534
                STRV_FOREACH(p, l)
×
3535
                        if (!path_is_absolute(*p) || !path_is_normalized(*p) || strchr(*p, ':'))
×
3536
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3537

3538
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3539
                        if (strv_isempty(l)) {
×
3540
                                c->exec_search_path = strv_free(c->exec_search_path);
×
3541
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=");
×
3542
                        } else {
3543
                                _cleanup_free_ char *joined = NULL;
×
3544
                                r = strv_extend_strv(&c->exec_search_path, l, true);
×
3545
                                if (r < 0)
×
3546
                                        return r;
3547
                                joined = strv_join(c->exec_search_path, ":");
×
3548
                                if (!joined)
×
3549
                                        return log_oom();
×
3550
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=%s", joined);
×
3551
                        }
3552
                }
3553

3554
                return 1;
×
3555

3556
        } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
762✔
3557
                _cleanup_strv_free_ char **l = NULL;
114✔
3558

3559
                r = sd_bus_message_read_strv(message, &l);
114✔
3560
                if (r < 0)
114✔
3561
                        return r;
3562

3563
                STRV_FOREACH(p, l) {
288✔
3564
                        if (!path_is_normalized(*p))
174✔
3565
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
×
3566

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

3570
                        if (path_startswith(*p, "private"))
174✔
3571
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
×
3572
                }
3573

3574
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
114✔
3575
                        ExecDirectoryType i;
57✔
3576
                        ExecDirectory *d;
57✔
3577

3578
                        assert_se((i = exec_directory_type_from_string(name)) >= 0);
57✔
3579
                        d = c->directories + i;
57✔
3580

3581
                        if (strv_isempty(l)) {
57✔
3582
                                exec_directory_done(d);
×
3583
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3584
                        } else {
3585
                                _cleanup_free_ char *joined = NULL;
57✔
3586

3587
                                STRV_FOREACH(source, l) {
144✔
3588
                                        r = exec_directory_add(d, *source, /* symlink= */ NULL, /* flags= */ 0);
87✔
3589
                                        if (r < 0)
87✔
3590
                                                return log_oom();
×
3591
                                }
3592
                                exec_directory_sort(d);
57✔
3593

3594
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
57✔
3595
                                if (!joined)
57✔
3596
                                        return -ENOMEM;
3597

3598
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
57✔
3599
                        }
3600
                }
3601

3602
                return 1;
114✔
3603

3604
        } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
648✔
3605
                int ignore;
×
3606
                const char *s;
×
3607

3608
                r = sd_bus_message_read(message, "(bs)", &ignore, &s);
×
3609
                if (r < 0)
×
3610
                        return r;
×
3611

3612
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3613
                        char **p;
×
3614
                        bool *b;
×
3615

3616
                        if (streq(name, "AppArmorProfile")) {
×
3617
                                p = &c->apparmor_profile;
×
3618
                                b = &c->apparmor_profile_ignore;
×
3619
                        } else { /* "SmackProcessLabel" */
3620
                                p = &c->smack_process_label;
×
3621
                                b = &c->smack_process_label_ignore;
×
3622
                        }
3623

3624
                        if (isempty(s)) {
×
3625
                                *p = mfree(*p);
×
3626
                                *b = false;
×
3627
                        } else {
3628
                                if (free_and_strdup(p, s) < 0)
×
3629
                                        return -ENOMEM;
3630
                                *b = ignore;
×
3631
                        }
3632

3633
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
×
3634
                }
3635

3636
                return 1;
×
3637

3638
        } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
648✔
3639
                char *source, *destination;
14✔
3640
                int ignore_enoent;
14✔
3641
                uint64_t mount_flags;
14✔
3642
                bool empty = true;
14✔
3643

3644
                r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
14✔
3645
                if (r < 0)
14✔
3646
                        return r;
14✔
3647

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

3650
                        if (!path_is_absolute(source))
30✔
3651
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3652
                        if (!path_is_absolute(destination))
30✔
3653
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
3654
                        if (!IN_SET(mount_flags, 0, MS_REC))
30✔
3655
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
×
3656

3657
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
30✔
3658
                                r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
30✔
3659
                                                   &(BindMount) {
15✔
3660
                                                           .source = source,
3661
                                                           .destination = destination,
3662
                                                           .read_only = !!strstr(name, "ReadOnly"),
15✔
3663
                                                           .recursive = !!(mount_flags & MS_REC),
15✔
3664
                                                           .ignore_enoent = ignore_enoent,
15✔
3665
                                                   });
3666
                                if (r < 0)
15✔
3667
                                        return r;
×
3668

3669
                                unit_write_settingf(
45✔
3670
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
15✔
3671
                                                "%s=%s%s:%s:%s",
3672
                                                name,
3673
                                                ignore_enoent ? "-" : "",
15✔
3674
                                                source,
3675
                                                destination,
3676
                                                (mount_flags & MS_REC) ? "rbind" : "norbind");
15✔
3677
                        }
3678

3679
                        empty = false;
3680
                }
3681
                if (r < 0)
14✔
3682
                        return r;
3683

3684
                r = sd_bus_message_exit_container(message);
14✔
3685
                if (r < 0)
14✔
3686
                        return r;
3687

3688
                if (empty) {
14✔
3689
                        bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
×
3690
                        c->bind_mounts = NULL;
×
3691
                        c->n_bind_mounts = 0;
×
3692

3693
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3694
                }
3695

3696
                return 1;
14✔
3697

3698
        } else if (streq(name, "TemporaryFileSystem")) {
634✔
3699
                const char *path, *options;
8✔
3700
                bool empty = true;
8✔
3701

3702
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
8✔
3703
                if (r < 0)
8✔
3704
                        return r;
8✔
3705

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

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

3711
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
3712
                                r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
4✔
3713
                                if (r < 0)
4✔
3714
                                        return r;
3715

3716
                                unit_write_settingf(
4✔
3717
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
4✔
3718
                                                "%s=%s:%s",
3719
                                                name,
3720
                                                path,
3721
                                                options);
3722
                        }
3723

3724
                        empty = false;
3725
                }
3726
                if (r < 0)
8✔
3727
                        return r;
3728

3729
                r = sd_bus_message_exit_container(message);
8✔
3730
                if (r < 0)
8✔
3731
                        return r;
3732

3733
                if (empty) {
8✔
3734
                        temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
×
3735
                        c->temporary_filesystems = NULL;
×
3736
                        c->n_temporary_filesystems = 0;
×
3737

3738
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3739
                }
3740

3741
                return 1;
8✔
3742

3743
        } else if ((suffix = startswith(name, "Limit"))) {
626✔
3744
                const char *soft = NULL;
88✔
3745
                int ri;
88✔
3746

3747
                ri = rlimit_from_string(suffix);
88✔
3748
                if (ri < 0) {
88✔
3749
                        soft = endswith(suffix, "Soft");
44✔
3750
                        if (soft) {
44✔
3751
                                const char *n;
44✔
3752

3753
                                n = strndupa_safe(suffix, soft - suffix);
44✔
3754
                                ri = rlimit_from_string(n);
44✔
3755
                                if (ri >= 0)
44✔
3756
                                        name = strjoina("Limit", n);
220✔
3757
                        }
3758
                }
3759

3760
                if (ri >= 0) {
44✔
3761
                        uint64_t rl;
88✔
3762
                        rlim_t x;
88✔
3763

3764
                        r = sd_bus_message_read(message, "t", &rl);
88✔
3765
                        if (r < 0)
88✔
3766
                                return r;
88✔
3767

3768
                        if (rl == UINT64_MAX)
88✔
3769
                                x = RLIM_INFINITY;
3770
                        else {
3771
                                x = (rlim_t) rl;
72✔
3772

3773
                                if ((uint64_t) x != rl)
72✔
3774
                                        return -ERANGE;
3775
                        }
3776

3777
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
88✔
3778
                                _cleanup_free_ char *f = NULL;
44✔
3779
                                struct rlimit nl;
44✔
3780

3781
                                if (c->rlimit[ri]) {
44✔
3782
                                        nl = *c->rlimit[ri];
27✔
3783

3784
                                        if (soft)
27✔
3785
                                                nl.rlim_cur = x;
22✔
3786
                                        else
3787
                                                nl.rlim_max = x;
5✔
3788
                                } else
3789
                                        /* When the resource limit is not initialized yet, then assign the value to both fields */
3790
                                        nl = (struct rlimit) {
17✔
3791
                                                .rlim_cur = x,
3792
                                                .rlim_max = x,
3793
                                        };
3794

3795
                                r = rlimit_format(&nl, &f);
44✔
3796
                                if (r < 0)
44✔
3797
                                        return r;
3798

3799
                                if (c->rlimit[ri])
44✔
3800
                                        *c->rlimit[ri] = nl;
27✔
3801
                                else {
3802
                                        c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
17✔
3803
                                        if (!c->rlimit[ri])
17✔
3804
                                                return -ENOMEM;
3805
                                }
3806

3807
                                unit_write_settingf(u, flags, name, "%s=%s", name, f);
44✔
3808
                        }
3809

3810
                        return 1;
88✔
3811
                }
3812

3813
        } else if (streq(name, "MountImages")) {
538✔
3814
                _cleanup_free_ char *format_str = NULL;
×
3815
                MountImage *mount_images = NULL;
×
3816
                size_t n_mount_images = 0;
×
3817
                char *source, *destination;
×
3818
                int permissive;
×
3819

3820
                r = sd_bus_message_enter_container(message, 'a', "(ssba(ss))");
×
3821
                if (r < 0)
×
3822
                        return r;
3823

3824
                for (;;) {
×
3825
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3826
                        _cleanup_free_ char *source_escaped = NULL, *destination_escaped = NULL;
×
3827
                        char *tuple;
×
3828

3829
                        r = sd_bus_message_enter_container(message, 'r', "ssba(ss)");
×
3830
                        if (r < 0)
×
3831
                                return r;
3832

3833
                        r = sd_bus_message_read(message, "ssb", &source, &destination, &permissive);
×
3834
                        if (r <= 0)
×
3835
                                break;
3836

3837
                        if (!path_is_absolute(source))
×
3838
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3839
                        if (!path_is_normalized(source))
×
3840
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
3841
                        if (!path_is_absolute(destination))
×
3842
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
3843
                        if (!path_is_normalized(destination))
×
3844
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
3845

3846
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
3847
                        source_escaped = shell_escape(source, ":");
×
3848
                        if (!source_escaped)
×
3849
                                return -ENOMEM;
3850
                        destination_escaped = shell_escape(destination, ":");
×
3851
                        if (!destination_escaped)
×
3852
                                return -ENOMEM;
3853

3854
                        tuple = strjoin(format_str,
×
3855
                                        format_str ? " " : "",
3856
                                        permissive ? "-" : "",
3857
                                        source_escaped,
3858
                                        ":",
3859
                                        destination_escaped);
3860
                        if (!tuple)
×
3861
                                return -ENOMEM;
3862
                        free_and_replace(format_str, tuple);
×
3863

3864
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
3865
                        if (r < 0)
×
3866
                                return r;
3867

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

3872
                        r = mount_image_add(&mount_images, &n_mount_images,
×
3873
                                            &(MountImage) {
×
3874
                                                    .source = source,
3875
                                                    .destination = destination,
3876
                                                    .mount_options = options,
3877
                                                    .ignore_enoent = permissive,
×
3878
                                                    .type = MOUNT_IMAGE_DISCRETE,
3879
                                            });
3880
                        if (r < 0)
×
3881
                                return r;
3882
                }
3883
                if (r < 0)
×
3884
                        return r;
3885

3886
                r = sd_bus_message_exit_container(message);
×
3887
                if (r < 0)
×
3888
                        return r;
3889

3890
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3891
                        if (n_mount_images == 0) {
×
3892
                                c->mount_images = mount_image_free_many(c->mount_images, &c->n_mount_images);
×
3893

3894
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3895
                        } else {
3896
                                for (size_t i = 0; i < n_mount_images; ++i) {
×
3897
                                        r = mount_image_add(&c->mount_images, &c->n_mount_images, &mount_images[i]);
×
3898
                                        if (r < 0)
×
3899
                                                return r;
3900
                                }
3901

3902
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
3903
                                                    name,
3904
                                                    "%s=%s",
3905
                                                    name,
3906
                                                    format_str);
3907
                        }
3908
                }
3909

3910
                mount_images = mount_image_free_many(mount_images, &n_mount_images);
×
3911

3912
                return 1;
×
3913
        } else if (streq(name, "ExtensionImages")) {
538✔
3914
                _cleanup_free_ char *format_str = NULL;
×
3915
                MountImage *extension_images = NULL;
×
3916
                size_t n_extension_images = 0;
×
3917

3918
                r = sd_bus_message_enter_container(message, 'a', "(sba(ss))");
×
3919
                if (r < 0)
×
3920
                        return r;
3921

3922
                for (;;) {
×
3923
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3924
                        _cleanup_free_ char *source_escaped = NULL;
×
3925
                        char *source, *tuple;
×
3926
                        int permissive;
×
3927

3928
                        r = sd_bus_message_enter_container(message, 'r', "sba(ss)");
×
3929
                        if (r < 0)
×
3930
                                return r;
3931

3932
                        r = sd_bus_message_read(message, "sb", &source, &permissive);
×
3933
                        if (r <= 0)
×
3934
                                break;
3935

3936
                        if (!path_is_absolute(source))
×
3937
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3938
                        if (!path_is_normalized(source))
×
3939
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
3940

3941
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
3942
                        source_escaped = shell_escape(source, ":");
×
3943
                        if (!source_escaped)
×
3944
                                return -ENOMEM;
3945

3946
                        tuple = strjoin(format_str,
×
3947
                                        format_str ? " " : "",
3948
                                        permissive ? "-" : "",
3949
                                        source_escaped);
3950
                        if (!tuple)
×
3951
                                return -ENOMEM;
3952
                        free_and_replace(format_str, tuple);
×
3953

3954
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
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
                        r = mount_image_add(&extension_images, &n_extension_images,
×
3963
                                            &(MountImage) {
×
3964
                                                    .source = source,
3965
                                                    .mount_options = options,
3966
                                                    .ignore_enoent = permissive,
×
3967
                                                    .type = MOUNT_IMAGE_EXTENSION,
3968
                                            });
3969
                        if (r < 0)
×
3970
                                return r;
3971
                }
3972
                if (r < 0)
×
3973
                        return r;
3974

3975
                r = sd_bus_message_exit_container(message);
×
3976
                if (r < 0)
×
3977
                        return r;
3978

3979
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3980
                        if (n_extension_images == 0) {
×
3981
                                c->extension_images = mount_image_free_many(c->extension_images, &c->n_extension_images);
×
3982

3983
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3984
                        } else {
3985
                                for (size_t i = 0; i < n_extension_images; ++i) {
×
3986
                                        r = mount_image_add(&c->extension_images, &c->n_extension_images, &extension_images[i]);
×
3987
                                        if (r < 0)
×
3988
                                                return r;
3989
                                }
3990

3991
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
3992
                                                    name,
3993
                                                    "%s=%s",
3994
                                                    name,
3995
                                                    format_str);
3996
                        }
3997
                }
3998

3999
                extension_images = mount_image_free_many(extension_images, &n_extension_images);
×
4000

4001
                return 1;
×
4002

4003
        } else if (STR_IN_SET(name, "StateDirectorySymlink", "RuntimeDirectorySymlink", "CacheDirectorySymlink", "LogsDirectorySymlink")) {
538✔
4004
                char *source, *destination;
14✔
4005
                ExecDirectory *directory;
14✔
4006
                uint64_t symlink_flags;
14✔
4007
                ExecDirectoryType i;
14✔
4008

4009
                assert_se((i = exec_directory_type_symlink_from_string(name)) >= 0);
14✔
4010
                directory = c->directories + i;
14✔
4011

4012
                r = sd_bus_message_enter_container(message, 'a', "(sst)");
14✔
4013
                if (r < 0)
14✔
4014
                        return r;
14✔
4015

4016
                while ((r = sd_bus_message_read(message, "(sst)", &source, &destination, &symlink_flags)) > 0) {
28✔
4017
                        if ((symlink_flags & ~_EXEC_DIRECTORY_FLAGS_PUBLIC) != 0)
14✔
4018
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid 'flags' parameter '%" PRIu64 "'", symlink_flags);
×
4019
                        if (!path_is_valid(source))
14✔
4020
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not valid.", source);
×
4021
                        if (path_is_absolute(source))
14✔
4022
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is absolute.", source);
×
4023
                        if (!path_is_normalized(source))
14✔
4024
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
4025
                        if (isempty(destination))
14✔
4026
                                destination = NULL;
2✔
4027
                        else {
4028
                                if (!path_is_valid(destination))
12✔
4029
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not valid.", destination);
×
4030
                                if (path_is_absolute(destination))
12✔
4031
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is absolute.", destination);
×
4032
                                if (!path_is_normalized(destination))
12✔
4033
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
4034
                        }
4035

4036
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
4037
                                _cleanup_free_ char *destination_escaped = NULL, *source_escaped = NULL;
7✔
4038

4039
                                r = exec_directory_add(directory, source, destination, symlink_flags);
7✔
4040
                                if (r < 0)
7✔
4041
                                        return r;
4042

4043
                                /* Need to store them in the unit with the escapes, so that they can be parsed again */
4044
                                source_escaped = xescape(source, ":");
7✔
4045
                                if (!source_escaped)
7✔
4046
                                        return -ENOMEM;
4047
                                if (destination) {
7✔
4048
                                        destination_escaped = xescape(destination, ":");
6✔
4049
                                        if (!destination_escaped)
6✔
4050
                                                return -ENOMEM;
4051
                                }
4052

4053
                                unit_write_settingf(
8✔
4054
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, exec_directory_type_to_string(i),
7✔
4055
                                                "%s=%s%s%s%s",
4056
                                                exec_directory_type_to_string(i),
4057
                                                source_escaped,
4058
                                                destination_escaped || FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":" : "",
1✔
4059
                                                destination_escaped,
4060
                                                FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":ro" : "");
7✔
4061
                        }
4062
                }
4063
                if (r < 0)
14✔
4064
                        return r;
4065

4066
                exec_directory_sort(directory);
14✔
4067

4068
                r = sd_bus_message_exit_container(message);
14✔
4069
                if (r < 0)
14✔
4070
                        return r;
4071

4072
                return 1;
14✔
4073

4074
        } else if (STR_IN_SET(name, "RootImagePolicy", "MountImagePolicy", "ExtensionImagePolicy")) {
524✔
4075
                _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
×
4076
                const char *s;
×
4077

4078
                r = sd_bus_message_read(message, "s", &s);
×
4079
                if (r < 0)
×
4080
                        return r;
4081

4082
                r = image_policy_from_string(s, &p);
×
4083
                if (r < 0)
×
4084
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse image policy string: %s", s);
×
4085

4086
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
4087
                        _cleanup_free_ char *t = NULL;
×
4088
                        ImagePolicy **pp =
×
4089
                                streq(name, "RootImagePolicy")  ? &c->root_image_policy :
×
4090
                                streq(name, "MountImagePolicy") ? &c->mount_image_policy :
×
4091
                                                                  &c->extension_image_policy;
4092

4093
                        r = image_policy_to_string(p, /* simplify= */ true, &t);
×
4094
                        if (r < 0)
×
4095
                                return r;
×
4096

4097
                        image_policy_free(*pp);
×
4098
                        *pp = TAKE_PTR(p);
×
4099

4100
                        unit_write_settingf(
×
4101
                                        u, flags, name,
4102
                                        "%s=%s",
4103
                                        name,
4104
                                        t); /* no escaping necessary */
4105
                }
4106

4107
                return 1;
×
4108
        }
4109

4110
        return 0;
524✔
4111
}
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