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

systemd / systemd / 16280725298

14 Jul 2025 08:16PM UTC coverage: 72.166% (-0.006%) from 72.172%
16280725298

push

github

web-flow
Two fixlets for coverage test (#38183)

302135 of 418667 relevant lines covered (72.17%)

773261.64 hits per line

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

51.61
/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
#include <unistd.h>
6

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

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

82
static int property_get_environment_files(
1,319✔
83
                sd_bus *bus,
84
                const char *path,
85
                const char *interface,
86
                const char *property,
87
                sd_bus_message *reply,
88
                void *userdata,
89
                sd_bus_error *error) {
90

91
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
92
        int r;
1,319✔
93

94
        assert(bus);
1,319✔
95
        assert(reply);
1,319✔
96

97
        r = sd_bus_message_open_container(reply, 'a', "(sb)");
1,319✔
98
        if (r < 0)
1,319✔
99
                return r;
100

101
        STRV_FOREACH(j, c->environment_files) {
1,323✔
102
                const char *fn = *j;
4✔
103

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

109
        return sd_bus_message_close_container(reply);
1,319✔
110
}
111

112
static int property_get_cpu_affinity(
1,319✔
113
                sd_bus *bus,
114
                const char *path,
115
                const char *interface,
116
                const char *property,
117
                sd_bus_message *reply,
118
                void *userdata,
119
                sd_bus_error *error) {
120

121
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
122
        _cleanup_(cpu_set_done) CPUSet s = {};
×
123
        _cleanup_free_ uint8_t *array = NULL;
1,319✔
124
        size_t allocated;
1,319✔
125

126
        assert(bus);
1,319✔
127
        assert(reply);
1,319✔
128

129
        if (c->cpu_affinity_from_numa) {
1,319✔
130
                int r;
×
131

132
                r = numa_to_cpu_set(&c->numa_policy, &s);
×
133
                if (r < 0)
×
134
                        return r;
135
        }
136

137
        (void) cpu_set_to_dbus(c->cpu_affinity_from_numa ? &s : &c->cpu_set,  &array, &allocated);
1,319✔
138

139
        return sd_bus_message_append_array(reply, 'y', array, allocated);
1,319✔
140
}
141

142
static int property_get_numa_mask(
1,319✔
143
                sd_bus *bus,
144
                const char *path,
145
                const char *interface,
146
                const char *property,
147
                sd_bus_message *reply,
148
                void *userdata,
149
                sd_bus_error *error) {
150

151
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
152
        _cleanup_free_ uint8_t *array = NULL;
1,319✔
153
        size_t allocated;
1,319✔
154

155
        assert(bus);
1,319✔
156
        assert(reply);
1,319✔
157

158
        (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
1,319✔
159

160
        return sd_bus_message_append_array(reply, 'y', array, allocated);
1,319✔
161
}
162

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

174
        assert(bus);
1,319✔
175
        assert(reply);
1,319✔
176

177
        policy = numa_policy_get_type(&c->numa_policy);
1,319✔
178

179
        return sd_bus_message_append_basic(reply, 'i', &policy);
1,319✔
180
}
181

182
static int property_get_syscall_filter(
1,319✔
183
                sd_bus *bus,
184
                const char *path,
185
                const char *interface,
186
                const char *property,
187
                sd_bus_message *reply,
188
                void *userdata,
189
                sd_bus_error *error) {
190

191
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
192
        _cleanup_strv_free_ char **l = NULL;
1,319✔
193
        int r;
1,319✔
194

195
        assert(bus);
1,319✔
196
        assert(reply);
1,319✔
197

198
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,319✔
199
        if (r < 0)
1,319✔
200
                return r;
201

202
        r = sd_bus_message_append(reply, "b", c->syscall_allow_list);
1,319✔
203
        if (r < 0)
1,319✔
204
                return r;
205

206
        l = exec_context_get_syscall_filter(c);
1,319✔
207
        if (!l)
1,319✔
208
                return -ENOMEM;
209

210
        r = sd_bus_message_append_strv(reply, l);
1,319✔
211
        if (r < 0)
1,319✔
212
                return r;
213

214
        return sd_bus_message_close_container(reply);
1,319✔
215
}
216

217
static int property_get_syscall_log(
1,319✔
218
                sd_bus *bus,
219
                const char *path,
220
                const char *interface,
221
                const char *property,
222
                sd_bus_message *reply,
223
                void *userdata,
224
                sd_bus_error *error) {
225

226
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
227
        _cleanup_strv_free_ char **l = NULL;
1,319✔
228
        int r;
1,319✔
229

230
        assert(bus);
1,319✔
231
        assert(reply);
1,319✔
232

233
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,319✔
234
        if (r < 0)
1,319✔
235
                return r;
236

237
        r = sd_bus_message_append(reply, "b", c->syscall_log_allow_list);
1,319✔
238
        if (r < 0)
1,319✔
239
                return r;
240

241
        l = exec_context_get_syscall_log(c);
1,319✔
242
        if (!l)
1,319✔
243
                return -ENOMEM;
244

245
        r = sd_bus_message_append_strv(reply, l);
1,319✔
246
        if (r < 0)
1,319✔
247
                return r;
248

249
        return sd_bus_message_close_container(reply);
1,319✔
250
}
251

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

261
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
262
        _cleanup_strv_free_ char **l = NULL;
1,319✔
263
        int r;
1,319✔
264

265
        assert(bus);
1,319✔
266
        assert(reply);
1,319✔
267

268
        l = exec_context_get_syscall_archs(c);
1,319✔
269
        if (!l)
1,319✔
270
                return -ENOMEM;
271

272
        r = sd_bus_message_append_strv(reply, l);
1,319✔
273
        if (r < 0)
1,319✔
274
                return r;
×
275

276
        return 0;
277
}
278

279
static int property_get_selinux_context(
1,319✔
280
                sd_bus *bus,
281
                const char *path,
282
                const char *interface,
283
                const char *property,
284
                sd_bus_message *reply,
285
                void *userdata,
286
                sd_bus_error *error) {
287

288
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
289

290
        assert(bus);
1,319✔
291
        assert(reply);
1,319✔
292

293
        return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
1,319✔
294
}
295

296
static int property_get_apparmor_profile(
1,319✔
297
                sd_bus *bus,
298
                const char *path,
299
                const char *interface,
300
                const char *property,
301
                sd_bus_message *reply,
302
                void *userdata,
303
                sd_bus_error *error) {
304

305
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
306

307
        assert(bus);
1,319✔
308
        assert(reply);
1,319✔
309

310
        return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
1,319✔
311
}
312

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

322
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
323

324
        assert(bus);
1,319✔
325
        assert(reply);
1,319✔
326

327
        return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
1,319✔
328
}
329

330
static int property_get_address_families(
1,319✔
331
                sd_bus *bus,
332
                const char *path,
333
                const char *interface,
334
                const char *property,
335
                sd_bus_message *reply,
336
                void *userdata,
337
                sd_bus_error *error) {
338

339
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
340
        _cleanup_strv_free_ char **l = NULL;
1,319✔
341
        int r;
1,319✔
342

343
        assert(bus);
1,319✔
344
        assert(reply);
1,319✔
345

346
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,319✔
347
        if (r < 0)
1,319✔
348
                return r;
349

350
        r = sd_bus_message_append(reply, "b", c->address_families_allow_list);
1,319✔
351
        if (r < 0)
1,319✔
352
                return r;
353

354
        l = exec_context_get_address_families(c);
1,319✔
355
        if (!l)
1,319✔
356
                return -ENOMEM;
357

358
        r = sd_bus_message_append_strv(reply, l);
1,319✔
359
        if (r < 0)
1,319✔
360
                return r;
361

362
        return sd_bus_message_close_container(reply);
1,319✔
363
}
364

365
static int property_get_working_directory(
1,319✔
366
                sd_bus *bus,
367
                const char *path,
368
                const char *interface,
369
                const char *property,
370
                sd_bus_message *reply,
371
                void *userdata,
372
                sd_bus_error *error) {
373

374
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
375
        const char *wd;
1,319✔
376

377
        assert(bus);
1,319✔
378
        assert(reply);
1,319✔
379

380
        if (c->working_directory_home)
1,319✔
381
                wd = "~";
382
        else
383
                wd = c->working_directory;
1,319✔
384

385
        if (c->working_directory_missing_ok)
1,319✔
386
                wd = strjoina("!", wd);
2,135✔
387

388
        return sd_bus_message_append(reply, "s", wd);
1,319✔
389
}
390

391
static int property_get_stdio_fdname(
3,957✔
392
                sd_bus *bus,
393
                const char *path,
394
                const char *interface,
395
                const char *property,
396
                sd_bus_message *reply,
397
                void *userdata,
398
                sd_bus_error *error) {
399

400
        ExecContext *c = ASSERT_PTR(userdata);
3,957✔
401
        int fileno;
3,957✔
402

403
        assert(bus);
3,957✔
404
        assert(property);
3,957✔
405
        assert(reply);
3,957✔
406

407
        if (streq(property, "StandardInputFileDescriptorName"))
3,957✔
408
                fileno = STDIN_FILENO;
409
        else if (streq(property, "StandardOutputFileDescriptorName"))
2,638✔
410
                fileno = STDOUT_FILENO;
411
        else {
412
                assert(streq(property, "StandardErrorFileDescriptorName"));
1,319✔
413
                fileno = STDERR_FILENO;
414
        }
415

416
        return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
3,957✔
417
}
418

419
static int property_get_input_data(
1,319✔
420
                sd_bus *bus,
421
                const char *path,
422
                const char *interface,
423
                const char *property,
424
                sd_bus_message *reply,
425
                void *userdata,
426
                sd_bus_error *error) {
427

428
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
429

430
        assert(bus);
1,319✔
431
        assert(property);
1,319✔
432
        assert(reply);
1,319✔
433

434
        return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
1,319✔
435
}
436

437
static int property_get_restrict_filesystems(
1,319✔
438
                sd_bus *bus,
439
                const char *path,
440
                const char *interface,
441
                const char *property,
442
                sd_bus_message *reply,
443
                void *userdata,
444
                sd_bus_error *error) {
445

446
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
447
        _cleanup_free_ char **l = NULL; /* Strings are owned by 'c->restrict_filesystems'! */
1,319✔
448
        int r;
1,319✔
449

450
        assert(bus);
1,319✔
451
        assert(reply);
1,319✔
452

453
        r = sd_bus_message_open_container(reply, 'r', "bas");
1,319✔
454
        if (r < 0)
1,319✔
455
                return r;
456

457
        r = sd_bus_message_append(reply, "b", c->restrict_filesystems_allow_list);
1,319✔
458
        if (r < 0)
1,319✔
459
                return r;
460

461
        l = exec_context_get_restrict_filesystems(c);
1,319✔
462
        if (!l)
1,319✔
463
                return -ENOMEM;
464

465
        r = sd_bus_message_append_strv(reply, l);
1,319✔
466
        if (r < 0)
1,319✔
467
                return r;
468

469
        return sd_bus_message_close_container(reply);
1,319✔
470
}
471

472
static int property_get_bind_paths(
2,638✔
473
                sd_bus *bus,
474
                const char *path,
475
                const char *interface,
476
                const char *property,
477
                sd_bus_message *reply,
478
                void *userdata,
479
                sd_bus_error *error) {
480

481
        ExecContext *c = ASSERT_PTR(userdata);
2,638✔
482
        bool ro;
2,638✔
483
        int r;
2,638✔
484

485
        assert(bus);
2,638✔
486
        assert(property);
2,638✔
487
        assert(reply);
2,638✔
488

489
        ro = strstr(property, "ReadOnly");
2,638✔
490

491
        r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
2,638✔
492
        if (r < 0)
2,638✔
493
                return r;
494

495
        FOREACH_ARRAY(i, c->bind_mounts, c->n_bind_mounts) {
2,778✔
496
                if (ro != i->read_only)
140✔
497
                        continue;
70✔
498

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

509
        return sd_bus_message_close_container(reply);
2,638✔
510
}
511

512
static int property_get_temporary_filesystems(
1,319✔
513
                sd_bus *bus,
514
                const char *path,
515
                const char *interface,
516
                const char *property,
517
                sd_bus_message *reply,
518
                void *userdata,
519
                sd_bus_error *error) {
520

521
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
522
        int r;
1,319✔
523

524
        assert(bus);
1,319✔
525
        assert(property);
1,319✔
526
        assert(reply);
1,319✔
527

528
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,319✔
529
        if (r < 0)
1,319✔
530
                return r;
531

532
        FOREACH_ARRAY(t, c->temporary_filesystems, c->n_temporary_filesystems) {
1,345✔
533
                r = sd_bus_message_append(
26✔
534
                                reply, "(ss)",
535
                                t->path,
536
                                t->options);
537
                if (r < 0)
26✔
538
                        return r;
539
        }
540

541
        return sd_bus_message_close_container(reply);
1,319✔
542
}
543

544
static int property_get_log_extra_fields(
1,319✔
545
                sd_bus *bus,
546
                const char *path,
547
                const char *interface,
548
                const char *property,
549
                sd_bus_message *reply,
550
                void *userdata,
551
                sd_bus_error *error) {
552

553
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
554
        int r;
1,319✔
555

556
        assert(bus);
1,319✔
557
        assert(property);
1,319✔
558
        assert(reply);
1,319✔
559

560
        r = sd_bus_message_open_container(reply, 'a', "ay");
1,319✔
561
        if (r < 0)
1,319✔
562
                return r;
563

564
        FOREACH_ARRAY(i, c->log_extra_fields, c->n_log_extra_fields) {
1,319✔
565
                r = sd_bus_message_append_array(reply, 'y', i->iov_base, i->iov_len);
×
566
                if (r < 0)
×
567
                        return r;
568
        }
569

570
        return sd_bus_message_close_container(reply);
1,319✔
571
}
572

573
static int sd_bus_message_append_log_filter_patterns(sd_bus_message *reply, Set *patterns, bool is_allowlist) {
2,638✔
574
        const char *pattern;
2,638✔
575
        int r;
2,638✔
576

577
        assert(reply);
2,638✔
578

579
        SET_FOREACH(pattern, patterns) {
2,638✔
580
                r = sd_bus_message_append(reply, "(bs)", is_allowlist, pattern);
×
581
                if (r < 0)
×
582
                        return r;
×
583
        }
584

585
        return 0;
2,638✔
586
}
587

588
static int property_get_log_filter_patterns(
1,319✔
589
                sd_bus *bus,
590
                const char *path,
591
                const char *interface,
592
                const char *property,
593
                sd_bus_message *reply,
594
                void *userdata,
595
                sd_bus_error *error) {
596

597
        ExecContext *c = userdata;
1,319✔
598
        int r;
1,319✔
599

600
        assert(c);
1,319✔
601
        assert(reply);
1,319✔
602

603
        r = sd_bus_message_open_container(reply, 'a', "(bs)");
1,319✔
604
        if (r < 0)
1,319✔
605
                return r;
606

607
        r = sd_bus_message_append_log_filter_patterns(reply, c->log_filter_allowed_patterns,
1,319✔
608
                                                      /* is_allowlist = */ true);
609
        if (r < 0)
1,319✔
610
                return r;
611

612
        r = sd_bus_message_append_log_filter_patterns(reply, c->log_filter_denied_patterns,
1,319✔
613
                                                      /* is_allowlist = */ false);
614
        if (r < 0)
1,319✔
615
                return r;
616

617
        return sd_bus_message_close_container(reply);
1,319✔
618
}
619

620
static int property_get_set_credential(
2,638✔
621
                sd_bus *bus,
622
                const char *path,
623
                const char *interface,
624
                const char *property,
625
                sd_bus_message *reply,
626
                void *userdata,
627
                sd_bus_error *error) {
628

629
        ExecContext *c = ASSERT_PTR(userdata);
2,638✔
630
        ExecSetCredential *sc;
2,638✔
631
        int r;
2,638✔
632

633
        assert(bus);
2,638✔
634
        assert(property);
2,638✔
635
        assert(reply);
2,638✔
636

637
        r = sd_bus_message_open_container(reply, 'a', "(say)");
2,638✔
638
        if (r < 0)
2,638✔
639
                return r;
2,638✔
640

641
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,638✔
642

643
                if (sc->encrypted != streq(property, "SetCredentialEncrypted"))
×
644
                        continue;
×
645

646
                r = sd_bus_message_open_container(reply, 'r', "say");
×
647
                if (r < 0)
×
648
                        return r;
×
649

650
                r = sd_bus_message_append(reply, "s", sc->id);
×
651
                if (r < 0)
×
652
                        return r;
653

654
                r = sd_bus_message_append_array(reply, 'y', sc->data, sc->size);
×
655
                if (r < 0)
×
656
                        return r;
657

658
                r = sd_bus_message_close_container(reply);
×
659
                if (r < 0)
×
660
                        return r;
661
        }
662

663
        return sd_bus_message_close_container(reply);
2,638✔
664
}
665

666
static int property_get_load_credential(
2,638✔
667
                sd_bus *bus,
668
                const char *path,
669
                const char *interface,
670
                const char *property,
671
                sd_bus_message *reply,
672
                void *userdata,
673
                sd_bus_error *error) {
674

675
        ExecContext *c = ASSERT_PTR(userdata);
2,638✔
676
        ExecLoadCredential *lc;
2,638✔
677
        int r;
2,638✔
678

679
        assert(bus);
2,638✔
680
        assert(property);
2,638✔
681
        assert(reply);
2,638✔
682

683
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
2,638✔
684
        if (r < 0)
2,638✔
685
                return r;
2,638✔
686

687
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,654✔
688

689
                if (lc->encrypted != streq(property, "LoadCredentialEncrypted"))
16✔
690
                        continue;
8✔
691

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

697
        return sd_bus_message_close_container(reply);
2,638✔
698
}
699

700
static int property_get_import_credential(
1,319✔
701
                sd_bus *bus,
702
                const char *path,
703
                const char *interface,
704
                const char *property,
705
                sd_bus_message *reply,
706
                void *userdata,
707
                sd_bus_error *error) {
708

709
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
710
        ExecImportCredential *ic;
1,319✔
711
        int r;
1,319✔
712

713
        assert(bus);
1,319✔
714
        assert(property);
1,319✔
715
        assert(reply);
1,319✔
716

717
        r = sd_bus_message_open_container(reply, 'a', "s");
1,319✔
718
        if (r < 0)
1,319✔
719
                return r;
1,319✔
720

721
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
1,450✔
722
                r = sd_bus_message_append(reply, "s", ic->glob);
131✔
723
                if (r < 0)
131✔
724
                        return r;
×
725
        }
726

727
        return sd_bus_message_close_container(reply);
1,319✔
728
}
729

730
static int property_get_import_credential_ex(
1,319✔
731
                sd_bus *bus,
732
                const char *path,
733
                const char *interface,
734
                const char *property,
735
                sd_bus_message *reply,
736
                void *userdata,
737
                sd_bus_error *error) {
738

739
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
740
        ExecImportCredential *ic;
1,319✔
741
        int r;
1,319✔
742

743
        assert(bus);
1,319✔
744
        assert(property);
1,319✔
745
        assert(reply);
1,319✔
746

747
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,319✔
748
        if (r < 0)
1,319✔
749
                return r;
1,319✔
750

751
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
1,450✔
752
                r = sd_bus_message_append(reply, "(ss)", ic->glob, ic->rename);
131✔
753
                if (r < 0)
131✔
754
                        return r;
×
755
        }
756

757
        return sd_bus_message_close_container(reply);
1,319✔
758
}
759

760
static int property_get_root_hash(
1,319✔
761
                sd_bus *bus,
762
                const char *path,
763
                const char *interface,
764
                const char *property,
765
                sd_bus_message *reply,
766
                void *userdata,
767
                sd_bus_error *error) {
768

769
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
770

771
        assert(bus);
1,319✔
772
        assert(property);
1,319✔
773
        assert(reply);
1,319✔
774

775
        return sd_bus_message_append_array(reply, 'y', c->root_hash, c->root_hash_size);
1,319✔
776
}
777

778
static int property_get_root_hash_sig(
1,319✔
779
                sd_bus *bus,
780
                const char *path,
781
                const char *interface,
782
                const char *property,
783
                sd_bus_message *reply,
784
                void *userdata,
785
                sd_bus_error *error) {
786

787
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
788

789
        assert(bus);
1,319✔
790
        assert(property);
1,319✔
791
        assert(reply);
1,319✔
792

793
        return sd_bus_message_append_array(reply, 'y', c->root_hash_sig, c->root_hash_sig_size);
1,319✔
794
}
795

796
static int property_get_root_image_options(
1,319✔
797
                sd_bus *bus,
798
                const char *path,
799
                const char *interface,
800
                const char *property,
801
                sd_bus_message *reply,
802
                void *userdata,
803
                sd_bus_error *error) {
804

805
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
806
        int r;
1,319✔
807

808
        assert(bus);
1,319✔
809
        assert(property);
1,319✔
810
        assert(reply);
1,319✔
811

812
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
1,319✔
813
        if (r < 0)
1,319✔
814
                return r;
815

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

824
        return sd_bus_message_close_container(reply);
1,319✔
825
}
826

827
static int property_get_mount_images(
1,319✔
828
                sd_bus *bus,
829
                const char *path,
830
                const char *interface,
831
                const char *property,
832
                sd_bus_message *reply,
833
                void *userdata,
834
                sd_bus_error *error) {
835

836
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
837
        int r;
1,319✔
838

839
        assert(bus);
1,319✔
840
        assert(property);
1,319✔
841
        assert(reply);
1,319✔
842

843
        r = sd_bus_message_open_container(reply, 'a', "(ssba(ss))");
1,319✔
844
        if (r < 0)
1,319✔
845
                return r;
846

847
        FOREACH_ARRAY(i, c->mount_images, c->n_mount_images) {
1,319✔
848
                r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "ssba(ss)");
×
849
                if (r < 0)
×
850
                        return r;
851

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

860
                r = sd_bus_message_open_container(reply, 'a', "(ss)");
×
861
                if (r < 0)
×
862
                        return r;
863

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

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

876
                r = sd_bus_message_close_container(reply);
×
877
                if (r < 0)
×
878
                        return r;
879
        }
880

881
        return sd_bus_message_close_container(reply);
1,319✔
882
}
883

884
static int property_get_extension_images(
1,319✔
885
                sd_bus *bus,
886
                const char *path,
887
                const char *interface,
888
                const char *property,
889
                sd_bus_message *reply,
890
                void *userdata,
891
                sd_bus_error *error) {
892

893
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
894
        int r;
1,319✔
895

896
        assert(bus);
1,319✔
897
        assert(property);
1,319✔
898
        assert(reply);
1,319✔
899

900
        r = sd_bus_message_open_container(reply, 'a', "(sba(ss))");
1,319✔
901
        if (r < 0)
1,319✔
902
                return r;
903

904
        FOREACH_ARRAY(i, c->extension_images, c->n_extension_images) {
1,319✔
905
                r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "sba(ss)");
×
906
                if (r < 0)
×
907
                        return r;
908

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

916
                r = sd_bus_message_open_container(reply, 'a', "(ss)");
×
917
                if (r < 0)
×
918
                        return r;
919

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

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

932
                r = sd_bus_message_close_container(reply);
×
933
                if (r < 0)
×
934
                        return r;
935
        }
936

937
        return sd_bus_message_close_container(reply);
1,319✔
938
}
939

940
static int property_get_exec_dir(
6,595✔
941
                sd_bus *bus,
942
                const char *path,
943
                const char *interface,
944
                const char *property,
945
                sd_bus_message *reply,
946
                void *userdata,
947
                sd_bus_error *error) {
948

949
        ExecDirectory *d = ASSERT_PTR(userdata);
6,595✔
950
        int r;
6,595✔
951

952
        assert(bus);
6,595✔
953
        assert(property);
6,595✔
954
        assert(reply);
6,595✔
955

956
        r = sd_bus_message_open_container(reply, 'a', "s");
6,595✔
957
        if (r < 0)
6,595✔
958
                return r;
959

960
        FOREACH_ARRAY(i, d->items, d->n_items) {
7,321✔
961
                r = sd_bus_message_append_basic(reply, 's', i->path);
726✔
962
                if (r < 0)
726✔
963
                        return r;
964
        }
965

966
        return sd_bus_message_close_container(reply);
6,595✔
967
}
968

969
static int property_get_exec_dir_symlink(
5,276✔
970
                sd_bus *bus,
971
                const char *path,
972
                const char *interface,
973
                const char *property,
974
                sd_bus_message *reply,
975
                void *userdata,
976
                sd_bus_error *error) {
977

978
        ExecDirectory *d = ASSERT_PTR(userdata);
5,276✔
979
        int r;
5,276✔
980

981
        assert(bus);
5,276✔
982
        assert(property);
5,276✔
983
        assert(reply);
5,276✔
984

985
        r = sd_bus_message_open_container(reply, 'a', "(sst)");
5,276✔
986
        if (r < 0)
5,276✔
987
                return r;
988

989
        FOREACH_ARRAY(i, d->items, d->n_items)
5,794✔
990
                if (strv_isempty(i->symlinks)) {
518✔
991
                        /* The old exec directory properties cannot represent flags, so list them here with no
992
                         * destination */
993
                        r = sd_bus_message_append(reply, "(sst)", i->path, "", (uint64_t) (i->flags & _EXEC_DIRECTORY_FLAGS_PUBLIC));
467✔
994
                        if (r < 0)
467✔
995
                                return r;
996
                } else
997
                        STRV_FOREACH(dst, i->symlinks) {
102✔
998
                                r = sd_bus_message_append(reply, "(sst)", i->path, *dst, (uint64_t) (i->flags & _EXEC_DIRECTORY_FLAGS_PUBLIC));
51✔
999
                                if (r < 0)
51✔
1000
                                        return r;
1001
                        }
1002

1003
        return sd_bus_message_close_container(reply);
5,276✔
1004
}
1005

1006
static int property_get_exec_quota(sd_bus *bus,
3,957✔
1007
                const char *path,
1008
                const char *interface,
1009
                const char *property,
1010
                sd_bus_message *reply,
1011
                void *userdata,
1012
                sd_bus_error *error) {
1013

1014
        QuotaLimit *q = ASSERT_PTR(userdata);
3,957✔
1015

1016
        assert(bus);
3,957✔
1017
        assert(reply);
3,957✔
1018

1019
        return sd_bus_message_append(reply, "(tus)", q->quota_absolute, q->quota_scale, yes_no(q->quota_enforce));
7,914✔
1020
}
1021

1022
static int property_get_image_policy(
3,957✔
1023
                sd_bus *bus,
1024
                const char *path,
1025
                const char *interface,
1026
                const char *property,
1027
                sd_bus_message *reply,
1028
                void *userdata,
1029
                sd_bus_error *error) {
1030

1031
        ImagePolicy **pp = ASSERT_PTR(userdata);
3,957✔
1032
        _cleanup_free_ char *s = NULL;
3,957✔
1033
        int r;
3,957✔
1034

1035
        assert(bus);
3,957✔
1036
        assert(property);
3,957✔
1037
        assert(reply);
3,957✔
1038

1039
        r = image_policy_to_string(*pp ?: &image_policy_service, /* simplify= */ true, &s);
7,914✔
1040
        if (r < 0)
3,957✔
1041
                return r;
1042

1043
        return sd_bus_message_append(reply, "s", s);
3,957✔
1044
}
1045

1046
static int property_get_private_tmp(
1,319✔
1047
                sd_bus *bus,
1048
                const char *path,
1049
                const char *interface,
1050
                const char *property,
1051
                sd_bus_message *reply,
1052
                void *userdata,
1053
                sd_bus_error *error) {
1054

1055
        PrivateTmp *p = ASSERT_PTR(userdata);
1,319✔
1056
        int b = *p != PRIVATE_TMP_NO;
1,319✔
1057

1058
        return sd_bus_message_append_basic(reply, 'b', &b);
1,319✔
1059
}
1060

1061
static int property_get_private_users(
1,319✔
1062
                sd_bus *bus,
1063
                const char *path,
1064
                const char *interface,
1065
                const char *property,
1066
                sd_bus_message *reply,
1067
                void *userdata,
1068
                sd_bus_error *error) {
1069

1070
        PrivateUsers *p = ASSERT_PTR(userdata);
1,319✔
1071
        int b = *p != PRIVATE_USERS_NO;
1,319✔
1072

1073
        return sd_bus_message_append_basic(reply, 'b', &b);
1,319✔
1074
}
1075

1076
static int property_get_protect_control_groups(
1,319✔
1077
                sd_bus *bus,
1078
                const char *path,
1079
                const char *interface,
1080
                const char *property,
1081
                sd_bus_message *reply,
1082
                void *userdata,
1083
                sd_bus_error *error) {
1084

1085
        ProtectControlGroups *p = ASSERT_PTR(userdata);
1,319✔
1086
        int b = *p != PROTECT_CONTROL_GROUPS_NO;
1,319✔
1087

1088
        return sd_bus_message_append_basic(reply, 'b', &b);
1,319✔
1089
}
1090

1091
static int property_get_protect_hostname(
1,319✔
1092
                sd_bus *bus,
1093
                const char *path,
1094
                const char *interface,
1095
                const char *property,
1096
                sd_bus_message *reply,
1097
                void *userdata,
1098
                sd_bus_error *error) {
1099

1100
        ProtectHostname *p = ASSERT_PTR(userdata);
1,319✔
1101
        int b = *p != PROTECT_HOSTNAME_NO;
1,319✔
1102

1103
        return sd_bus_message_append_basic(reply, 'b', &b);
1,319✔
1104
}
1105

1106
static int property_get_protect_hostname_ex(
1,319✔
1107
                sd_bus *bus,
1108
                const char *path,
1109
                const char *interface,
1110
                const char *property,
1111
                sd_bus_message *reply,
1112
                void *userdata,
1113
                sd_bus_error *error) {
1114

1115
        ExecContext *c = ASSERT_PTR(userdata);
1,319✔
1116

1117
        return sd_bus_message_append(reply, "(ss)", protect_hostname_to_string(c->protect_hostname), c->private_hostname);
1,319✔
1118
}
1119

1120
static int property_get_unsigned_as_uint16(
2,638✔
1121
                sd_bus *bus,
1122
                const char *path,
1123
                const char *interface,
1124
                const char *property,
1125
                sd_bus_message *reply,
1126
                void *userdata,
1127
                sd_bus_error *error) {
1128

1129
        unsigned *value = ASSERT_PTR(userdata);
2,638✔
1130

1131
        /* 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. */
1132

1133
        uint16_t q = *value >= UINT16_MAX ? UINT16_MAX : (uint16_t) *value;
2,638✔
1134
        return sd_bus_message_append_basic(reply, 'q', &q);
2,638✔
1135
}
1136

1137
static int property_get_bpf_delegate_commands(
1,319✔
1138
                sd_bus *bus,
1139
                const char *path,
1140
                const char *interface,
1141
                const char *property,
1142
                sd_bus_message *reply,
1143
                void *userdata,
1144
                sd_bus_error *error) {
1145

1146
        uint64_t *u = ASSERT_PTR(userdata);
1,319✔
1147
        _cleanup_free_ char *s = NULL;
1,319✔
1148

1149
        assert(reply);
1,319✔
1150

1151
        s = bpf_delegate_commands_to_string(*u);
1,319✔
1152
        if (!s)
1,319✔
1153
                return -ENOMEM;
1154

1155
        return sd_bus_message_append(reply, "s", s);
1,319✔
1156
}
1157

1158
static int property_get_bpf_delegate_maps(
1,319✔
1159
                sd_bus *bus,
1160
                const char *path,
1161
                const char *interface,
1162
                const char *property,
1163
                sd_bus_message *reply,
1164
                void *userdata,
1165
                sd_bus_error *error) {
1166

1167
        uint64_t *u = ASSERT_PTR(userdata);
1,319✔
1168
        _cleanup_free_ char *s = NULL;
1,319✔
1169

1170
        assert(reply);
1,319✔
1171

1172
        s = bpf_delegate_maps_to_string(*u);
1,319✔
1173
        if (!s)
1,319✔
1174
                return -ENOMEM;
1175

1176
        return sd_bus_message_append(reply, "s", s);
1,319✔
1177
}
1178

1179
static int property_get_bpf_delegate_programs(
1,319✔
1180
                sd_bus *bus,
1181
                const char *path,
1182
                const char *interface,
1183
                const char *property,
1184
                sd_bus_message *reply,
1185
                void *userdata,
1186
                sd_bus_error *error) {
1187

1188
        uint64_t *u = ASSERT_PTR(userdata);
1,319✔
1189
        _cleanup_free_ char *s = NULL;
1,319✔
1190

1191
        assert(reply);
1,319✔
1192

1193
        s = bpf_delegate_programs_to_string(*u);
1,319✔
1194
        if (!s)
1,319✔
1195
                return -ENOMEM;
1196

1197
        return sd_bus_message_append(reply, "s", s);
1,319✔
1198
}
1199

1200
static int property_get_bpf_delegate_attachments(
1,319✔
1201
                sd_bus *bus,
1202
                const char *path,
1203
                const char *interface,
1204
                const char *property,
1205
                sd_bus_message *reply,
1206
                void *userdata,
1207
                sd_bus_error *error) {
1208

1209
        uint64_t *u = ASSERT_PTR(userdata);
1,319✔
1210
        _cleanup_free_ char *s = NULL;
1,319✔
1211

1212
        assert(reply);
1,319✔
1213

1214
        s = bpf_delegate_attachments_to_string(*u);
1,319✔
1215
        if (!s)
1,319✔
1216
                return -ENOMEM;
1217

1218
        return sd_bus_message_append(reply, "s", s);
1,319✔
1219
}
1220

1221
const sd_bus_vtable bus_exec_vtable[] = {
1222
        SD_BUS_VTABLE_START(0),
1223
        SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
1224
        SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1225
        SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
1226
        SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
1227
        SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
1228
        SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1229
        SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1230
        SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1231
        SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1232
        SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1233
        SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1234
        SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1235
        SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1236
        SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1237
        SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1238
        SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1239
        SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1240
        SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1241
        SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1242
        SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1243
        SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1244
        SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1245
        SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1246
        SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1247
        SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1248
        SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1249
        SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1250
        SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1251
        SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1252
        SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1253
        SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1254
        SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1255
        SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1256
        SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1257
        SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1258
        SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1259
        SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1260
        SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1261
        SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
1262
        SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
1263
        SD_BUS_PROPERTY("RootImageOptions", "a(ss)", property_get_root_image_options, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1264
        SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1265
        SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
1266
        SD_BUS_PROPERTY("RootHashSignature", "ay", property_get_root_hash_sig, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1267
        SD_BUS_PROPERTY("RootHashSignaturePath", "s", NULL, offsetof(ExecContext, root_hash_sig_path), SD_BUS_VTABLE_PROPERTY_CONST),
1268
        SD_BUS_PROPERTY("RootVerity", "s", NULL, offsetof(ExecContext, root_verity), SD_BUS_VTABLE_PROPERTY_CONST),
1269
        SD_BUS_PROPERTY("RootEphemeral", "b", bus_property_get_bool, offsetof(ExecContext, root_ephemeral), SD_BUS_VTABLE_PROPERTY_CONST),
1270
        SD_BUS_PROPERTY("ExtensionDirectories", "as", NULL, offsetof(ExecContext, extension_directories), SD_BUS_VTABLE_PROPERTY_CONST),
1271
        SD_BUS_PROPERTY("ExtensionImages", "a(sba(ss))", property_get_extension_images, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1272
        SD_BUS_PROPERTY("MountImages", "a(ssba(ss))", property_get_mount_images, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1273
        SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1274
        SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1275
        SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1276
        SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1277
        SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1278
        SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1279
        SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1280
        SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1281
        SD_BUS_PROPERTY("CPUAffinityFromNUMA", "b", property_get_cpu_affinity_from_numa, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1282
        SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1283
        SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1284
        SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1285
        SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
1286
        SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
1287
        SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
1288
        SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1289
        SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1290
        SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1291
        SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1292
        SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
1293
        SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1294
        SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
1295
        SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
1296
        SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
1297
        SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
1298
        SD_BUS_PROPERTY("TTYRows", "q", property_get_unsigned_as_uint16, offsetof(ExecContext, tty_rows), SD_BUS_VTABLE_PROPERTY_CONST),
1299
        SD_BUS_PROPERTY("TTYColumns", "q", property_get_unsigned_as_uint16, offsetof(ExecContext, tty_cols), SD_BUS_VTABLE_PROPERTY_CONST),
1300
        SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1301
        SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
1302
        SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
1303
        SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1304
        SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
1305
        SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
1306
        SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
1307
        SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
1308
        SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1309
        SD_BUS_PROPERTY("LogFilterPatterns", "a(bs)", property_get_log_filter_patterns, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1310
        SD_BUS_PROPERTY("LogNamespace", "s", NULL, offsetof(ExecContext, log_namespace), SD_BUS_VTABLE_PROPERTY_CONST),
1311
        SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
1312
        SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
1313
        SD_BUS_PROPERTY("AmbientCapabilities", "t", NULL, offsetof(ExecContext, capability_ambient_set), SD_BUS_VTABLE_PROPERTY_CONST),
1314
        SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
1315
        SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
1316
        SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
1317
        SD_BUS_PROPERTY("SetLoginEnvironment", "b", property_get_set_login_environment, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1318
        SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
1319
        SD_BUS_PROPERTY("SetCredential", "a(say)", property_get_set_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1320
        SD_BUS_PROPERTY("SetCredentialEncrypted", "a(say)", property_get_set_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1321
        SD_BUS_PROPERTY("LoadCredential", "a(ss)", property_get_load_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1322
        SD_BUS_PROPERTY("LoadCredentialEncrypted", "a(ss)", property_get_load_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1323
        SD_BUS_PROPERTY("ImportCredential", "as", property_get_import_credential, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1324
        SD_BUS_PROPERTY("ImportCredentialEx", "a(ss)", property_get_import_credential_ex, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1325
        SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1326
        SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
1327
        SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1328
        SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1329
        SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1330
        SD_BUS_PROPERTY("ExecPaths", "as", NULL, offsetof(ExecContext, exec_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1331
        SD_BUS_PROPERTY("NoExecPaths", "as", NULL, offsetof(ExecContext, no_exec_paths), SD_BUS_VTABLE_PROPERTY_CONST),
1332
        SD_BUS_PROPERTY("ExecSearchPath", "as", NULL, offsetof(ExecContext, exec_search_path), SD_BUS_VTABLE_PROPERTY_CONST),
1333
        SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_propagation_flag), SD_BUS_VTABLE_PROPERTY_CONST),
1334
        SD_BUS_PROPERTY("PrivateTmp", "b", property_get_private_tmp, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
1335
        SD_BUS_PROPERTY("PrivateTmpEx", "s", property_get_private_tmp_ex, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
1336
        SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
1337
        SD_BUS_PROPERTY("ProtectClock", "b", bus_property_get_bool, offsetof(ExecContext, protect_clock), SD_BUS_VTABLE_PROPERTY_CONST),
1338
        SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
1339
        SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
1340
        SD_BUS_PROPERTY("ProtectKernelLogs", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_logs), SD_BUS_VTABLE_PROPERTY_CONST),
1341
        SD_BUS_PROPERTY("ProtectControlGroups", "b", property_get_protect_control_groups, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1342
        SD_BUS_PROPERTY("ProtectControlGroupsEx", "s", property_get_protect_control_groups_ex, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
1343
        SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
1344
        SD_BUS_PROPERTY("PrivateUsers", "b", property_get_private_users, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
1345
        SD_BUS_PROPERTY("PrivateUsersEx", "s", property_get_private_users_ex, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
1346
        SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_tristate, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST),
1347
        SD_BUS_PROPERTY("PrivateIPC", "b", bus_property_get_bool, offsetof(ExecContext, private_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
1348
        SD_BUS_PROPERTY("PrivatePIDs", "s", property_get_private_pids, offsetof(ExecContext, private_pids), SD_BUS_VTABLE_PROPERTY_CONST),
1349
        SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
1350
        SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
1351
        SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
1352
        SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
1353
        SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1354
        SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1355
        SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1356
        SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1357
        SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
1358
        SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
1359
        SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1360
        SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1361
        SD_BUS_PROPERTY("SystemCallErrorNumber", "i", bus_property_get_int, offsetof(ExecContext, syscall_errno), SD_BUS_VTABLE_PROPERTY_CONST),
1362
        SD_BUS_PROPERTY("SystemCallLog", "(bas)", property_get_syscall_log, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1363
        SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST),
1364
        SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
1365
        SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1366
        SD_BUS_PROPERTY("RuntimeDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1367
        SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", bus_property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1368
        SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1369
        SD_BUS_PROPERTY("RuntimeDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1370
        SD_BUS_PROPERTY("StateDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
1371
        SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1372
        SD_BUS_PROPERTY("StateDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1373
        SD_BUS_PROPERTY("StateDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
1374
        SD_BUS_PROPERTY("StateDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
1375
        SD_BUS_PROPERTY("CacheDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
1376
        SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1377
        SD_BUS_PROPERTY("CacheDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1378
        SD_BUS_PROPERTY("CacheDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
1379
        SD_BUS_PROPERTY("CacheDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
1380
        SD_BUS_PROPERTY("LogsDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
1381
        SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1382
        SD_BUS_PROPERTY("LogsDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1383
        SD_BUS_PROPERTY("LogsDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
1384
        SD_BUS_PROPERTY("LogsDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
1385
        SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
1386
        SD_BUS_PROPERTY("ConfigurationDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION]), SD_BUS_VTABLE_PROPERTY_CONST),
1387
        SD_BUS_PROPERTY("TimeoutCleanUSec", "t", bus_property_get_usec, offsetof(ExecContext, timeout_clean_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1388
        SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
1389
        SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
1390
        SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
1391
        SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
1392
        SD_BUS_PROPERTY("DelegateNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, delegate_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
1393
        SD_BUS_PROPERTY("RestrictFileSystems", "(bas)", property_get_restrict_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1394
        SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1395
        SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1396
        SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1397
        SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1398
        SD_BUS_PROPERTY("BindLogSockets", "b", property_get_bind_log_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1399
        SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
1400
        SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
1401
        SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
1402
        SD_BUS_PROPERTY("ProtectHostname", "b", property_get_protect_hostname, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
1403
        SD_BUS_PROPERTY("ProtectHostnameEx", "(ss)", property_get_protect_hostname_ex, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1404
        SD_BUS_PROPERTY("PrivateBPF", "s", property_get_private_bpf, offsetof(ExecContext, private_bpf), SD_BUS_VTABLE_PROPERTY_CONST),
1405
        SD_BUS_PROPERTY("BPFDelegateCommands", "s", property_get_bpf_delegate_commands, offsetof(ExecContext, bpf_delegate_commands), SD_BUS_VTABLE_PROPERTY_CONST),
1406
        SD_BUS_PROPERTY("BPFDelegateMaps", "s", property_get_bpf_delegate_maps, offsetof(ExecContext, bpf_delegate_maps), SD_BUS_VTABLE_PROPERTY_CONST),
1407
        SD_BUS_PROPERTY("BPFDelegatePrograms", "s", property_get_bpf_delegate_programs, offsetof(ExecContext, bpf_delegate_programs), SD_BUS_VTABLE_PROPERTY_CONST),
1408
        SD_BUS_PROPERTY("BPFDelegateAttachments", "s", property_get_bpf_delegate_attachments, offsetof(ExecContext, bpf_delegate_attachments), SD_BUS_VTABLE_PROPERTY_CONST),
1409
        SD_BUS_PROPERTY("MemoryKSM", "b", bus_property_get_tristate, offsetof(ExecContext, memory_ksm), SD_BUS_VTABLE_PROPERTY_CONST),
1410
        SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
1411
        SD_BUS_PROPERTY("IPCNamespacePath", "s", NULL, offsetof(ExecContext, ipc_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
1412
        SD_BUS_PROPERTY("RootImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, root_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1413
        SD_BUS_PROPERTY("MountImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, mount_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1414
        SD_BUS_PROPERTY("ExtensionImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, extension_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
1415

1416
        /* Obsolete/redundant properties: */
1417
        SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1418
        SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1419
        SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1420
        SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1421
        SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1422

1423
        SD_BUS_VTABLE_END
1424
};
1425

1426
static int property_get_quota_usage(
3,957✔
1427
                sd_bus *bus,
1428
                const char *path,
1429
                const char *interface,
1430
                const char *property,
1431
                sd_bus_message *reply,
1432
                void *userdata,
1433
                sd_bus_error *error) {
1434

1435
        Unit *u = ASSERT_PTR(userdata);
3,957✔
1436
        ExecContext *c = ASSERT_PTR(unit_get_exec_context(u));
3,957✔
1437
        uint64_t current_usage_bytes = UINT64_MAX, limit_bytes = UINT64_MAX;
3,957✔
1438
        int r;
3,957✔
1439

1440
        assert(bus);
3,957✔
1441
        assert(reply);
3,957✔
1442

1443
        ExecDirectoryType dt;
3,957✔
1444
        if (streq(property, "StateDirectoryQuotaUsage"))
3,957✔
1445
                dt = EXEC_DIRECTORY_STATE;
1446
        else if (streq(property, "CacheDirectoryQuotaUsage"))
2,638✔
1447
                dt = EXEC_DIRECTORY_CACHE;
1448
        else if (streq(property, "LogsDirectoryQuotaUsage"))
1,319✔
1449
                dt = EXEC_DIRECTORY_LOGS;
1450
        else
1451
                assert_not_reached();
×
1452

1453
        const QuotaLimit *q;
3,957✔
1454
        q = &c->directories[dt].exec_quota;
3,957✔
1455

1456
        if (q->quota_enforce || q->quota_accounting) {
3,957✔
1457
                r = unit_get_exec_quota_stats(u, c, dt, &current_usage_bytes, &limit_bytes);
×
1458
                if (r < 0)
×
1459
                        return r;
3,957✔
1460
        }
1461

1462
        if (!q->quota_enforce)
3,957✔
1463
                limit_bytes = UINT64_MAX;
3,957✔
1464
        if (!q->quota_accounting)
3,957✔
1465
                current_usage_bytes = UINT64_MAX;
3,957✔
1466

1467
        return sd_bus_message_append(reply, "(tt)", current_usage_bytes, limit_bytes);
3,957✔
1468
}
1469

1470
const sd_bus_vtable bus_unit_exec_vtable[] = {
1471
        SD_BUS_VTABLE_START(0),
1472

1473
        SD_BUS_PROPERTY("StateDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
1474
        SD_BUS_PROPERTY("CacheDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
1475
        SD_BUS_PROPERTY("LogsDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
1476

1477
        SD_BUS_VTABLE_END
1478
};
1479

1480
static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
1,499✔
1481
        int r;
1,499✔
1482

1483
        assert(reply);
1,499✔
1484
        assert(c);
1,499✔
1485

1486
        if (!c->path)
1,499✔
1487
                return 0;
1488

1489
        r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
1,272✔
1490
        if (r < 0)
1,272✔
1491
                return r;
1492

1493
        r = sd_bus_message_append(reply, "s", c->path);
1,272✔
1494
        if (r < 0)
1,272✔
1495
                return r;
1496

1497
        r = sd_bus_message_append_strv(reply, c->argv);
1,272✔
1498
        if (r < 0)
1,272✔
1499
                return r;
1500

1501
        r = sd_bus_message_append(reply, "bttttuii",
2,544✔
1502
                                  !!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
1,272✔
1503
                                  c->exec_status.start_timestamp.realtime,
1504
                                  c->exec_status.start_timestamp.monotonic,
1505
                                  c->exec_status.exit_timestamp.realtime,
1506
                                  c->exec_status.exit_timestamp.monotonic,
1507
                                  (uint32_t) c->exec_status.pid,
1,272✔
1508
                                  (int32_t) c->exec_status.code,
1509
                                  (int32_t) c->exec_status.status);
1510
        if (r < 0)
1,272✔
1511
                return r;
1512

1513
        return sd_bus_message_close_container(reply);
1,272✔
1514
}
1515

1516
static int append_exec_ex_command(sd_bus_message *reply, ExecCommand *c) {
1,268✔
1517
        _cleanup_strv_free_ char **ex_opts = NULL;
1,268✔
1518
        int r;
1,268✔
1519

1520
        assert(reply);
1,268✔
1521
        assert(c);
1,268✔
1522

1523
        if (!c->path)
1,268✔
1524
                return 0;
1525

1526
        r = sd_bus_message_open_container(reply, 'r', "sasasttttuii");
1,268✔
1527
        if (r < 0)
1,268✔
1528
                return r;
1529

1530
        r = sd_bus_message_append(reply, "s", c->path);
1,268✔
1531
        if (r < 0)
1,268✔
1532
                return r;
1533

1534
        r = sd_bus_message_append_strv(reply, c->argv);
1,268✔
1535
        if (r < 0)
1,268✔
1536
                return r;
1537

1538
        r = exec_command_flags_to_strv(c->flags, &ex_opts);
1,268✔
1539
        if (r < 0)
1,268✔
1540
                return r;
1541

1542
        r = sd_bus_message_append_strv(reply, ex_opts);
1,268✔
1543
        if (r < 0)
1,268✔
1544
                return r;
1545

1546
        r = sd_bus_message_append(reply, "ttttuii",
2,536✔
1547
                                  c->exec_status.start_timestamp.realtime,
1548
                                  c->exec_status.start_timestamp.monotonic,
1549
                                  c->exec_status.exit_timestamp.realtime,
1550
                                  c->exec_status.exit_timestamp.monotonic,
1551
                                  (uint32_t) c->exec_status.pid,
1,268✔
1552
                                  (int32_t) c->exec_status.code,
1553
                                  (int32_t) c->exec_status.status);
1554
        if (r < 0)
1,268✔
1555
                return r;
1556

1557
        return sd_bus_message_close_container(reply);
1,268✔
1558
}
1559

1560
int bus_property_get_exec_command(
231✔
1561
                sd_bus *bus,
1562
                const char *path,
1563
                const char *interface,
1564
                const char *property,
1565
                sd_bus_message *reply,
1566
                void *userdata,
1567
                sd_bus_error *ret_error) {
1568

1569
        ExecCommand *c = (ExecCommand*) userdata;
231✔
1570
        int r;
231✔
1571

1572
        assert(bus);
231✔
1573
        assert(reply);
231✔
1574

1575
        r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
231✔
1576
        if (r < 0)
231✔
1577
                return r;
1578

1579
        r = append_exec_command(reply, c);
231✔
1580
        if (r < 0)
231✔
1581
                return r;
1582

1583
        return sd_bus_message_close_container(reply);
231✔
1584
}
1585

1586
int bus_property_get_exec_command_list(
8,352✔
1587
                sd_bus *bus,
1588
                const char *path,
1589
                const char *interface,
1590
                const char *property,
1591
                sd_bus_message *reply,
1592
                void *userdata,
1593
                sd_bus_error *ret_error) {
1594

1595
        ExecCommand *exec_command = *(ExecCommand**) userdata;
8,352✔
1596
        int r;
8,352✔
1597

1598
        assert(bus);
8,352✔
1599
        assert(reply);
8,352✔
1600

1601
        r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
8,352✔
1602
        if (r < 0)
8,352✔
1603
                return r;
1604

1605
        LIST_FOREACH(command, c, exec_command) {
9,620✔
1606
                r = append_exec_command(reply, c);
1,268✔
1607
                if (r < 0)
1,268✔
1608
                        return r;
1609
        }
1610

1611
        return sd_bus_message_close_container(reply);
8,352✔
1612
}
1613

1614
int bus_property_get_exec_ex_command_list(
7,896✔
1615
                sd_bus *bus,
1616
                const char *path,
1617
                const char *interface,
1618
                const char *property,
1619
                sd_bus_message *reply,
1620
                void *userdata,
1621
                sd_bus_error *ret_error) {
1622

1623
        ExecCommand *exec_command = *(ExecCommand**) userdata;
7,896✔
1624
        int r;
7,896✔
1625

1626
        assert(bus);
7,896✔
1627
        assert(reply);
7,896✔
1628

1629
        r = sd_bus_message_open_container(reply, 'a', "(sasasttttuii)");
7,896✔
1630
        if (r < 0)
7,896✔
1631
                return r;
1632

1633
        LIST_FOREACH(command, c, exec_command) {
9,164✔
1634
                r = append_exec_ex_command(reply, c);
1,268✔
1635
                if (r < 0)
1,268✔
1636
                        return r;
1637
        }
1638

1639
        return sd_bus_message_close_container(reply);
7,896✔
1640
}
1641

1642
static char* exec_command_flags_to_exec_chars(ExecCommandFlags flags) {
149✔
1643
        return strjoin(FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE)   ? "-" : "",
893✔
1644
                       FLAGS_SET(flags, EXEC_COMMAND_NO_ENV_EXPAND)    ? ":" : "",
1645
                       FLAGS_SET(flags, EXEC_COMMAND_FULLY_PRIVILEGED) ? "+" : "",
1646
                       FLAGS_SET(flags, EXEC_COMMAND_NO_SETUID)        ? "!" : "",
1647
                       FLAGS_SET(flags, EXEC_COMMAND_VIA_SHELL)        ? "|" : "");
1648
}
1649

1650
int bus_set_transient_exec_command(
298✔
1651
                Unit *u,
1652
                const char *name,
1653
                ExecCommand **exec_command,
1654
                sd_bus_message *message,
1655
                UnitWriteFlags flags,
1656
                sd_bus_error *error) {
1657

1658
        const char *ex_prop = endswith(ASSERT_PTR(name), "Ex");
298✔
1659
        size_t n = 0;
298✔
1660
        int r;
298✔
1661

1662
        assert(u);
298✔
1663
        assert(exec_command);
298✔
1664
        assert(message);
298✔
1665
        assert(error);
298✔
1666

1667
        /* Drop Ex from the written setting. E.g. ExecStart=, not ExecStartEx=. */
1668
        const char *written_name = ex_prop ? strndupa_safe(name, ex_prop - name) : name;
298✔
1669

1670
        r = sd_bus_message_enter_container(message, 'a', ex_prop ? "(sasas)" : "(sasb)");
298✔
1671
        if (r < 0)
298✔
1672
                return r;
1673

1674
        while ((r = sd_bus_message_enter_container(message, 'r', ex_prop ? "sasas" : "sasb")) > 0) {
1,192✔
1675
                _cleanup_strv_free_ char **argv = NULL;
×
1676
                const char *path;
298✔
1677
                ExecCommandFlags command_flags;
298✔
1678

1679
                r = sd_bus_message_read(message, "s", &path);
298✔
1680
                if (r < 0)
298✔
1681
                        return r;
1682

1683
                r = sd_bus_message_read_strv(message, &argv);
298✔
1684
                if (r < 0)
298✔
1685
                        return r;
1686

1687
                if (ex_prop) {
298✔
1688
                        _cleanup_strv_free_ char **ex_opts = NULL;
×
1689

1690
                        r = sd_bus_message_read_strv(message, &ex_opts);
×
1691
                        if (r < 0)
×
1692
                                return r;
1693

1694
                        r = exec_command_flags_from_strv(ex_opts, &command_flags);
×
1695
                        if (r < 0)
×
1696
                                return r;
1697
                } else {
1698
                        int b;
298✔
1699

1700
                        r = sd_bus_message_read(message, "b", &b);
298✔
1701
                        if (r < 0)
298✔
1702
                                return r;
×
1703

1704
                        command_flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
298✔
1705
                }
1706

1707
                if (!FLAGS_SET(command_flags, EXEC_COMMAND_VIA_SHELL)) {
298✔
1708
                        if (!filename_or_absolute_path_is_valid(path))
298✔
1709
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1710
                                                         "\"%s\" is neither a valid executable name nor an absolute path",
1711
                                                         path);
1712

1713
                        if (strv_isempty(argv))
298✔
1714
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1715
                                                         "\"%s\" argv cannot be empty", name);
1716
                } else {
1717
                        /* Always normalize path and argv0 to be "sh" */
1718
                        path = _PATH_BSHELL;
×
1719

1720
                        if (strv_isempty(argv))
×
1721
                                r = strv_extend(&argv, "sh");
×
1722
                        else
1723
                                r = free_and_strdup(&argv[0], argv[0][0] == '-' ? "-sh" : "sh");
×
1724
                        if (r < 0)
×
1725
                                return r;
1726
                }
1727

1728
                r = sd_bus_message_exit_container(message);
298✔
1729
                if (r < 0)
298✔
1730
                        return r;
1731

1732
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
298✔
1733
                        _cleanup_(exec_command_freep) ExecCommand *c = NULL;
149✔
1734

1735
                        c = new(ExecCommand, 1);
149✔
1736
                        if (!c)
149✔
1737
                                return -ENOMEM;
1738

1739
                        *c = (ExecCommand) {
149✔
1740
                                .argv = TAKE_PTR(argv),
149✔
1741
                                .flags = command_flags,
1742
                        };
1743

1744
                        r = path_simplify_alloc(path, &c->path);
149✔
1745
                        if (r < 0)
149✔
1746
                                return r;
1747

1748
                        exec_command_append_list(exec_command, TAKE_PTR(c));
149✔
1749
                }
1750

1751
                n++;
298✔
1752
        }
1753
        if (r < 0)
298✔
1754
                return r;
1755

1756
        r = sd_bus_message_exit_container(message);
298✔
1757
        if (r < 0)
298✔
1758
                return r;
1759

1760
        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
298✔
1761
                _cleanup_(memstream_done) MemStream m = {};
×
1762
                _cleanup_free_ char *buf = NULL;
149✔
1763
                FILE *f;
149✔
1764

1765
                if (n == 0)
149✔
1766
                        *exec_command = exec_command_free_list(*exec_command);
×
1767

1768
                f = memstream_init(&m);
149✔
1769
                if (!f)
149✔
1770
                        return -ENOMEM;
1771

1772
                fprintf(f, "%s=\n", written_name);
149✔
1773

1774
                LIST_FOREACH(command, c, *exec_command) {
298✔
1775
                        _cleanup_free_ char *a = NULL, *exec_chars = NULL;
149✔
1776
                        UnitWriteFlags esc_flags = UNIT_ESCAPE_SPECIFIERS |
149✔
1777
                                (FLAGS_SET(c->flags, EXEC_COMMAND_NO_ENV_EXPAND) ? UNIT_ESCAPE_EXEC_SYNTAX : UNIT_ESCAPE_EXEC_SYNTAX_ENV);
149✔
1778
                        bool via_shell = FLAGS_SET(c->flags, EXEC_COMMAND_VIA_SHELL);
149✔
1779

1780
                        exec_chars = exec_command_flags_to_exec_chars(c->flags);
149✔
1781
                        if (!exec_chars)
149✔
1782
                                return -ENOMEM;
1783

1784
                        a = unit_concat_strv(via_shell ? strv_skip(c->argv, 1) : c->argv, esc_flags);
149✔
1785
                        if (!a)
149✔
1786
                                return -ENOMEM;
1787

1788
                        if (via_shell || streq(c->path, c->argv[0]))
149✔
1789
                                fprintf(f, "%s=%s%s%s\n",
149✔
1790
                                        written_name, exec_chars, via_shell && c->argv[0][0] == '-' ? "@" : "", a);
×
1791
                        else {
1792
                                _cleanup_free_ char *t = NULL;
×
1793
                                const char *p;
×
1794

1795
                                p = unit_escape_setting(c->path, esc_flags, &t);
×
1796
                                if (!p)
×
1797
                                        return -ENOMEM;
×
1798

1799
                                fprintf(f, "%s=%s@%s %s\n", written_name, exec_chars, p, a);
×
1800
                        }
1801
                }
1802

1803
                r = memstream_finalize(&m, &buf, NULL);
149✔
1804
                if (r < 0)
149✔
1805
                        return r;
1806

1807
                unit_write_setting(u, flags, written_name, buf);
149✔
1808
        }
1809

1810
        return 1;
1811
}
1812

1813
static int parse_personality(const char *s, unsigned long *p) {
×
1814
        unsigned long v;
×
1815

1816
        assert(p);
×
1817

1818
        v = personality_from_string(s);
×
1819
        if (v == PERSONALITY_INVALID)
×
1820
                return -EINVAL;
1821

1822
        *p = v;
×
1823
        return 0;
×
1824
}
1825

1826
static const char* mount_propagation_flag_to_string_with_check(unsigned long n) {
2✔
1827
        if (!mount_propagation_flag_is_valid(n))
2✔
1828
                return NULL;
1829

1830
        return mount_propagation_flag_to_string(n);
2✔
1831
}
1832

1833
static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
×
1834
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
×
1835
#if HAVE_SECCOMP
1836
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, seccomp_errno_or_action_is_valid);
×
1837
#endif
1838
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
×
1839
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
60✔
1840
static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
×
1841
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
2✔
1842
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
6✔
1843
static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
×
1844
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string);
10✔
1845
static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string);
6✔
1846
static BUS_DEFINE_SET_TRANSIENT_PARSE(private_bpf, PrivateBPF, private_bpf_from_string);
×
1847
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_commands, uint64_t, bpf_delegate_commands_from_string);
×
1848
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_maps, uint64_t, bpf_delegate_maps_from_string);
×
1849
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_programs, uint64_t, bpf_delegate_programs_from_string);
×
1850
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_attachments, uint64_t, bpf_delegate_attachments_from_string);
×
1851
BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
10✔
1852
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
×
1853
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
×
1854
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string);
10✔
1855
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
20✔
1856
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_propagation_flag, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flag_to_string_with_check);
2✔
1857

1858
int bus_exec_context_set_transient_property(
1,146✔
1859
                Unit *u,
1860
                ExecContext *c,
1861
                const char *name,
1862
                sd_bus_message *message,
1863
                UnitWriteFlags flags,
1864
                sd_bus_error *error) {
1865

1866
        const char *suffix;
1,146✔
1867
        int r;
1,146✔
1868

1869
        assert(u);
1,146✔
1870
        assert(c);
1,146✔
1871
        assert(name);
1,146✔
1872
        assert(message);
1,146✔
1873

1874
        flags |= UNIT_PRIVATE;
1,146✔
1875

1876
        if (streq(name, "User"))
1,146✔
1877
                return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error);
26✔
1878

1879
        if (streq(name, "Group"))
1,120✔
1880
                return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error);
4✔
1881

1882
        if (streq(name, "SetLoginEnvironment"))
1,116✔
1883
                return bus_set_transient_tristate(u, name, &c->set_login_environment, message, flags, error);
×
1884

1885
        if (streq(name, "TTYPath"))
1,116✔
1886
                return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
×
1887

1888
        if (streq(name, "RootImage"))
1,116✔
1889
                return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
2✔
1890

1891
        if (streq(name, "RootImageOptions")) {
1,114✔
1892
                _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
1893
                _cleanup_free_ char *format_str = NULL;
×
1894

1895
                r = bus_read_mount_options(message, error, &options, &format_str, " ");
×
1896
                if (r < 0)
×
1897
                        return r;
1898

1899
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1900
                        if (options) {
×
1901
                                LIST_JOIN(mount_options, c->root_image_options, options);
×
1902
                                unit_write_settingf(
×
1903
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
1904
                                                "%s=%s",
1905
                                                name,
1906
                                                format_str);
1907
                        } else {
1908
                                c->root_image_options = mount_options_free_all(c->root_image_options);
×
1909
                                unit_write_settingf(u, flags, name, "%s=", name);
×
1910
                        }
1911
                }
1912

1913
                return 1;
×
1914
        }
1915

1916
        if (streq(name, "RootHash")) {
1,114✔
1917
                const void *roothash_decoded;
×
1918
                size_t roothash_decoded_size;
×
1919

1920
                r = sd_bus_message_read_array(message, 'y', &roothash_decoded, &roothash_decoded_size);
×
1921
                if (r < 0)
×
1922
                        return r;
×
1923

1924
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1925
                        _cleanup_free_ char *encoded = NULL;
×
1926

1927
                        if (roothash_decoded_size == 0) {
×
1928
                                c->root_hash_path = mfree(c->root_hash_path);
×
1929
                                c->root_hash = mfree(c->root_hash);
×
1930
                                c->root_hash_size = 0;
×
1931

1932
                                unit_write_settingf(u, flags, name, "RootHash=");
×
1933
                        } else {
1934
                                _cleanup_free_ void *p = NULL;
×
1935

1936
                                encoded = hexmem(roothash_decoded, roothash_decoded_size);
×
1937
                                if (!encoded)
×
1938
                                        return -ENOMEM;
1939

1940
                                p = memdup(roothash_decoded, roothash_decoded_size);
×
1941
                                if (!p)
×
1942
                                        return -ENOMEM;
1943

1944
                                free_and_replace(c->root_hash, p);
×
1945
                                c->root_hash_size = roothash_decoded_size;
×
1946
                                c->root_hash_path = mfree(c->root_hash_path);
×
1947

1948
                                unit_write_settingf(u, flags, name, "RootHash=%s", encoded);
×
1949
                        }
1950
                }
1951

1952
                return 1;
×
1953
        }
1954

1955
        if (streq(name, "RootHashPath")) {
1,114✔
1956
                c->root_hash_size = 0;
×
1957
                c->root_hash = mfree(c->root_hash);
×
1958

1959
                return bus_set_transient_path(u, "RootHash", &c->root_hash_path, message, flags, error);
×
1960
        }
1961

1962
        if (streq(name, "RootHashSignature")) {
1,114✔
1963
                const void *roothash_sig_decoded;
×
1964
                size_t roothash_sig_decoded_size;
×
1965

1966
                r = sd_bus_message_read_array(message, 'y', &roothash_sig_decoded, &roothash_sig_decoded_size);
×
1967
                if (r < 0)
×
1968
                        return r;
×
1969

1970
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
1971
                        _cleanup_free_ char *encoded = NULL;
×
1972

1973
                        if (roothash_sig_decoded_size == 0) {
×
1974
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1975
                                c->root_hash_sig = mfree(c->root_hash_sig);
×
1976
                                c->root_hash_sig_size = 0;
×
1977

1978
                                unit_write_settingf(u, flags, name, "RootHashSignature=");
×
1979
                        } else {
1980
                                _cleanup_free_ void *p = NULL;
×
1981
                                ssize_t len;
×
1982

1983
                                len = base64mem(roothash_sig_decoded, roothash_sig_decoded_size, &encoded);
×
1984
                                if (len < 0)
×
1985
                                        return -ENOMEM;
1986

1987
                                p = memdup(roothash_sig_decoded, roothash_sig_decoded_size);
×
1988
                                if (!p)
×
1989
                                        return -ENOMEM;
1990

1991
                                free_and_replace(c->root_hash_sig, p);
×
1992
                                c->root_hash_sig_size = roothash_sig_decoded_size;
×
1993
                                c->root_hash_sig_path = mfree(c->root_hash_sig_path);
×
1994

1995
                                unit_write_settingf(u, flags, name, "RootHashSignature=base64:%s", encoded);
×
1996
                        }
1997
                }
1998

1999
                return 1;
×
2000
        }
2001

2002
        if (streq(name, "RootHashSignaturePath")) {
1,114✔
2003
                c->root_hash_sig_size = 0;
×
2004
                c->root_hash_sig = mfree(c->root_hash_sig);
×
2005

2006
                return bus_set_transient_path(u, "RootHashSignature", &c->root_hash_sig_path, message, flags, error);
×
2007
        }
2008

2009
        if (streq(name, "RootVerity"))
1,114✔
2010
                return bus_set_transient_path(u, name, &c->root_verity, message, flags, error);
×
2011

2012
        if (streq(name, "RootDirectory"))
1,114✔
2013
                return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
8✔
2014

2015
        if (streq(name, "RootEphemeral"))
1,106✔
2016
                return bus_set_transient_bool(u, name, &c->root_ephemeral, message, flags, error);
×
2017

2018
        if (streq(name, "SyslogIdentifier"))
1,106✔
2019
                return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
×
2020

2021
        if (streq(name, "LogLevelMax"))
1,106✔
2022
                return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
×
2023

2024
        if (streq(name, "LogRateLimitIntervalUSec"))
1,106✔
2025
                return bus_set_transient_usec(u, name, &c->log_ratelimit.interval, message, flags, error);
×
2026

2027
        if (streq(name, "LogRateLimitBurst"))
1,106✔
2028
                return bus_set_transient_unsigned(u, name, &c->log_ratelimit.burst, message, flags, error);
×
2029

2030
        if (streq(name, "LogFilterPatterns")) {
1,106✔
2031
                /* Use _cleanup_free_, not _cleanup_strv_free_, as we don't want the content of the strv
2032
                 * to be freed. */
2033
                _cleanup_free_ char **allow_list = NULL, **deny_list = NULL;
×
2034
                const char *pattern;
×
2035
                int is_allowlist;
×
2036

2037
                r = sd_bus_message_enter_container(message, 'a', "(bs)");
×
2038
                if (r < 0)
×
2039
                        return r;
2040

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

2044
                        if (isempty(pattern))
×
2045
                                continue;
×
2046

2047
                        r = pattern_compile_and_log(pattern, 0, &compiled_pattern);
×
2048
                        if (r < 0)
×
2049
                                return r;
2050

2051
                        r = strv_push(is_allowlist ? &allow_list : &deny_list, (char *)pattern);
×
2052
                        if (r < 0)
×
2053
                                return r;
2054
                }
2055
                if (r < 0)
×
2056
                        return r;
2057

2058
                r = sd_bus_message_exit_container(message);
×
2059
                if (r < 0)
×
2060
                        return r;
2061

2062
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2063
                        if (strv_isempty(allow_list) && strv_isempty(deny_list)) {
×
2064
                                c->log_filter_allowed_patterns = set_free(c->log_filter_allowed_patterns);
×
2065
                                c->log_filter_denied_patterns = set_free(c->log_filter_denied_patterns);
×
2066
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2067
                        } else {
2068
                                r = set_put_strdupv(&c->log_filter_allowed_patterns, allow_list);
×
2069
                                if (r < 0)
×
2070
                                        return r;
2071
                                r = set_put_strdupv(&c->log_filter_denied_patterns, deny_list);
×
2072
                                if (r < 0)
×
2073
                                        return r;
2074

2075
                                STRV_FOREACH(unit_pattern, allow_list)
×
2076
                                        unit_write_settingf(u, flags, name, "%s=%s", name, *unit_pattern);
×
2077
                                STRV_FOREACH(unit_pattern, deny_list)
×
2078
                                        unit_write_settingf(u, flags, name, "%s=~%s", name, *unit_pattern);
×
2079
                        }
2080
                }
2081

2082
                return 1;
×
2083
        }
2084

2085
        if (streq(name, "Personality"))
1,106✔
2086
                return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
×
2087

2088
        if (streq(name, "StandardInput"))
1,106✔
2089
                return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
×
2090

2091
        if (streq(name, "StandardOutput"))
1,106✔
2092
                return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
30✔
2093

2094
        if (streq(name, "StandardError"))
1,076✔
2095
                return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
30✔
2096

2097
        if (streq(name, "IgnoreSIGPIPE"))
1,046✔
2098
                return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
×
2099

2100
        if (streq(name, "TTYVHangup"))
1,046✔
2101
                return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
×
2102

2103
        if (streq(name, "TTYReset"))
1,046✔
2104
                return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
×
2105

2106
        if (streq(name, "TTYVTDisallocate"))
1,046✔
2107
                return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
×
2108

2109
        if (streq(name, "TTYRows"))
1,046✔
2110
                return bus_set_transient_unsigned(u, name, &c->tty_rows, message, flags, error);
×
2111

2112
        if (streq(name, "TTYColumns"))
1,046✔
2113
                return bus_set_transient_unsigned(u, name, &c->tty_cols, message, flags, error);
×
2114

2115
        if (streq(name, "PrivateTmp")) {
1,046✔
2116
                int v;
10✔
2117

2118
                r = sd_bus_message_read(message, "b", &v);
10✔
2119
                if (r < 0)
10✔
2120
                        return r;
10✔
2121

2122
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
10✔
2123
                        c->private_tmp = v ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_NO;
5✔
2124
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
5✔
2125
                }
2126

2127
                return 1;
10✔
2128

2129
        } else if (streq(name, "PrivateTmpEx")) {
1,036✔
2130
                const char *s;
×
2131
                PrivateTmp t;
×
2132

2133
                r = sd_bus_message_read(message, "s", &s);
×
2134
                if (r < 0)
×
2135
                        return r;
×
2136

2137
                t = private_tmp_from_string(s);
×
2138
                if (t < 0)
×
2139
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2140

2141
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2142
                        c->private_tmp = t;
×
2143
                        (void) unit_write_settingf(u, flags, name, "PrivateTmp=%s",
×
2144
                                                   private_tmp_to_string(c->private_tmp));
2145
                }
2146

2147
                return 1;
×
2148
        }
2149

2150
        if (streq(name, "PrivateUsers")) {
1,036✔
2151
                int v;
8✔
2152

2153
                r = sd_bus_message_read(message, "b", &v);
8✔
2154
                if (r < 0)
8✔
2155
                        return r;
8✔
2156

2157
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
2158
                        c->private_users = v ? PRIVATE_USERS_SELF : PRIVATE_USERS_NO;
4✔
2159
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
4✔
2160
                }
2161

2162
                return 1;
8✔
2163

2164
        } else if (streq(name, "PrivateUsersEx")) {
1,028✔
2165
                const char *s;
18✔
2166
                PrivateUsers t;
18✔
2167

2168
                r = sd_bus_message_read(message, "s", &s);
18✔
2169
                if (r < 0)
18✔
2170
                        return r;
18✔
2171

2172
                t = private_users_from_string(s);
18✔
2173
                if (t < 0)
18✔
2174
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2175

2176
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
18✔
2177
                        c->private_users = t;
9✔
2178
                        (void) unit_write_settingf(u, flags, name, "PrivateUsers=%s",
9✔
2179
                                                   private_users_to_string(c->private_users));
2180
                }
2181

2182
                return 1;
18✔
2183
        }
2184

2185
        if (streq(name, "ProtectControlGroups")) {
1,010✔
2186
                int v;
×
2187

2188
                r = sd_bus_message_read(message, "b", &v);
×
2189
                if (r < 0)
×
2190
                        return r;
×
2191

2192
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2193
                        c->protect_control_groups = v ? PROTECT_CONTROL_GROUPS_YES : PROTECT_CONTROL_GROUPS_NO;
×
2194
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
×
2195
                }
2196

2197
                return 1;
×
2198
        }
2199

2200
        if (streq(name, "ProtectControlGroupsEx")) {
1,010✔
2201
                const char *s;
2✔
2202
                ProtectControlGroups t;
2✔
2203

2204
                r = sd_bus_message_read(message, "s", &s);
2✔
2205
                if (r < 0)
2✔
2206
                        return r;
2✔
2207

2208
                t = protect_control_groups_from_string(s);
2✔
2209
                if (t < 0)
2✔
2210
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2211

2212
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2213
                        c->protect_control_groups = t;
1✔
2214
                        (void) unit_write_settingf(u, flags, name, "ProtectControlGroups=%s",
1✔
2215
                                                   protect_control_groups_to_string(c->protect_control_groups));
2216
                }
2217

2218
                return 1;
2✔
2219
        }
2220

2221
        if (streq(name, "PrivatePIDs")) {
1,008✔
2222
                const char *s;
8✔
2223
                PrivatePIDs t;
8✔
2224

2225
                r = sd_bus_message_read(message, "s", &s);
8✔
2226
                if (r < 0)
8✔
2227
                        return r;
8✔
2228

2229
                t = private_pids_from_string(s);
8✔
2230
                if (t < 0)
8✔
2231
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2232

2233
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
2234
                        c->private_pids = t;
4✔
2235
                        (void) unit_write_settingf(u, flags, name, "%s=%s",
4✔
2236
                                                   name, private_pids_to_string(c->private_pids));
2237
                }
2238

2239
                return 1;
8✔
2240
        }
2241

2242
        if (streq(name, "ProtectHostname")) {
1,000✔
2243
                int v;
4✔
2244

2245
                r = sd_bus_message_read(message, "b", &v);
4✔
2246
                if (r < 0)
4✔
2247
                        return r;
4✔
2248

2249
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2250
                        c->protect_hostname = v ? PROTECT_HOSTNAME_YES : PROTECT_HOSTNAME_NO;
2✔
2251
                        (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
2✔
2252
                }
2253

2254
                return 1;
4✔
2255

2256
        }
2257

2258
        if (streq(name, "ProtectHostnameEx")) {
996✔
2259
                const char *s, *h = NULL;
4✔
2260

2261
                r = sd_bus_message_read(message, "(ss)", &s, &h);
4✔
2262
                if (r < 0)
4✔
2263
                        return r;
4✔
2264

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

2268
                ProtectHostname t = protect_hostname_from_string(s);
4✔
2269
                if (t < 0 || (t == PROTECT_HOSTNAME_NO && !isempty(h)))
4✔
2270
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
×
2271

2272
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
2273
                        c->protect_hostname = t;
2✔
2274
                        r = free_and_strdup(&c->private_hostname, empty_to_null(h));
4✔
2275
                        if (r < 0)
2✔
2276
                                return r;
2277

2278
                        (void) unit_write_settingf(u, flags, name, "ProtectHostname=%s%s%s",
4✔
2279
                                                   protect_hostname_to_string(c->protect_hostname),
2280
                                                   c->private_hostname ? ":" : "",
2281
                                                   strempty(c->private_hostname));
2✔
2282
                }
2283

2284
                return 1;
4✔
2285
        }
2286

2287
        if (streq(name, "PrivateDevices"))
992✔
2288
                return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
4✔
2289

2290
        if (streq(name, "PrivateMounts"))
988✔
2291
                return bus_set_transient_tristate(u, name, &c->private_mounts, message, flags, error);
20✔
2292

2293
        if (streq(name, "MountAPIVFS"))
968✔
2294
                return bus_set_transient_tristate(u, name, &c->mount_apivfs, message, flags, error);
4✔
2295

2296
        if (streq(name, "BindLogSockets"))
964✔
2297
                return bus_set_transient_tristate(u, name, &c->bind_log_sockets, message, flags, error);
×
2298

2299
        if (streq(name, "PrivateNetwork"))
964✔
2300
                return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
8✔
2301

2302
        if (streq(name, "PrivateIPC"))
956✔
2303
                return bus_set_transient_bool(u, name, &c->private_ipc, message, flags, error);
4✔
2304

2305
        if (streq(name, "NoNewPrivileges"))
952✔
2306
                return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
2✔
2307

2308
        if (streq(name, "SyslogLevelPrefix"))
950✔
2309
                return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
×
2310

2311
        if (streq(name, "MemoryDenyWriteExecute"))
950✔
2312
                return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
×
2313

2314
        if (streq(name, "RestrictRealtime"))
950✔
2315
                return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
×
2316

2317
        if (streq(name, "RestrictSUIDSGID"))
950✔
2318
                return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
×
2319

2320
        if (streq(name, "DynamicUser"))
950✔
2321
                return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
2✔
2322

2323
        if (streq(name, "RemoveIPC"))
948✔
2324
                return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
×
2325

2326
        if (streq(name, "ProtectKernelTunables"))
948✔
2327
                return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
4✔
2328

2329
        if (streq(name, "ProtectKernelModules"))
944✔
2330
                return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
4✔
2331

2332
        if (streq(name, "ProtectKernelLogs"))
940✔
2333
                return bus_set_transient_bool(u, name, &c->protect_kernel_logs, message, flags, error);
2✔
2334

2335
        if (streq(name, "ProtectClock"))
938✔
2336
                return bus_set_transient_bool(u, name, &c->protect_clock, message, flags, error);
4✔
2337

2338
        if (streq(name, "CPUSchedulingResetOnFork"))
934✔
2339
                return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
×
2340

2341
        if (streq(name, "NonBlocking"))
934✔
2342
                return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
×
2343

2344
        if (streq(name, "LockPersonality"))
934✔
2345
                return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
2✔
2346

2347
        if (streq(name, "MemoryKSM"))
932✔
2348
                return bus_set_transient_tristate(u, name, &c->memory_ksm, message, flags, error);
×
2349

2350
        if (streq(name, "UtmpIdentifier"))
932✔
2351
                return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
×
2352

2353
        if (streq(name, "UtmpMode"))
932✔
2354
                return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
×
2355

2356
        if (streq(name, "PAMName"))
932✔
2357
                return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
10✔
2358

2359
        if (streq(name, "TimerSlackNSec"))
922✔
2360
                return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
×
2361

2362
        if (streq(name, "ProtectSystem"))
922✔
2363
                return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
2✔
2364

2365
        if (streq(name, "ProtectHome"))
920✔
2366
                return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
6✔
2367

2368
        if (streq(name, "KeyringMode"))
914✔
2369
                return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
×
2370

2371
        if (streq(name, "ProtectProc"))
914✔
2372
                return bus_set_transient_protect_proc(u, name, &c->protect_proc, message, flags, error);
10✔
2373

2374
        if (streq(name, "ProcSubset"))
904✔
2375
                return bus_set_transient_proc_subset(u, name, &c->proc_subset, message, flags, error);
6✔
2376

2377
        if (streq(name, "PrivateBPF"))
898✔
2378
                return bus_set_transient_private_bpf(u, name, &c->private_bpf, message, flags, error);
×
2379

2380
        if (streq(name, "BPFDelegateCommands"))
898✔
2381
                return bus_set_transient_bpf_delegate_commands(u, name, &c->bpf_delegate_commands, message, flags, error);
×
2382

2383
        if (streq(name, "BPFDelegateMaps"))
898✔
2384
                return bus_set_transient_bpf_delegate_maps(u, name, &c->bpf_delegate_maps, message, flags, error);
×
2385

2386
        if (streq(name, "BPFDelegatePrograms"))
898✔
2387
                return bus_set_transient_bpf_delegate_programs(u, name, &c->bpf_delegate_programs, message, flags, error);
×
2388

2389
        if (streq(name, "BPFDelegateAttachments"))
898✔
2390
                return bus_set_transient_bpf_delegate_attachments(u, name, &c->bpf_delegate_attachments, message, flags, error);
×
2391

2392
        if (streq(name, "RuntimeDirectoryPreserve"))
898✔
2393
                return bus_set_transient_exec_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
10✔
2394

2395
        if (streq(name, "UMask"))
888✔
2396
                return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
×
2397

2398
        if (streq(name, "RuntimeDirectoryMode"))
888✔
2399
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
×
2400

2401
        if (streq(name, "StateDirectoryAccounting"))
888✔
2402
                return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_STATE].exec_quota.quota_accounting, message, flags, error);
×
2403

2404
        if (streq(name, "CacheDirectoryAccounting"))
888✔
2405
                return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_CACHE].exec_quota.quota_accounting, message, flags, error);
×
2406

2407
        if (streq(name, "LogsDirectoryAccounting"))
888✔
2408
                return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_LOGS].exec_quota.quota_accounting, message, flags, error);
×
2409

2410
        if (streq(name, "StateDirectoryMode"))
888✔
2411
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
10✔
2412

2413
        if (streq(name, "CacheDirectoryMode"))
878✔
2414
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
20✔
2415

2416
        if (streq(name, "LogsDirectoryMode"))
858✔
2417
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
×
2418

2419
        if (streq(name, "ConfigurationDirectoryMode"))
858✔
2420
                return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
10✔
2421

2422
        if (streq(name, "SELinuxContext"))
848✔
2423
                return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
×
2424

2425
        if (streq(name, "SecureBits"))
848✔
2426
                return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
×
2427

2428
        if (streq(name, "CapabilityBoundingSet"))
848✔
2429
                return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
2✔
2430

2431
        if (streq(name, "AmbientCapabilities"))
846✔
2432
                return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
8✔
2433

2434
        if (streq(name, "RestrictNamespaces"))
838✔
2435
                return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
×
2436

2437
        if (streq(name, "DelegateNamespaces"))
838✔
2438
                return bus_set_transient_namespace_flag(u, name, &c->delegate_namespaces, message, flags, error);
18✔
2439

2440
        if (streq(name, "RestrictFileSystems")) {
820✔
2441
                int allow_list;
×
2442
                _cleanup_strv_free_ char **l = NULL;
×
2443

2444
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2445
                if (r < 0)
×
2446
                        return r;
2447

2448
                r = sd_bus_message_read(message, "b", &allow_list);
×
2449
                if (r < 0)
×
2450
                        return r;
2451

2452
                r = sd_bus_message_read_strv(message, &l);
×
2453
                if (r < 0)
×
2454
                        return r;
2455

2456
                r = sd_bus_message_exit_container(message);
×
2457
                if (r < 0)
×
2458
                        return r;
2459

2460
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2461
                        _cleanup_free_ char *joined = NULL;
×
2462
                        FilesystemParseFlags invert_flag = allow_list ? 0 : FILESYSTEM_PARSE_INVERT;
×
2463

2464
                        if (strv_isempty(l)) {
×
2465
                                c->restrict_filesystems_allow_list = false;
×
2466
                                c->restrict_filesystems = set_free(c->restrict_filesystems);
×
2467

2468
                                unit_write_setting(u, flags, name, "RestrictFileSystems=");
×
2469
                                return 1;
2470
                        }
2471

2472
                        if (!c->restrict_filesystems)
×
2473
                                c->restrict_filesystems_allow_list = allow_list;
×
2474

2475
                        STRV_FOREACH(s, l) {
×
2476
                                r = bpf_restrict_fs_parse_filesystem(
×
2477
                                              *s,
2478
                                              &c->restrict_filesystems,
2479
                                              FILESYSTEM_PARSE_LOG|
×
2480
                                              (invert_flag ? FILESYSTEM_PARSE_INVERT : 0)|
×
2481
                                              (c->restrict_filesystems_allow_list ? FILESYSTEM_PARSE_ALLOW_LIST : 0),
×
2482
                                              u->id, NULL, 0);
×
2483
                                if (r < 0)
×
2484
                                        return r;
2485
                        }
2486

2487
                        joined = strv_join(l, " ");
×
2488
                        if (!joined)
×
2489
                                return -ENOMEM;
2490

2491
                        unit_write_settingf(u, flags, name, "%s=%s%s", name, allow_list ? "" : "~", joined);
×
2492
                }
2493

2494
                return 1;
×
2495
        }
2496

2497
        if (streq(name, "MountFlags"))
820✔
2498
                return bus_set_transient_mount_propagation_flag(u, name, &c->mount_propagation_flag, message, flags, error);
2✔
2499

2500
        if (streq(name, "NetworkNamespacePath"))
818✔
2501
                return bus_set_transient_path(u, name, &c->network_namespace_path, message, flags, error);
×
2502

2503
        if (streq(name, "IPCNamespacePath"))
818✔
2504
                return bus_set_transient_path(u, name, &c->ipc_namespace_path, message, flags, error);
×
2505

2506
        if (streq(name, "SupplementaryGroups")) {
818✔
2507
                _cleanup_strv_free_ char **l = NULL;
×
2508

2509
                r = sd_bus_message_read_strv(message, &l);
×
2510
                if (r < 0)
×
2511
                        return r;
2512

2513
                STRV_FOREACH(p, l)
×
2514
                        if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN))
×
2515
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
2516
                                                        "Invalid supplementary group names");
2517

2518
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2519
                        if (strv_isempty(l)) {
×
2520
                                c->supplementary_groups = strv_free(c->supplementary_groups);
×
2521
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2522
                        } else {
2523
                                _cleanup_free_ char *joined = NULL;
×
2524

2525
                                r = strv_extend_strv(&c->supplementary_groups, l, true);
×
2526
                                if (r < 0)
×
2527
                                        return r;
2528

2529
                                joined = strv_join(c->supplementary_groups, " ");
×
2530
                                if (!joined)
×
2531
                                        return -ENOMEM;
2532

2533
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
×
2534
                        }
2535
                }
2536

2537
                return 1;
×
2538

2539
        } else if (STR_IN_SET(name, "SetCredential", "SetCredentialEncrypted")) {
818✔
2540
                bool isempty = true;
×
2541

2542
                r = sd_bus_message_enter_container(message, 'a', "(say)");
×
2543
                if (r < 0)
×
2544
                        return r;
4✔
2545

2546
                for (;;) {
×
2547
                        const char *id;
×
2548
                        const void *p;
×
2549
                        size_t sz;
×
2550

2551
                        r = sd_bus_message_enter_container(message, 'r', "say");
×
2552
                        if (r < 0)
×
2553
                                return r;
×
2554
                        if (r == 0)
×
2555
                                break;
2556

2557
                        r = sd_bus_message_read(message, "s", &id);
×
2558
                        if (r < 0)
×
2559
                                return r;
2560

2561
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2562
                        if (r < 0)
×
2563
                                return r;
2564

2565
                        r = sd_bus_message_exit_container(message);
×
2566
                        if (r < 0)
×
2567
                                return r;
2568

2569
                        if (!credential_name_valid(id))
×
2570
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2571

2572
                        isempty = false;
×
2573

2574
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2575
                                bool encrypted = endswith(name, "Encrypted");
×
2576
                                _cleanup_free_ char *a = NULL, *b = NULL;
×
2577
                                _cleanup_free_ void *copy = NULL;
×
2578

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

2583
                                a = specifier_escape(id);
×
2584
                                if (!a)
×
2585
                                        return -ENOMEM;
2586

2587
                                b = cescape_length(p, sz);
×
2588
                                if (!b)
×
2589
                                        return -ENOMEM;
2590

2591
                                r = exec_context_put_set_credential(c, id, TAKE_PTR(copy), sz, encrypted);
×
2592
                                if (r < 0)
×
2593
                                        return r;
2594

2595
                                (void) unit_write_settingf(u, flags, name, "%s=%s:%s", name, a, b);
×
2596
                        }
2597
                }
2598

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

2603
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
×
2604
                        c->set_credentials = hashmap_free(c->set_credentials);
×
2605
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2606
                }
2607

2608
                return 1;
×
2609

2610
        } else if (STR_IN_SET(name, "LoadCredential", "LoadCredentialEncrypted")) {
818✔
2611
                bool isempty = true;
2✔
2612

2613
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
2✔
2614
                if (r < 0)
2✔
2615
                        return r;
4✔
2616

2617
                for (;;) {
2✔
2618
                        const char *id, *source;
4✔
2619

2620
                        r = sd_bus_message_read(message, "(ss)", &id, &source);
4✔
2621
                        if (r < 0)
4✔
2622
                                return r;
×
2623
                        if (r == 0)
4✔
2624
                                break;
2625

2626
                        if (!credential_name_valid(id))
2✔
2627
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Credential ID is invalid: %s", id);
×
2628

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

2632
                        isempty = false;
2✔
2633

2634
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2635
                                bool encrypted = endswith(name, "Encrypted");
1✔
2636

2637
                                r = exec_context_put_load_credential(c, id, source, encrypted);
1✔
2638
                                if (r < 0)
1✔
2639
                                        return r;
2640

2641
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s:%s", name, id, source);
1✔
2642
                        }
2643
                }
2644

2645
                r = sd_bus_message_exit_container(message);
2✔
2646
                if (r < 0)
2✔
2647
                        return r;
2648

2649
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && isempty) {
2✔
2650
                        c->load_credentials = hashmap_free(c->load_credentials);
×
2651
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2652
                }
2653

2654
                return 1;
2✔
2655

2656
        } else if (STR_IN_SET(name, "ImportCredential", "ImportCredentialEx")) {
816✔
2657
                bool empty = true, ex = streq(name, "ImportCredentialEx");
2✔
2658

2659
                r = sd_bus_message_enter_container(message, 'a', ex ? "(ss)" : "s");
4✔
2660
                if (r < 0)
2✔
2661
                        return r;
2✔
2662

2663
                for (;;) {
2✔
2664
                        const char *glob, *rename = NULL;
4✔
2665

2666
                        if (ex)
4✔
2667
                                r = sd_bus_message_read(message, "(ss)", &glob, &rename);
×
2668
                        else
2669
                                r = sd_bus_message_read(message, "s", &glob);
4✔
2670
                        if (r < 0)
4✔
2671
                                return r;
×
2672
                        if (r == 0)
4✔
2673
                                break;
2674

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

2678
                        rename = empty_to_null(rename);
2✔
2679

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

2683
                        empty = false;
2✔
2684

2685
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2✔
2686
                                r = exec_context_put_import_credential(c, glob, rename);
1✔
2687
                                if (r < 0)
1✔
2688
                                        return r;
2689

2690
                                (void) unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
3✔
2691
                                                           "ImportCredential=%s%s%s",
2692
                                                           glob, rename ? ":" : "", strempty(rename));
2693
                        }
2694
                }
2695

2696
                r = sd_bus_message_exit_container(message);
2✔
2697
                if (r < 0)
2✔
2698
                        return r;
2699

2700
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
2✔
2701
                        c->import_credentials = ordered_set_free(c->import_credentials);
×
2702
                        (void) unit_write_settingf(u, flags, name, "%s=", name);
×
2703
                }
2704

2705
                return 1;
2✔
2706

2707
        } else if (streq(name, "SyslogLevel")) {
814✔
2708
                int32_t level;
×
2709

2710
                r = sd_bus_message_read(message, "i", &level);
×
2711
                if (r < 0)
×
2712
                        return r;
×
2713

2714
                if (!log_level_is_valid(level))
×
2715
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
×
2716

2717
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2718
                        c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
×
2719
                        unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
×
2720
                }
2721

2722
                return 1;
×
2723

2724
        } else if (streq(name, "SyslogFacility")) {
814✔
2725
                int32_t facility;
×
2726

2727
                r = sd_bus_message_read(message, "i", &facility);
×
2728
                if (r < 0)
×
2729
                        return r;
×
2730

2731
                if (!log_facility_unshifted_is_valid(facility))
×
2732
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
×
2733

2734
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2735
                        c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
×
2736
                        unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
×
2737
                }
2738

2739
                return 1;
×
2740

2741
        } else if (streq(name, "LogNamespace")) {
814✔
2742
                const char *n;
×
2743

2744
                r = sd_bus_message_read(message, "s", &n);
×
2745
                if (r < 0)
×
2746
                        return r;
×
2747

2748
                if (!isempty(n) && !log_namespace_name_valid(n))
×
2749
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Log namespace name not valid");
×
2750

2751
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2752

2753
                        if (isempty(n)) {
×
2754
                                c->log_namespace = mfree(c->log_namespace);
×
2755
                                unit_write_settingf(u, flags, name, "%s=", name);
×
2756
                        } else {
2757
                                r = free_and_strdup(&c->log_namespace, n);
×
2758
                                if (r < 0)
×
2759
                                        return r;
2760

2761
                                unit_write_settingf(u, flags, name, "%s=%s", name, n);
×
2762
                        }
2763
                }
2764

2765
                return 1;
×
2766

2767
        } else if (streq(name, "LogExtraFields")) {
814✔
2768
                size_t n = 0;
×
2769

2770
                r = sd_bus_message_enter_container(message, 'a', "ay");
×
2771
                if (r < 0)
×
2772
                        return r;
2773

2774
                for (;;) {
×
2775
                        _cleanup_free_ void *copy = NULL;
×
2776
                        const char *eq;
×
2777
                        const void *p;
×
2778
                        size_t sz;
×
2779

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

2787
                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
2788
                        if (r < 0)
×
2789
                                return r;
2790
                        if (r == 0)
×
2791
                                break;
2792

2793
                        if (memchr(p, 0, sz))
×
2794
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
×
2795

2796
                        eq = memchr(p, '=', sz);
×
2797
                        if (!eq)
×
2798
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
×
2799
                        if (!journal_field_valid(p, eq - (const char*) p, false))
×
2800
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
×
2801

2802
                        copy = memdup_suffix0(p, sz);
×
2803
                        if (!copy)
×
2804
                                return -ENOMEM;
2805

2806
                        if (!utf8_is_valid(copy))
×
2807
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
×
2808

2809
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2810
                                if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
×
2811
                                        return -ENOMEM;
2812

2813
                                c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
×
2814
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
×
2815
                                TAKE_PTR(copy);
2816
                        }
2817

2818
                        n++;
×
2819
                }
2820

2821
                r = sd_bus_message_exit_container(message);
×
2822
                if (r < 0)
×
2823
                        return r;
2824

2825
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
×
2826
                        exec_context_free_log_extra_fields(c);
×
2827
                        unit_write_setting(u, flags, name, "LogExtraFields=");
×
2828
                }
2829

2830
                return 1;
×
2831
        }
2832

2833
#if HAVE_SECCOMP
2834

2835
        if (streq(name, "SystemCallErrorNumber"))
814✔
2836
                return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
×
2837

2838
        if (streq(name, "SystemCallFilter")) {
814✔
2839
                int allow_list;
×
2840
                _cleanup_strv_free_ char **l = NULL;
×
2841

2842
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2843
                if (r < 0)
×
2844
                        return r;
2845

2846
                r = sd_bus_message_read(message, "b", &allow_list);
×
2847
                if (r < 0)
×
2848
                        return r;
2849

2850
                r = sd_bus_message_read_strv(message, &l);
×
2851
                if (r < 0)
×
2852
                        return r;
2853

2854
                r = sd_bus_message_exit_container(message);
×
2855
                if (r < 0)
×
2856
                        return r;
2857

2858
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2859
                        _cleanup_free_ char *joined = NULL;
×
2860
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2861

2862
                        if (strv_isempty(l)) {
×
2863
                                c->syscall_allow_list = false;
×
2864
                                c->syscall_filter = hashmap_free(c->syscall_filter);
×
2865

2866
                                unit_write_settingf(u, flags, name, "SystemCallFilter=");
×
2867
                                return 1;
2868
                        }
2869

2870
                        if (!c->syscall_filter) {
×
2871
                                c->syscall_filter = hashmap_new(NULL);
×
2872
                                if (!c->syscall_filter)
×
2873
                                        return log_oom();
×
2874

2875
                                c->syscall_allow_list = allow_list;
×
2876

2877
                                if (c->syscall_allow_list) {
×
2878
                                        r = seccomp_parse_syscall_filter("@default",
×
2879
                                                                         -1,
2880
                                                                         c->syscall_filter,
2881
                                                                         SECCOMP_PARSE_PERMISSIVE |
2882
                                                                         SECCOMP_PARSE_ALLOW_LIST,
2883
                                                                         u->id,
×
2884
                                                                         NULL, 0);
2885
                                        if (r < 0)
×
2886
                                                return r;
2887
                                }
2888
                        }
2889

2890
                        STRV_FOREACH(s, l) {
×
2891
                                _cleanup_free_ char *n = NULL;
×
2892
                                int e;
×
2893

2894
                                r = parse_syscall_and_errno(*s, &n, &e);
×
2895
                                if (r < 0)
×
2896
                                        return r;
2897

2898
                                if (allow_list && e >= 0)
×
2899
                                        return -EINVAL;
2900

2901
                                r = seccomp_parse_syscall_filter(n,
×
2902
                                                                 e,
2903
                                                                 c->syscall_filter,
2904
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2905
                                                                 invert_flag |
×
2906
                                                                 (c->syscall_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2907
                                                                 u->id,
×
2908
                                                                 NULL, 0);
2909
                                if (r < 0)
×
2910
                                        return r;
2911
                        }
2912

2913
                        joined = strv_join(l, " ");
×
2914
                        if (!joined)
×
2915
                                return -ENOMEM;
2916

2917
                        unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", allow_list ? "" : "~", joined);
×
2918
                }
2919

2920
                return 1;
×
2921

2922
        } else if (streq(name, "SystemCallLog")) {
814✔
2923
                int allow_list;
×
2924
                _cleanup_strv_free_ char **l = NULL;
×
2925

2926
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
2927
                if (r < 0)
×
2928
                        return r;
2929

2930
                r = sd_bus_message_read(message, "b", &allow_list);
×
2931
                if (r < 0)
×
2932
                        return r;
2933

2934
                r = sd_bus_message_read_strv(message, &l);
×
2935
                if (r < 0)
×
2936
                        return r;
2937

2938
                r = sd_bus_message_exit_container(message);
×
2939
                if (r < 0)
×
2940
                        return r;
2941

2942
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2943
                        _cleanup_free_ char *joined = NULL;
×
2944
                        SeccompParseFlags invert_flag = allow_list ? 0 : SECCOMP_PARSE_INVERT;
×
2945

2946
                        if (strv_isempty(l)) {
×
2947
                                c->syscall_log_allow_list = false;
×
2948
                                c->syscall_log = hashmap_free(c->syscall_log);
×
2949

2950
                                unit_write_settingf(u, flags, name, "SystemCallLog=");
×
2951
                                return 1;
2952
                        }
2953

2954
                        if (!c->syscall_log) {
×
2955
                                c->syscall_log = hashmap_new(NULL);
×
2956
                                if (!c->syscall_log)
×
2957
                                        return log_oom();
×
2958

2959
                                c->syscall_log_allow_list = allow_list;
×
2960
                        }
2961

2962
                        STRV_FOREACH(s, l) {
×
2963
                                r = seccomp_parse_syscall_filter(*s,
×
2964
                                                                 -1, /* errno not used */
2965
                                                                 c->syscall_log,
2966
                                                                 SECCOMP_PARSE_LOG | SECCOMP_PARSE_PERMISSIVE |
2967
                                                                 invert_flag |
×
2968
                                                                 (c->syscall_log_allow_list ? SECCOMP_PARSE_ALLOW_LIST : 0),
×
2969
                                                                 u->id,
×
2970
                                                                 NULL, 0);
2971
                                if (r < 0)
×
2972
                                        return r;
2973
                        }
2974

2975
                        joined = strv_join(l, " ");
×
2976
                        if (!joined)
×
2977
                                return -ENOMEM;
2978

2979
                        unit_write_settingf(u, flags, name, "SystemCallLog=%s%s", allow_list ? "" : "~", joined);
×
2980
                }
2981

2982
                return 1;
×
2983

2984
        } else if (streq(name, "SystemCallArchitectures")) {
814✔
2985
                _cleanup_strv_free_ char **l = NULL;
×
2986

2987
                r = sd_bus_message_read_strv(message, &l);
×
2988
                if (r < 0)
×
2989
                        return r;
2990

2991
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
2992
                        _cleanup_free_ char *joined = NULL;
×
2993

2994
                        if (strv_isempty(l))
×
2995
                                c->syscall_archs = set_free(c->syscall_archs);
×
2996
                        else {
2997
                                r = parse_syscall_archs(l, &c->syscall_archs);
×
2998
                                if (r < 0)
×
2999
                                        return r;
3000
                        }
3001

3002
                        joined = strv_join(l, " ");
×
3003
                        if (!joined)
×
3004
                                return -ENOMEM;
3005

3006
                        unit_write_settingf(u, flags, name, "%s=%s", name, joined);
×
3007
                }
3008

3009
                return 1;
×
3010

3011
        } else if (streq(name, "RestrictAddressFamilies")) {
814✔
3012
                _cleanup_strv_free_ char **l = NULL;
×
3013
                int allow_list;
×
3014

3015
                r = sd_bus_message_enter_container(message, 'r', "bas");
×
3016
                if (r < 0)
×
3017
                        return r;
3018

3019
                r = sd_bus_message_read(message, "b", &allow_list);
×
3020
                if (r < 0)
×
3021
                        return r;
3022

3023
                r = sd_bus_message_read_strv(message, &l);
×
3024
                if (r < 0)
×
3025
                        return r;
3026

3027
                r = sd_bus_message_exit_container(message);
×
3028
                if (r < 0)
×
3029
                        return r;
3030

3031
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3032
                        _cleanup_free_ char *joined = NULL;
×
3033

3034
                        if (strv_isempty(l)) {
×
3035
                                c->address_families_allow_list = allow_list;
×
3036
                                c->address_families = set_free(c->address_families);
×
3037

3038
                                unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s",
×
3039
                                                    allow_list ? "none" : "");
×
3040
                                return 1;
3041
                        }
3042

3043
                        if (!c->address_families) {
×
3044
                                c->address_families = set_new(NULL);
×
3045
                                if (!c->address_families)
×
3046
                                        return log_oom();
×
3047

3048
                                c->address_families_allow_list = allow_list;
×
3049
                        }
3050

3051
                        STRV_FOREACH(s, l) {
×
3052
                                int af;
×
3053

3054
                                af = af_from_name(*s);
×
3055
                                if (af < 0)
×
3056
                                        return af;
3057

3058
                                if (allow_list == c->address_families_allow_list) {
×
3059
                                        r = set_put(c->address_families, INT_TO_PTR(af));
×
3060
                                        if (r < 0)
×
3061
                                                return r;
3062
                                } else
3063
                                        set_remove(c->address_families, INT_TO_PTR(af));
×
3064
                        }
3065

3066
                        joined = strv_join(l, " ");
×
3067
                        if (!joined)
×
3068
                                return -ENOMEM;
3069

3070
                        unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", allow_list ? "" : "~", joined);
×
3071
                }
3072

3073
                return 1;
×
3074
        }
3075
#endif
3076
        if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
814✔
3077
                _cleanup_(cpu_set_done) CPUSet set = {};
×
3078
                const void *a;
×
3079
                size_t n;
×
3080

3081
                r = sd_bus_message_read_array(message, 'y', &a, &n);
×
3082
                if (r < 0)
×
3083
                        return r;
3084

3085
                r = cpu_set_from_dbus(a, n, &set);
×
3086
                if (r < 0)
×
3087
                        return r;
3088

3089
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3090
                        CPUSet *cpuset = streq(name, "CPUAffinity") ? &c->cpu_set : &c->numa_policy.nodes;
×
3091

3092
                        if (n == 0) {
×
3093
                                cpu_set_done(cpuset);
×
3094
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3095
                        } else {
3096
                                _cleanup_free_ char *str = NULL;
×
3097

3098
                                str = cpu_set_to_string(&set);
×
3099
                                if (!str)
×
3100
                                        return -ENOMEM;
3101

3102
                                /* We forego any optimizations here, and always create the structure using
3103
                                 * cpu_set_add_set(), because we don't want to care if the existing size we
3104
                                 * got over dbus is appropriate. */
3105
                                r = cpu_set_add_set(cpuset, &set);
×
3106
                                if (r < 0)
×
3107
                                        return r;
3108

3109
                                unit_write_settingf(u, flags, name, "%s=%s", name, str);
×
3110
                        }
3111
                }
3112

3113
                return 1;
×
3114

3115
        } else if (streq(name, "CPUAffinityFromNUMA")) {
814✔
3116
                int q;
×
3117

3118
                r = sd_bus_message_read_basic(message, 'b', &q);
×
3119
                if (r < 0)
×
3120
                        return r;
×
3121

3122
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3123
                        c->cpu_affinity_from_numa = q;
×
3124
                        unit_write_settingf(u, flags, name, "%s=%s", "CPUAffinity", "numa");
×
3125
                }
3126

3127
                return 1;
×
3128

3129
        } else if (streq(name, "NUMAPolicy")) {
814✔
3130
                int32_t type;
×
3131

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

3136
                if (!mpol_is_valid(type))
×
3137
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
×
3138

3139
                if (!UNIT_WRITE_FLAGS_NOOP(flags))
×
3140
                        c->numa_policy.type = type;
×
3141

3142
                return 1;
×
3143

3144
        } else if (streq(name, "Nice")) {
814✔
3145
                int32_t q;
×
3146

3147
                r = sd_bus_message_read(message, "i", &q);
×
3148
                if (r < 0)
×
3149
                        return r;
×
3150

3151
                if (!nice_is_valid(q))
×
3152
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
×
3153

3154
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3155
                        c->nice = q;
×
3156
                        c->nice_set = true;
×
3157

3158
                        unit_write_settingf(u, flags, name, "Nice=%i", q);
×
3159
                }
3160

3161
                return 1;
×
3162

3163
        } else if (streq(name, "CPUSchedulingPolicy")) {
814✔
3164
                int32_t q;
×
3165

3166
                r = sd_bus_message_read(message, "i", &q);
×
3167
                if (r < 0)
×
3168
                        return r;
×
3169

3170
                if (!sched_policy_is_valid(q))
×
3171
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
×
3172

3173
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3174
                        _cleanup_free_ char *s = NULL;
×
3175

3176
                        r = sched_policy_to_string_alloc(q, &s);
×
3177
                        if (r < 0)
×
3178
                                return r;
×
3179

3180
                        c->cpu_sched_policy = q;
×
3181
                        c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
×
3182
                        c->cpu_sched_set = true;
×
3183

3184
                        unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
×
3185
                }
3186

3187
                return 1;
×
3188

3189
        } else if (streq(name, "CPUSchedulingPriority")) {
814✔
3190
                int32_t p;
×
3191

3192
                r = sd_bus_message_read(message, "i", &p);
×
3193
                if (r < 0)
×
3194
                        return r;
×
3195

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

3201
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3202
                        c->cpu_sched_priority = p;
×
3203
                        c->cpu_sched_set = true;
×
3204

3205
                        unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
×
3206
                }
3207

3208
                return 1;
×
3209

3210
        } else if (streq(name, "IOSchedulingClass")) {
814✔
3211
                int32_t q;
×
3212

3213
                r = sd_bus_message_read(message, "i", &q);
×
3214
                if (r < 0)
×
3215
                        return r;
×
3216

3217
                if (!ioprio_class_is_valid(q))
×
3218
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
×
3219

3220
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3221
                        _cleanup_free_ char *s = NULL;
×
3222

3223
                        r = ioprio_class_to_string_alloc(q, &s);
×
3224
                        if (r < 0)
×
3225
                                return r;
×
3226

3227
                        c->ioprio = ioprio_normalize(ioprio_prio_value(q, ioprio_prio_data(c->ioprio)));
×
3228
                        c->ioprio_is_set = true;
×
3229

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

3233
                return 1;
×
3234

3235
        } else if (streq(name, "IOSchedulingPriority")) {
814✔
3236
                int32_t p;
×
3237

3238
                r = sd_bus_message_read(message, "i", &p);
×
3239
                if (r < 0)
×
3240
                        return r;
×
3241

3242
                if (!ioprio_priority_is_valid(p))
×
3243
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
×
3244

3245
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3246
                        c->ioprio = ioprio_normalize(ioprio_prio_value(ioprio_prio_class(c->ioprio), p));
×
3247
                        c->ioprio_is_set = true;
×
3248

3249
                        unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
×
3250
                }
3251

3252
                return 1;
×
3253

3254
        } else if (streq(name, "WorkingDirectory")) {
814✔
3255
                _cleanup_free_ char *simplified = NULL;
×
3256
                bool missing_ok = false, is_home = false;
×
3257
                const char *s;
×
3258

3259
                r = sd_bus_message_read(message, "s", &s);
×
3260
                if (r < 0)
×
3261
                        return r;
3262

3263
                if (!isempty(s)) {
×
3264
                        if (s[0] == '-') {
×
3265
                                missing_ok = true;
×
3266
                                s++;
×
3267
                        }
3268

3269
                        if (streq(s, "~"))
×
3270
                                is_home = true;
3271
                        else {
3272
                                if (!path_is_absolute(s))
×
3273
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3274
                                                                "WorkingDirectory= expects an absolute path or '~'");
3275

3276
                                r = path_simplify_alloc(s, &simplified);
×
3277
                                if (r < 0)
×
3278
                                        return r;
3279

3280
                                if (!path_is_normalized(simplified))
×
3281
                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
3282
                                                                "WorkingDirectory= expects a normalized path or '~'");
3283
                        }
3284
                }
3285

3286
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3287
                        free_and_replace(c->working_directory, simplified);
×
3288
                        c->working_directory_home = is_home;
×
3289
                        c->working_directory_missing_ok = missing_ok;
×
3290

3291
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
×
3292
                                            "WorkingDirectory=%s%s",
3293
                                            c->working_directory_missing_ok ? "-" : "",
×
3294
                                            c->working_directory_home ? "~" : strempty(c->working_directory));
×
3295
                }
3296

3297
                return 1;
×
3298

3299
        } else if (STR_IN_SET(name,
814✔
3300
                              "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
3301
                const char *s;
×
3302

3303
                r = sd_bus_message_read(message, "s", &s);
×
3304
                if (r < 0)
×
3305
                        return r;
×
3306

3307
                if (!isempty(s) && !fdname_is_valid(s))
×
3308
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
×
3309

3310
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3311

3312
                        if (streq(name, "StandardInputFileDescriptorName")) {
×
3313
                                r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s));
×
3314
                                if (r < 0)
×
3315
                                        return r;
3316

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

3320
                        } else if (streq(name, "StandardOutputFileDescriptorName")) {
×
3321
                                r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s));
×
3322
                                if (r < 0)
×
3323
                                        return r;
3324

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

3328
                        } else {
3329
                                assert(streq(name, "StandardErrorFileDescriptorName"));
×
3330

3331
                                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s));
×
3332
                                if (r < 0)
×
3333
                                        return r;
3334

3335
                                c->std_error = EXEC_OUTPUT_NAMED_FD;
×
3336
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
×
3337
                        }
3338
                }
3339

3340
                return 1;
×
3341

3342
        } else if (STR_IN_SET(name,
814✔
3343
                              "StandardInputFile",
3344
                              "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate",
3345
                              "StandardErrorFile", "StandardErrorFileToAppend", "StandardErrorFileToTruncate")) {
3346
                const char *s;
×
3347

3348
                r = sd_bus_message_read(message, "s", &s);
×
3349
                if (r < 0)
×
3350
                        return r;
×
3351

3352
                if (!isempty(s)) {
×
3353
                        if (!path_is_absolute(s))
×
3354
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
×
3355
                        if (!path_is_normalized(s))
×
3356
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
×
3357
                }
3358

3359
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3360

3361
                        if (streq(name, "StandardInputFile")) {
×
3362
                                r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s));
×
3363
                                if (r < 0)
×
3364
                                        return r;
3365

3366
                                c->std_input = EXEC_INPUT_FILE;
×
3367
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
×
3368

3369
                        } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend", "StandardOutputFileToTruncate")) {
×
3370
                                r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
×
3371
                                if (r < 0)
×
3372
                                        return r;
×
3373

3374
                                if (streq(name, "StandardOutputFile")) {
×
3375
                                        c->std_output = EXEC_OUTPUT_FILE;
×
3376
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
×
3377
                                } else if (streq(name, "StandardOutputFileToAppend")) {
×
3378
                                        c->std_output = EXEC_OUTPUT_FILE_APPEND;
×
3379
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s);
×
3380
                                } else {
3381
                                        assert(streq(name, "StandardOutputFileToTruncate"));
×
3382
                                        c->std_output = EXEC_OUTPUT_FILE_TRUNCATE;
×
3383
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=truncate:%s", s);
×
3384
                                }
3385
                        } else {
3386
                                assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend", "StandardErrorFileToTruncate"));
×
3387

3388
                                r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
×
3389
                                if (r < 0)
×
3390
                                        return r;
3391

3392
                                if (streq(name, "StandardErrorFile")) {
×
3393
                                        c->std_error = EXEC_OUTPUT_FILE;
×
3394
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
×
3395
                                } else if (streq(name, "StandardErrorFileToAppend")) {
×
3396
                                        c->std_error = EXEC_OUTPUT_FILE_APPEND;
×
3397
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
×
3398
                                } else {
3399
                                        assert(streq(name, "StandardErrorFileToTruncate"));
×
3400
                                        c->std_error = EXEC_OUTPUT_FILE_TRUNCATE;
×
3401
                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=truncate:%s", s);
×
3402
                                }
3403
                        }
3404
                }
3405

3406
                return 1;
×
3407

3408
        } else if (streq(name, "StandardInputData")) {
814✔
3409
                const void *p;
×
3410
                size_t sz;
×
3411

3412
                r = sd_bus_message_read_array(message, 'y', &p, &sz);
×
3413
                if (r < 0)
×
3414
                        return r;
×
3415

3416
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3417
                        _cleanup_free_ char *encoded = NULL;
×
3418

3419
                        if (sz == 0) {
×
3420
                                c->stdin_data = mfree(c->stdin_data);
×
3421
                                c->stdin_data_size = 0;
×
3422

3423
                                unit_write_settingf(u, flags, name, "StandardInputData=");
×
3424
                        } else {
3425
                                void *q;
×
3426
                                ssize_t n;
×
3427

3428
                                if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
×
3429
                                    c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
3430
                                        return -E2BIG;
3431

3432
                                n = base64mem(p, sz, &encoded);
×
3433
                                if (n < 0)
×
3434
                                        return (int) n;
×
3435

3436
                                q = realloc(c->stdin_data, c->stdin_data_size + sz);
×
3437
                                if (!q)
×
3438
                                        return -ENOMEM;
3439

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

3442
                                c->stdin_data = q;
×
3443
                                c->stdin_data_size += sz;
×
3444

3445
                                unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
×
3446
                        }
3447
                }
3448

3449
                return 1;
×
3450

3451
        } else if (streq(name, "Environment")) {
814✔
3452

3453
                _cleanup_strv_free_ char **l = NULL;
16✔
3454

3455
                r = sd_bus_message_read_strv(message, &l);
16✔
3456
                if (r < 0)
16✔
3457
                        return r;
3458

3459
                if (!strv_env_is_valid(l))
16✔
3460
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
×
3461

3462
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
16✔
3463
                        if (strv_isempty(l)) {
8✔
3464
                                c->environment = strv_free(c->environment);
×
3465
                                unit_write_setting(u, flags, name, "Environment=");
×
3466
                        } else {
3467
                                _cleanup_free_ char *joined = NULL;
8✔
3468
                                char **e;
8✔
3469

3470
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
8✔
3471
                                if (!joined)
8✔
3472
                                        return -ENOMEM;
3473

3474
                                e = strv_env_merge(c->environment, l);
8✔
3475
                                if (!e)
8✔
3476
                                        return -ENOMEM;
3477

3478
                                strv_free_and_replace(c->environment, e);
8✔
3479
                                unit_write_settingf(u, flags, name, "Environment=%s", joined);
8✔
3480
                        }
3481
                }
3482

3483
                return 1;
16✔
3484

3485
        } else if (streq(name, "UnsetEnvironment")) {
798✔
3486

3487
                _cleanup_strv_free_ char **l = NULL;
×
3488

3489
                r = sd_bus_message_read_strv(message, &l);
×
3490
                if (r < 0)
×
3491
                        return r;
3492

3493
                if (!strv_env_name_or_assignment_is_valid(l))
×
3494
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
×
3495

3496
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3497
                        if (strv_isempty(l)) {
×
3498
                                c->unset_environment = strv_free(c->unset_environment);
×
3499
                                unit_write_setting(u, flags, name, "UnsetEnvironment=");
×
3500
                        } else {
3501
                                _cleanup_free_ char *joined = NULL;
×
3502
                                char **e;
×
3503

3504
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
×
3505
                                if (!joined)
×
3506
                                        return -ENOMEM;
3507

3508
                                e = strv_env_merge(c->unset_environment, l);
×
3509
                                if (!e)
×
3510
                                        return -ENOMEM;
3511

3512
                                strv_free_and_replace(c->unset_environment, e);
×
3513
                                unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
×
3514
                        }
3515
                }
3516

3517
                return 1;
×
3518

3519
        } else if (streq(name, "OOMScoreAdjust")) {
798✔
3520
                int oa;
×
3521

3522
                r = sd_bus_message_read(message, "i", &oa);
×
3523
                if (r < 0)
×
3524
                        return r;
×
3525

3526
                if (!oom_score_adjust_is_valid(oa))
×
3527
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
×
3528

3529
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3530
                        c->oom_score_adjust = oa;
×
3531
                        c->oom_score_adjust_set = true;
×
3532
                        unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
×
3533
                }
3534

3535
                return 1;
×
3536

3537
        } else if (streq(name, "CoredumpFilter")) {
798✔
3538
                uint64_t f;
×
3539

3540
                r = sd_bus_message_read(message, "t", &f);
×
3541
                if (r < 0)
×
3542
                        return r;
×
3543

3544
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3545
                        c->coredump_filter = f;
×
3546
                        c->coredump_filter_set = true;
×
3547
                        unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f);
×
3548
                }
3549

3550
                return 1;
×
3551

3552
        } else if (streq(name, "EnvironmentFiles")) {
798✔
3553
                _cleanup_(memstream_done) MemStream m = {};
×
3554
                _cleanup_free_ char *joined = NULL;
4✔
3555
                _cleanup_strv_free_ char **l = NULL;
4✔
3556
                FILE *f;
4✔
3557

3558
                r = sd_bus_message_enter_container(message, 'a', "(sb)");
4✔
3559
                if (r < 0)
4✔
3560
                        return r;
3561

3562
                f = memstream_init(&m);
4✔
3563
                if (!f)
4✔
3564
                        return -ENOMEM;
3565

3566
                fputs("EnvironmentFile=\n", f);
4✔
3567

3568
                STRV_FOREACH(i, c->environment_files) {
4✔
3569
                        _cleanup_free_ char *q = NULL;
×
3570

3571
                        q = specifier_escape(*i);
×
3572
                        if (!q)
×
3573
                                return -ENOMEM;
×
3574

3575
                        fprintf(f, "EnvironmentFile=%s\n", q);
×
3576
                }
3577

3578
                while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
8✔
3579
                        const char *path;
4✔
3580
                        int b;
4✔
3581

3582
                        r = sd_bus_message_read(message, "sb", &path, &b);
4✔
3583
                        if (r < 0)
4✔
3584
                                return r;
×
3585

3586
                        r = sd_bus_message_exit_container(message);
4✔
3587
                        if (r < 0)
4✔
3588
                                return r;
3589

3590
                        if (!path_is_absolute(path))
4✔
3591
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
×
3592

3593
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3594
                                _cleanup_free_ char *q = NULL, *buf = NULL;
2✔
3595

3596
                                buf = strjoin(b ? "-" : "", path);
3✔
3597
                                if (!buf)
2✔
3598
                                        return -ENOMEM;
3599

3600
                                q = specifier_escape(buf);
2✔
3601
                                if (!q)
2✔
3602
                                        return -ENOMEM;
3603

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

3606
                                r = strv_consume(&l, TAKE_PTR(buf));
2✔
3607
                                if (r < 0)
2✔
3608
                                        return r;
3609
                        }
3610
                }
3611
                if (r < 0)
4✔
3612
                        return r;
3613

3614
                r = sd_bus_message_exit_container(message);
4✔
3615
                if (r < 0)
4✔
3616
                        return r;
3617

3618
                r = memstream_finalize(&m, &joined, NULL);
4✔
3619
                if (r < 0)
4✔
3620
                        return r;
3621

3622
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
4✔
3623
                        if (strv_isempty(l)) {
2✔
3624
                                c->environment_files = strv_free(c->environment_files);
×
3625
                                unit_write_setting(u, flags, name, "EnvironmentFile=");
×
3626
                        } else {
3627
                                r = strv_extend_strv(&c->environment_files, l, true);
2✔
3628
                                if (r < 0)
2✔
3629
                                        return r;
3630

3631
                                unit_write_setting(u, flags, name, joined);
2✔
3632
                        }
3633
                }
3634

3635
                return 1;
4✔
3636

3637
        } else if (streq(name, "PassEnvironment")) {
794✔
3638

3639
                _cleanup_strv_free_ char **l = NULL;
×
3640

3641
                r = sd_bus_message_read_strv(message, &l);
×
3642
                if (r < 0)
×
3643
                        return r;
3644

3645
                if (!strv_env_name_is_valid(l))
×
3646
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
×
3647

3648
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3649
                        if (strv_isempty(l)) {
×
3650
                                c->pass_environment = strv_free(c->pass_environment);
×
3651
                                unit_write_setting(u, flags, name, "PassEnvironment=");
×
3652
                        } else {
3653
                                _cleanup_free_ char *joined = NULL;
×
3654

3655
                                r = strv_extend_strv(&c->pass_environment, l, true);
×
3656
                                if (r < 0)
×
3657
                                        return r;
3658

3659
                                /* We write just the new settings out to file, with unresolved specifiers. */
3660
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
×
3661
                                if (!joined)
×
3662
                                        return -ENOMEM;
3663

3664
                                unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
×
3665
                        }
3666
                }
3667

3668
                return 1;
×
3669

3670
        } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
794✔
3671
                              "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths", "ExecPaths", "NoExecPaths",
3672
                              "ExtensionDirectories")) {
3673
                _cleanup_strv_free_ char **l = NULL;
14✔
3674
                char ***dirs;
14✔
3675

3676
                r = sd_bus_message_read_strv(message, &l);
14✔
3677
                if (r < 0)
14✔
3678
                        return r;
3679

3680
                STRV_FOREACH(p, l) {
32✔
3681
                        char *i = *p;
18✔
3682
                        size_t offset;
18✔
3683

3684
                        offset = i[0] == '-';
18✔
3685
                        offset += i[offset] == '+';
18✔
3686
                        if (!path_is_absolute(i + offset))
18✔
3687
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3688

3689
                        path_simplify(i + offset);
18✔
3690
                }
3691

3692
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
3693
                        if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
7✔
3694
                                dirs = &c->read_write_paths;
1✔
3695
                        else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
6✔
3696
                                dirs = &c->read_only_paths;
2✔
3697
                        else if (streq(name, "ExecPaths"))
4✔
3698
                                dirs = &c->exec_paths;
1✔
3699
                        else if (streq(name, "NoExecPaths"))
3✔
3700
                                dirs = &c->no_exec_paths;
1✔
3701
                        else if (streq(name, "ExtensionDirectories"))
2✔
3702
                                dirs = &c->extension_directories;
1✔
3703
                        else /* "InaccessiblePaths" */
3704
                                dirs = &c->inaccessible_paths;
1✔
3705

3706
                        if (strv_isempty(l)) {
7✔
3707
                                *dirs = strv_free(*dirs);
×
3708
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3709
                        } else {
3710
                                _cleanup_free_ char *joined = NULL;
7✔
3711

3712
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
7✔
3713
                                if (!joined)
7✔
3714
                                        return -ENOMEM;
3715

3716
                                r = strv_extend_strv(dirs, l, true);
7✔
3717
                                if (r < 0)
7✔
3718
                                        return r;
3719

3720
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
7✔
3721
                        }
3722
                }
3723

3724
                return 1;
14✔
3725

3726
        } else if (streq(name, "ExecSearchPath")) {
780✔
3727
                _cleanup_strv_free_ char **l = NULL;
×
3728

3729
                r = sd_bus_message_read_strv(message, &l);
×
3730
                if (r < 0)
×
3731
                        return r;
3732

3733
                STRV_FOREACH(p, l)
×
3734
                        if (!path_is_absolute(*p) || !path_is_normalized(*p) || strchr(*p, ':'))
×
3735
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
×
3736

3737
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3738
                        if (strv_isempty(l)) {
×
3739
                                c->exec_search_path = strv_free(c->exec_search_path);
×
3740
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=");
×
3741
                        } else {
3742
                                _cleanup_free_ char *joined = NULL;
×
3743
                                r = strv_extend_strv(&c->exec_search_path, l, true);
×
3744
                                if (r < 0)
×
3745
                                        return r;
3746
                                joined = strv_join(c->exec_search_path, ":");
×
3747
                                if (!joined)
×
3748
                                        return log_oom();
×
3749
                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ExecSearchPath=%s", joined);
×
3750
                        }
3751
                }
3752

3753
                return 1;
×
3754

3755
        } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
780✔
3756
                _cleanup_strv_free_ char **l = NULL;
114✔
3757

3758
                r = sd_bus_message_read_strv(message, &l);
114✔
3759
                if (r < 0)
114✔
3760
                        return r;
3761

3762
                STRV_FOREACH(p, l) {
288✔
3763
                        if (!path_is_normalized(*p))
174✔
3764
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
×
3765

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

3769
                        if (path_startswith(*p, "private"))
174✔
3770
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
×
3771
                }
3772

3773
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
114✔
3774
                        ExecDirectoryType i;
57✔
3775
                        ExecDirectory *d;
57✔
3776

3777
                        assert_se((i = exec_directory_type_from_string(name)) >= 0);
57✔
3778
                        d = c->directories + i;
57✔
3779

3780
                        if (strv_isempty(l)) {
57✔
3781
                                exec_directory_done(d);
×
3782
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3783
                        } else {
3784
                                _cleanup_free_ char *joined = NULL;
57✔
3785

3786
                                STRV_FOREACH(source, l) {
144✔
3787
                                        r = exec_directory_add(d, *source, /* symlink= */ NULL, /* flags= */ 0);
87✔
3788
                                        if (r < 0)
87✔
3789
                                                return log_oom();
×
3790
                                }
3791
                                exec_directory_sort(d);
57✔
3792

3793
                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
57✔
3794
                                if (!joined)
57✔
3795
                                        return -ENOMEM;
3796

3797
                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
57✔
3798
                        }
3799
                }
3800

3801
                return 1;
114✔
3802

3803
        } else if (STR_IN_SET(name, "StateDirectoryQuota", "CacheDirectoryQuota", "LogsDirectoryQuota")) {
666✔
3804
                uint64_t quota_absolute = UINT64_MAX;
×
3805
                uint32_t quota_scale = UINT32_MAX;
×
3806
                const char *enforce_flag;
×
3807
                int quota_enforce;
×
3808

3809
                r = sd_bus_message_read(message, "(tus)", &quota_absolute, &quota_scale, &enforce_flag);
×
3810
                if (r < 0)
×
3811
                        return r;
×
3812

3813
                quota_enforce = parse_boolean(enforce_flag);
×
3814
                if (quota_enforce < 0)
×
3815
                        return quota_enforce;
3816

3817
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3818
                        ExecDirectoryType dt;
×
3819
                        if (streq(name, "StateDirectoryQuota"))
×
3820
                                dt = EXEC_DIRECTORY_STATE;
3821
                        else if (streq(name, "CacheDirectoryQuota"))
×
3822
                                dt = EXEC_DIRECTORY_CACHE;
3823
                        else if (streq(name, "LogsDirectoryQuota"))
×
3824
                                dt = EXEC_DIRECTORY_LOGS;
3825
                        else
3826
                                assert_not_reached();
×
3827

3828
                        if (quota_enforce) {
×
3829
                                c->directories[dt].exec_quota.quota_absolute = quota_absolute;
×
3830
                                c->directories[dt].exec_quota.quota_scale = quota_scale;
×
3831

3832
                                if (quota_absolute != UINT64_MAX)
×
3833
                                        unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, quota_absolute);
×
3834
                                else
3835
                                        unit_write_settingf(u, flags, name, "%s=%d%%", name, UINT32_SCALE_TO_PERCENT(quota_scale));
×
3836
                        } else
3837
                                unit_write_settingf(u, flags, name, "%s=", name);
×
3838

3839
                        c->directories[dt].exec_quota.quota_enforce = quota_enforce;
×
3840
                }
3841

3842
                return 1;
×
3843

3844
        } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
666✔
3845
                int ignore;
×
3846
                const char *s;
×
3847

3848
                r = sd_bus_message_read(message, "(bs)", &ignore, &s);
×
3849
                if (r < 0)
×
3850
                        return r;
×
3851

3852
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
3853
                        char **p;
×
3854
                        bool *b;
×
3855

3856
                        if (streq(name, "AppArmorProfile")) {
×
3857
                                p = &c->apparmor_profile;
×
3858
                                b = &c->apparmor_profile_ignore;
×
3859
                        } else { /* "SmackProcessLabel" */
3860
                                p = &c->smack_process_label;
×
3861
                                b = &c->smack_process_label_ignore;
×
3862
                        }
3863

3864
                        if (isempty(s)) {
×
3865
                                *p = mfree(*p);
×
3866
                                *b = false;
×
3867
                        } else {
3868
                                if (free_and_strdup(p, s) < 0)
×
3869
                                        return -ENOMEM;
3870
                                *b = ignore;
×
3871
                        }
3872

3873
                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
×
3874
                }
3875

3876
                return 1;
×
3877

3878
        } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
666✔
3879
                char *source, *destination;
14✔
3880
                int ignore_enoent;
14✔
3881
                uint64_t mount_flags;
14✔
3882
                bool empty = true;
14✔
3883

3884
                r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
14✔
3885
                if (r < 0)
14✔
3886
                        return r;
14✔
3887

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

3890
                        if (!path_is_absolute(source))
30✔
3891
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
3892
                        if (!path_is_absolute(destination))
30✔
3893
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
3894
                        if (!IN_SET(mount_flags, 0, MS_REC))
30✔
3895
                                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
×
3896

3897
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
30✔
3898
                                r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
30✔
3899
                                                   &(BindMount) {
15✔
3900
                                                           .source = source,
3901
                                                           .destination = destination,
3902
                                                           .read_only = !!strstr(name, "ReadOnly"),
15✔
3903
                                                           .recursive = !!(mount_flags & MS_REC),
15✔
3904
                                                           .ignore_enoent = ignore_enoent,
15✔
3905
                                                   });
3906
                                if (r < 0)
15✔
3907
                                        return r;
×
3908

3909
                                unit_write_settingf(
45✔
3910
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
15✔
3911
                                                "%s=%s%s:%s:%s",
3912
                                                name,
3913
                                                ignore_enoent ? "-" : "",
15✔
3914
                                                source,
3915
                                                destination,
3916
                                                (mount_flags & MS_REC) ? "rbind" : "norbind");
15✔
3917
                        }
3918

3919
                        empty = false;
3920
                }
3921
                if (r < 0)
14✔
3922
                        return r;
3923

3924
                r = sd_bus_message_exit_container(message);
14✔
3925
                if (r < 0)
14✔
3926
                        return r;
3927

3928
                if (empty) {
14✔
3929
                        bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
×
3930
                        c->bind_mounts = NULL;
×
3931
                        c->n_bind_mounts = 0;
×
3932

3933
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3934
                }
3935

3936
                return 1;
14✔
3937

3938
        } else if (streq(name, "TemporaryFileSystem")) {
652✔
3939
                const char *path, *options;
8✔
3940
                bool empty = true;
8✔
3941

3942
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
8✔
3943
                if (r < 0)
8✔
3944
                        return r;
8✔
3945

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

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

3951
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
8✔
3952
                                r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
4✔
3953
                                if (r < 0)
4✔
3954
                                        return r;
3955

3956
                                unit_write_settingf(
4✔
3957
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
4✔
3958
                                                "%s=%s:%s",
3959
                                                name,
3960
                                                path,
3961
                                                options);
3962
                        }
3963

3964
                        empty = false;
3965
                }
3966
                if (r < 0)
8✔
3967
                        return r;
3968

3969
                r = sd_bus_message_exit_container(message);
8✔
3970
                if (r < 0)
8✔
3971
                        return r;
3972

3973
                if (empty) {
8✔
3974
                        temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
×
3975
                        c->temporary_filesystems = NULL;
×
3976
                        c->n_temporary_filesystems = 0;
×
3977

3978
                        unit_write_settingf(u, flags, name, "%s=", name);
×
3979
                }
3980

3981
                return 1;
8✔
3982

3983
        } else if ((suffix = startswith(name, "Limit"))) {
644✔
3984
                const char *soft = NULL;
88✔
3985
                int ri;
88✔
3986

3987
                ri = rlimit_from_string(suffix);
88✔
3988
                if (ri < 0) {
88✔
3989
                        soft = endswith(suffix, "Soft");
44✔
3990
                        if (soft) {
44✔
3991
                                const char *n;
44✔
3992

3993
                                n = strndupa_safe(suffix, soft - suffix);
44✔
3994
                                ri = rlimit_from_string(n);
44✔
3995
                                if (ri >= 0)
44✔
3996
                                        name = strjoina("Limit", n);
220✔
3997
                        }
3998
                }
3999

4000
                if (ri >= 0) {
44✔
4001
                        uint64_t rl;
88✔
4002
                        rlim_t x;
88✔
4003

4004
                        r = sd_bus_message_read(message, "t", &rl);
88✔
4005
                        if (r < 0)
88✔
4006
                                return r;
88✔
4007

4008
                        if (rl == UINT64_MAX)
88✔
4009
                                x = RLIM_INFINITY;
4010
                        else {
4011
                                x = (rlim_t) rl;
72✔
4012

4013
                                if ((uint64_t) x != rl)
72✔
4014
                                        return -ERANGE;
4015
                        }
4016

4017
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
88✔
4018
                                _cleanup_free_ char *f = NULL;
44✔
4019
                                struct rlimit nl;
44✔
4020

4021
                                if (c->rlimit[ri]) {
44✔
4022
                                        nl = *c->rlimit[ri];
27✔
4023

4024
                                        if (soft)
27✔
4025
                                                nl.rlim_cur = x;
22✔
4026
                                        else
4027
                                                nl.rlim_max = x;
5✔
4028
                                } else
4029
                                        /* When the resource limit is not initialized yet, then assign the value to both fields */
4030
                                        nl = (struct rlimit) {
17✔
4031
                                                .rlim_cur = x,
4032
                                                .rlim_max = x,
4033
                                        };
4034

4035
                                r = rlimit_format(&nl, &f);
44✔
4036
                                if (r < 0)
44✔
4037
                                        return r;
4038

4039
                                if (c->rlimit[ri])
44✔
4040
                                        *c->rlimit[ri] = nl;
27✔
4041
                                else {
4042
                                        c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
17✔
4043
                                        if (!c->rlimit[ri])
17✔
4044
                                                return -ENOMEM;
4045
                                }
4046

4047
                                unit_write_settingf(u, flags, name, "%s=%s", name, f);
44✔
4048
                        }
4049

4050
                        return 1;
88✔
4051
                }
4052

4053
        } else if (streq(name, "MountImages")) {
556✔
4054
                _cleanup_free_ char *format_str = NULL;
×
4055
                MountImage *mount_images = NULL;
×
4056
                size_t n_mount_images = 0;
×
4057
                char *source, *destination;
×
4058
                int permissive;
×
4059

4060
                r = sd_bus_message_enter_container(message, 'a', "(ssba(ss))");
×
4061
                if (r < 0)
×
4062
                        return r;
4063

4064
                for (;;) {
×
4065
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
4066
                        _cleanup_free_ char *source_escaped = NULL, *destination_escaped = NULL;
×
4067
                        char *tuple;
×
4068

4069
                        r = sd_bus_message_enter_container(message, 'r', "ssba(ss)");
×
4070
                        if (r < 0)
×
4071
                                return r;
4072

4073
                        r = sd_bus_message_read(message, "ssb", &source, &destination, &permissive);
×
4074
                        if (r <= 0)
×
4075
                                break;
4076

4077
                        if (!path_is_absolute(source))
×
4078
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
4079
                        if (!path_is_normalized(source))
×
4080
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
4081
                        if (!path_is_absolute(destination))
×
4082
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
×
4083
                        if (!path_is_normalized(destination))
×
4084
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
4085

4086
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
4087
                        source_escaped = shell_escape(source, ":");
×
4088
                        if (!source_escaped)
×
4089
                                return -ENOMEM;
4090
                        destination_escaped = shell_escape(destination, ":");
×
4091
                        if (!destination_escaped)
×
4092
                                return -ENOMEM;
4093

4094
                        tuple = strjoin(format_str,
×
4095
                                        format_str ? " " : "",
4096
                                        permissive ? "-" : "",
4097
                                        source_escaped,
4098
                                        ":",
4099
                                        destination_escaped);
4100
                        if (!tuple)
×
4101
                                return -ENOMEM;
4102
                        free_and_replace(format_str, tuple);
×
4103

4104
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
4105
                        if (r < 0)
×
4106
                                return r;
4107

4108
                        r = sd_bus_message_exit_container(message);
×
4109
                        if (r < 0)
×
4110
                                return r;
4111

4112
                        r = mount_image_add(&mount_images, &n_mount_images,
×
4113
                                            &(MountImage) {
×
4114
                                                    .source = source,
4115
                                                    .destination = destination,
4116
                                                    .mount_options = options,
4117
                                                    .ignore_enoent = permissive,
×
4118
                                                    .type = MOUNT_IMAGE_DISCRETE,
4119
                                            });
4120
                        if (r < 0)
×
4121
                                return r;
4122
                }
4123
                if (r < 0)
×
4124
                        return r;
4125

4126
                r = sd_bus_message_exit_container(message);
×
4127
                if (r < 0)
×
4128
                        return r;
4129

4130
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
4131
                        if (n_mount_images == 0) {
×
4132
                                c->mount_images = mount_image_free_many(c->mount_images, &c->n_mount_images);
×
4133

4134
                                unit_write_settingf(u, flags, name, "%s=", name);
×
4135
                        } else {
4136
                                for (size_t i = 0; i < n_mount_images; ++i) {
×
4137
                                        r = mount_image_add(&c->mount_images, &c->n_mount_images, &mount_images[i]);
×
4138
                                        if (r < 0)
×
4139
                                                return r;
4140
                                }
4141

4142
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
4143
                                                    name,
4144
                                                    "%s=%s",
4145
                                                    name,
4146
                                                    format_str);
4147
                        }
4148
                }
4149

4150
                mount_images = mount_image_free_many(mount_images, &n_mount_images);
×
4151

4152
                return 1;
×
4153
        } else if (streq(name, "ExtensionImages")) {
556✔
4154
                _cleanup_free_ char *format_str = NULL;
×
4155
                MountImage *extension_images = NULL;
×
4156
                size_t n_extension_images = 0;
×
4157

4158
                r = sd_bus_message_enter_container(message, 'a', "(sba(ss))");
×
4159
                if (r < 0)
×
4160
                        return r;
4161

4162
                for (;;) {
×
4163
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
4164
                        _cleanup_free_ char *source_escaped = NULL;
×
4165
                        char *source, *tuple;
×
4166
                        int permissive;
×
4167

4168
                        r = sd_bus_message_enter_container(message, 'r', "sba(ss)");
×
4169
                        if (r < 0)
×
4170
                                return r;
4171

4172
                        r = sd_bus_message_read(message, "sb", &source, &permissive);
×
4173
                        if (r <= 0)
×
4174
                                break;
4175

4176
                        if (!path_is_absolute(source))
×
4177
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
×
4178
                        if (!path_is_normalized(source))
×
4179
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
4180

4181
                        /* Need to store them in the unit with the escapes, so that they can be parsed again */
4182
                        source_escaped = shell_escape(source, ":");
×
4183
                        if (!source_escaped)
×
4184
                                return -ENOMEM;
4185

4186
                        tuple = strjoin(format_str,
×
4187
                                        format_str ? " " : "",
4188
                                        permissive ? "-" : "",
4189
                                        source_escaped);
4190
                        if (!tuple)
×
4191
                                return -ENOMEM;
4192
                        free_and_replace(format_str, tuple);
×
4193

4194
                        r = bus_read_mount_options(message, error, &options, &format_str, ":");
×
4195
                        if (r < 0)
×
4196
                                return r;
4197

4198
                        r = sd_bus_message_exit_container(message);
×
4199
                        if (r < 0)
×
4200
                                return r;
4201

4202
                        r = mount_image_add(&extension_images, &n_extension_images,
×
4203
                                            &(MountImage) {
×
4204
                                                    .source = source,
4205
                                                    .mount_options = options,
4206
                                                    .ignore_enoent = permissive,
×
4207
                                                    .type = MOUNT_IMAGE_EXTENSION,
4208
                                            });
4209
                        if (r < 0)
×
4210
                                return r;
4211
                }
4212
                if (r < 0)
×
4213
                        return r;
4214

4215
                r = sd_bus_message_exit_container(message);
×
4216
                if (r < 0)
×
4217
                        return r;
4218

4219
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
4220
                        if (n_extension_images == 0) {
×
4221
                                c->extension_images = mount_image_free_many(c->extension_images, &c->n_extension_images);
×
4222

4223
                                unit_write_settingf(u, flags, name, "%s=", name);
×
4224
                        } else {
4225
                                for (size_t i = 0; i < n_extension_images; ++i) {
×
4226
                                        r = mount_image_add(&c->extension_images, &c->n_extension_images, &extension_images[i]);
×
4227
                                        if (r < 0)
×
4228
                                                return r;
4229
                                }
4230

4231
                                unit_write_settingf(u, flags|UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS,
×
4232
                                                    name,
4233
                                                    "%s=%s",
4234
                                                    name,
4235
                                                    format_str);
4236
                        }
4237
                }
4238

4239
                extension_images = mount_image_free_many(extension_images, &n_extension_images);
×
4240

4241
                return 1;
×
4242

4243
        } else if (STR_IN_SET(name, "StateDirectorySymlink", "RuntimeDirectorySymlink", "CacheDirectorySymlink", "LogsDirectorySymlink")) {
556✔
4244
                char *source, *destination;
14✔
4245
                ExecDirectory *directory;
14✔
4246
                uint64_t symlink_flags;
14✔
4247
                ExecDirectoryType i;
14✔
4248

4249
                assert_se((i = exec_directory_type_symlink_from_string(name)) >= 0);
14✔
4250
                directory = c->directories + i;
14✔
4251

4252
                r = sd_bus_message_enter_container(message, 'a', "(sst)");
14✔
4253
                if (r < 0)
14✔
4254
                        return r;
14✔
4255

4256
                while ((r = sd_bus_message_read(message, "(sst)", &source, &destination, &symlink_flags)) > 0) {
28✔
4257
                        if ((symlink_flags & ~_EXEC_DIRECTORY_FLAGS_PUBLIC) != 0)
14✔
4258
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid 'flags' parameter '%" PRIu64 "'", symlink_flags);
×
4259
                        if (!path_is_valid(source))
14✔
4260
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not valid.", source);
×
4261
                        if (path_is_absolute(source))
14✔
4262
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is absolute.", source);
×
4263
                        if (!path_is_normalized(source))
14✔
4264
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not normalized.", source);
×
4265
                        if (isempty(destination))
14✔
4266
                                destination = NULL;
2✔
4267
                        else {
4268
                                if (!path_is_valid(destination))
12✔
4269
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not valid.", destination);
×
4270
                                if (path_is_absolute(destination))
12✔
4271
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is absolute.", destination);
×
4272
                                if (!path_is_normalized(destination))
12✔
4273
                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not normalized.", destination);
×
4274
                        }
4275

4276
                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
14✔
4277
                                _cleanup_free_ char *destination_escaped = NULL, *source_escaped = NULL;
7✔
4278

4279
                                r = exec_directory_add(directory, source, destination, symlink_flags);
7✔
4280
                                if (r < 0)
7✔
4281
                                        return r;
4282

4283
                                /* Need to store them in the unit with the escapes, so that they can be parsed again */
4284
                                source_escaped = xescape(source, ":");
7✔
4285
                                if (!source_escaped)
7✔
4286
                                        return -ENOMEM;
4287
                                if (destination) {
7✔
4288
                                        destination_escaped = xescape(destination, ":");
6✔
4289
                                        if (!destination_escaped)
6✔
4290
                                                return -ENOMEM;
4291
                                }
4292

4293
                                unit_write_settingf(
8✔
4294
                                                u, flags|UNIT_ESCAPE_SPECIFIERS, exec_directory_type_to_string(i),
7✔
4295
                                                "%s=%s%s%s%s",
4296
                                                exec_directory_type_to_string(i),
4297
                                                source_escaped,
4298
                                                destination_escaped || FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":" : "",
1✔
4299
                                                destination_escaped,
4300
                                                FLAGS_SET(symlink_flags, EXEC_DIRECTORY_READ_ONLY) ? ":ro" : "");
7✔
4301
                        }
4302
                }
4303
                if (r < 0)
14✔
4304
                        return r;
4305

4306
                exec_directory_sort(directory);
14✔
4307

4308
                r = sd_bus_message_exit_container(message);
14✔
4309
                if (r < 0)
14✔
4310
                        return r;
4311

4312
                return 1;
14✔
4313

4314
        } else if (STR_IN_SET(name, "RootImagePolicy", "MountImagePolicy", "ExtensionImagePolicy")) {
542✔
4315
                _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
×
4316
                const char *s;
×
4317

4318
                r = sd_bus_message_read(message, "s", &s);
×
4319
                if (r < 0)
×
4320
                        return r;
4321

4322
                r = image_policy_from_string(s, &p);
×
4323
                if (r < 0)
×
4324
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse image policy string: %s", s);
×
4325

4326
                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
4327
                        _cleanup_free_ char *t = NULL;
×
4328
                        ImagePolicy **pp =
×
4329
                                streq(name, "RootImagePolicy")  ? &c->root_image_policy :
×
4330
                                streq(name, "MountImagePolicy") ? &c->mount_image_policy :
×
4331
                                                                  &c->extension_image_policy;
4332

4333
                        r = image_policy_to_string(p, /* simplify= */ true, &t);
×
4334
                        if (r < 0)
×
4335
                                return r;
×
4336

4337
                        image_policy_free(*pp);
×
4338
                        *pp = TAKE_PTR(p);
×
4339

4340
                        unit_write_settingf(
×
4341
                                        u, flags, name,
4342
                                        "%s=%s",
4343
                                        name,
4344
                                        t); /* no escaping necessary */
4345
                }
4346

4347
                return 1;
×
4348
        }
4349

4350
        return 0;
542✔
4351
}
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