1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2012 Lennart Poettering
6 Copyright 2013 Zbigniew Jędrzejewski-Szmek
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/capability.h>
29 #include "alloc-util.h"
30 #include "capability-util.h"
34 #include "hostname-util.h"
35 #include "install-printf.h"
37 #include "load-fragment.h"
40 #include "specifier.h"
41 #include "string-util.h"
43 #include "test-helper.h"
45 #include "user-util.h"
48 static int test_unit_file_get_set(void) {
54 h
= hashmap_new(&string_hash_ops
);
57 r
= unit_file_get_list(UNIT_FILE_SYSTEM
, NULL
, h
, NULL
, NULL
);
59 if (IN_SET(r
, -EPERM
, -EACCES
)) {
60 log_notice_errno(r
, "Skipping test: unit_file_get_list: %m");
61 return EXIT_TEST_SKIP
;
64 log_full_errno(r
== 0 ? LOG_INFO
: LOG_ERR
, r
,
65 "unit_file_get_list: %m");
69 HASHMAP_FOREACH(p
, h
, i
)
70 printf("%s = %s\n", p
->path
, unit_file_state_to_string(p
->state
));
72 unit_file_list_free(h
);
77 static void check_execcommand(ExecCommand
*c
,
86 log_info("expect: \"%s\" [\"%s\" \"%s\" \"%s\"]",
87 path
, argv0
?: path
, argv1
, argv2
);
88 n
= strv_length(c
->argv
);
89 log_info("actual: \"%s\" [\"%s\" \"%s\" \"%s\"]",
90 c
->path
, c
->argv
[0], n
> 0 ? c
->argv
[1] : NULL
, n
> 1 ? c
->argv
[2] : NULL
);
91 assert_se(streq(c
->path
, path
));
92 assert_se(streq(c
->argv
[0], argv0
?: path
));
94 assert_se(streq_ptr(c
->argv
[1], argv1
));
96 assert_se(streq_ptr(c
->argv
[2], argv2
));
97 assert_se(!!(c
->flags
& EXEC_COMMAND_IGNORE_FAILURE
) == ignore
);
100 static void test_config_parse_exec(void) {
101 /* int config_parse_exec(
103 const char *filename,
106 unsigned section_line,
114 ExecCommand
*c
= NULL
, *c1
;
116 _cleanup_(manager_freep
) Manager
*m
= NULL
;
117 _cleanup_(unit_freep
) Unit
*u
= NULL
;
119 r
= manager_new(UNIT_FILE_USER
, MANAGER_TEST_RUN_MINIMAL
, &m
);
120 if (MANAGER_SKIP_TEST(r
)) {
121 log_notice_errno(r
, "Skipping test: manager_new: %m");
126 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
128 assert_se(u
= unit_new(m
, sizeof(Service
)));
130 log_info("/* basic test */");
131 r
= config_parse_exec(NULL
, "fake", 1, "section", 1,
132 "LValue", 0, "/RValue r1",
135 check_execcommand(c
, "/RValue", "/RValue", "r1", NULL
, false);
137 r
= config_parse_exec(NULL
, "fake", 2, "section", 1,
138 "LValue", 0, "/RValue///slashes r1///",
141 log_info("/* test slashes */");
143 c1
= c
->command_next
;
144 check_execcommand(c1
, "/RValue/slashes", "/RValue///slashes", "r1///", NULL
, false);
146 log_info("/* trailing slash */");
147 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
148 "LValue", 0, "/RValue/ argv0 r1",
150 assert_se(r
== -ENOEXEC
);
151 assert_se(c1
->command_next
== NULL
);
153 log_info("/* honour_argv0 */");
154 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
155 "LValue", 0, "@/RValue///slashes2 ///argv0 r1",
158 c1
= c1
->command_next
;
159 check_execcommand(c1
, "/RValue/slashes2", "///argv0", "r1", NULL
, false);
161 log_info("/* honour_argv0, no args */");
162 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
163 "LValue", 0, "@/RValue",
165 assert_se(r
== -ENOEXEC
);
166 assert_se(c1
->command_next
== NULL
);
168 log_info("/* no command, whitespace only, reset */");
169 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
173 assert_se(c
== NULL
);
175 log_info("/* ignore && honour_argv0 */");
176 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
177 "LValue", 0, "-@/RValue///slashes3 argv0a r1",
181 check_execcommand(c1
, "/RValue/slashes3", "argv0a", "r1", NULL
, true);
183 log_info("/* ignore && honour_argv0 */");
184 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
185 "LValue", 0, "@-/RValue///slashes4 argv0b r1",
188 c1
= c1
->command_next
;
189 check_execcommand(c1
, "/RValue/slashes4", "argv0b", "r1", NULL
, true);
191 log_info("/* ignore && ignore */");
192 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
193 "LValue", 0, "--/RValue argv0 r1",
196 assert_se(c1
->command_next
== NULL
);
198 log_info("/* ignore && ignore (2) */");
199 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
200 "LValue", 0, "-@-/RValue argv0 r1",
203 assert_se(c1
->command_next
== NULL
);
205 log_info("/* semicolon */");
206 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
208 "-@/RValue argv0 r1 ; "
212 c1
= c1
->command_next
;
213 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
215 c1
= c1
->command_next
;
216 check_execcommand(c1
, "/goo/goo", NULL
, "boo", NULL
, false);
218 log_info("/* two semicolons in a row */");
219 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
221 "-@/RValue argv0 r1 ; ; "
224 assert_se(r
== -ENOEXEC
);
225 c1
= c1
->command_next
;
226 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
228 /* second command fails because the executable name is ";" */
229 assert_se(c1
->command_next
== NULL
);
231 log_info("/* trailing semicolon */");
232 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
234 "-@/RValue argv0 r1 ; ",
237 c1
= c1
->command_next
;
238 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
240 assert_se(c1
->command_next
== NULL
);
242 log_info("/* trailing semicolon, no whitespace */");
243 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
245 "-@/RValue argv0 r1 ;",
248 c1
= c1
->command_next
;
249 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
251 assert_se(c1
->command_next
== NULL
);
253 log_info("/* trailing semicolon in single quotes */");
254 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
256 "-@/RValue argv0 r1 ';'",
259 c1
= c1
->command_next
;
260 check_execcommand(c1
, "/RValue", "argv0", "r1", ";", true);
262 log_info("/* escaped semicolon */");
263 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
268 c1
= c1
->command_next
;
269 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
271 log_info("/* escaped semicolon with following arg */");
272 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
277 c1
= c1
->command_next
;
278 check_execcommand(c1
,
279 "/sbin/find", NULL
, ";", "/x", false);
281 log_info("/* escaped semicolon as part of an expression */");
282 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
287 c1
= c1
->command_next
;
288 check_execcommand(c1
,
289 "/sbin/find", NULL
, "\\;x", NULL
, false);
291 log_info("/* encoded semicolon */");
292 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
297 c1
= c1
->command_next
;
298 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
300 log_info("/* quoted semicolon */");
301 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
306 c1
= c1
->command_next
;
307 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
309 log_info("/* quoted semicolon with following arg */");
310 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
312 "/sbin/find \";\" /x",
315 c1
= c1
->command_next
;
316 check_execcommand(c1
,
317 "/sbin/find", NULL
, ";", "/x", false);
319 log_info("/* spaces in the filename */");
320 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
322 "\"/PATH WITH SPACES/daemon\" -1 -2",
325 c1
= c1
->command_next
;
326 check_execcommand(c1
,
327 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
329 log_info("/* spaces in the filename, no args */");
330 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
332 "\"/PATH WITH SPACES/daemon -1 -2\"",
335 c1
= c1
->command_next
;
336 check_execcommand(c1
,
337 "/PATH WITH SPACES/daemon -1 -2", NULL
, NULL
, NULL
, false);
339 log_info("/* spaces in the filename, everything quoted */");
340 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
342 "\"/PATH WITH SPACES/daemon\" \"-1\" '-2'",
345 c1
= c1
->command_next
;
346 check_execcommand(c1
,
347 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
349 log_info("/* escaped spaces in the filename */");
350 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
352 "\"/PATH\\sWITH\\sSPACES/daemon\" '-1 -2'",
355 c1
= c1
->command_next
;
356 check_execcommand(c1
,
357 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
359 log_info("/* escaped spaces in the filename (2) */");
360 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
362 "\"/PATH\\x20WITH\\x20SPACES/daemon\" \"-1 -2\"",
365 c1
= c1
->command_next
;
366 check_execcommand(c1
,
367 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
369 for (ccc
= "abfnrtv\\\'\"x"; *ccc
; ccc
++) {
370 /* \\x is an incomplete hexadecimal sequence, invalid because of the slash */
371 char path
[] = "/path\\X";
372 path
[sizeof(path
) - 2] = *ccc
;
374 log_info("/* invalid character: \\%c */", *ccc
);
375 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
378 assert_se(r
== -ENOEXEC
);
379 assert_se(c1
->command_next
== NULL
);
382 log_info("/* valid character: \\s */");
383 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
384 "LValue", 0, "/path\\s",
387 c1
= c1
->command_next
;
388 check_execcommand(c1
, "/path ", NULL
, NULL
, NULL
, false);
390 log_info("/* quoted backslashes */");
391 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
393 "/bin/grep '\\w+\\K'",
396 c1
= c1
->command_next
;
397 check_execcommand(c1
, "/bin/grep", NULL
, "\\w+\\K", NULL
, false);
400 log_info("/* trailing backslash: \\ */");
401 /* backslash is invalid */
402 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
403 "LValue", 0, "/path\\",
405 assert_se(r
== -ENOEXEC
);
406 assert_se(c1
->command_next
== NULL
);
408 log_info("/* missing ending ' */");
409 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
410 "LValue", 0, "/path 'foo",
412 assert_se(r
== -ENOEXEC
);
413 assert_se(c1
->command_next
== NULL
);
415 log_info("/* missing ending ' with trailing backslash */");
416 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
417 "LValue", 0, "/path 'foo\\",
419 assert_se(r
== -ENOEXEC
);
420 assert_se(c1
->command_next
== NULL
);
422 log_info("/* invalid space between modifiers */");
423 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
424 "LValue", 0, "- /path",
427 assert_se(c1
->command_next
== NULL
);
429 log_info("/* only modifiers, no path */");
430 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
434 assert_se(c1
->command_next
== NULL
);
436 log_info("/* empty argument, reset */");
437 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
441 assert_se(c
== NULL
);
443 exec_command_free_list(c
);
446 static void test_config_parse_log_extra_fields(void) {
447 /* int config_parse_log_extra_fields(
449 const char *filename,
452 unsigned section_line,
461 _cleanup_(manager_freep
) Manager
*m
= NULL
;
462 _cleanup_(unit_freep
) Unit
*u
= NULL
;
465 r
= manager_new(UNIT_FILE_USER
, MANAGER_TEST_RUN_MINIMAL
, &m
);
466 if (MANAGER_SKIP_TEST(r
)) {
467 log_notice_errno(r
, "Skipping test: manager_new: %m");
472 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
474 assert_se(u
= unit_new(m
, sizeof(Service
)));
476 log_info("/* %s – basic test */", __func__
);
477 r
= config_parse_log_extra_fields(NULL
, "fake", 1, "section", 1,
478 "LValue", 0, "FOO=BAR \"QOOF=quux ' ' \"",
481 assert_se(c
.n_log_extra_fields
== 2);
482 assert_se(strneq(c
.log_extra_fields
[0].iov_base
, "FOO=BAR", c
.log_extra_fields
[0].iov_len
));
483 assert_se(strneq(c
.log_extra_fields
[1].iov_base
, "QOOF=quux ' ' ", c
.log_extra_fields
[1].iov_len
));
485 log_info("/* %s – add some */", __func__
);
486 r
= config_parse_log_extra_fields(NULL
, "fake", 1, "section", 1,
487 "LValue", 0, "FOO2=BAR2 QOOF2=quux ' '",
490 assert_se(c
.n_log_extra_fields
== 4);
491 assert_se(strneq(c
.log_extra_fields
[0].iov_base
, "FOO=BAR", c
.log_extra_fields
[0].iov_len
));
492 assert_se(strneq(c
.log_extra_fields
[1].iov_base
, "QOOF=quux ' ' ", c
.log_extra_fields
[1].iov_len
));
493 assert_se(strneq(c
.log_extra_fields
[2].iov_base
, "FOO2=BAR2", c
.log_extra_fields
[2].iov_len
));
494 assert_se(strneq(c
.log_extra_fields
[3].iov_base
, "QOOF2=quux", c
.log_extra_fields
[3].iov_len
));
496 exec_context_dump(&c
, stdout
, " --> ");
498 log_info("/* %s – reset */", __func__
);
499 r
= config_parse_log_extra_fields(NULL
, "fake", 1, "section", 1,
503 assert_se(c
.n_log_extra_fields
== 0);
505 exec_context_free_log_extra_fields(&c
);
507 log_info("/* %s – bye */", __func__
);
525 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
526 "#--nouser-config \\\n" \
532 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
534 "# For compatibility reasons\n" \
536 "MODULE_0=coretemp\n" \
543 static void test_load_env_file_1(void) {
544 _cleanup_strv_free_
char **data
= NULL
;
547 char name
[] = "/tmp/test-load-env-file.XXXXXX";
548 _cleanup_close_
int fd
;
550 fd
= mkostemp_safe(name
);
552 assert_se(write(fd
, env_file_1
, sizeof(env_file_1
)) == sizeof(env_file_1
));
554 r
= load_env_file(NULL
, name
, NULL
, &data
);
556 assert_se(streq(data
[0], "a=a"));
557 assert_se(streq(data
[1], "b=bc"));
558 assert_se(streq(data
[2], "d=def"));
559 assert_se(streq(data
[3], "g=g "));
560 assert_se(streq(data
[4], "h=h"));
561 assert_se(streq(data
[5], "i=i"));
562 assert_se(data
[6] == NULL
);
566 static void test_load_env_file_2(void) {
567 _cleanup_strv_free_
char **data
= NULL
;
570 char name
[] = "/tmp/test-load-env-file.XXXXXX";
571 _cleanup_close_
int fd
;
573 fd
= mkostemp_safe(name
);
575 assert_se(write(fd
, env_file_2
, sizeof(env_file_2
)) == sizeof(env_file_2
));
577 r
= load_env_file(NULL
, name
, NULL
, &data
);
579 assert_se(streq(data
[0], "a=a"));
580 assert_se(data
[1] == NULL
);
584 static void test_load_env_file_3(void) {
585 _cleanup_strv_free_
char **data
= NULL
;
588 char name
[] = "/tmp/test-load-env-file.XXXXXX";
589 _cleanup_close_
int fd
;
591 fd
= mkostemp_safe(name
);
593 assert_se(write(fd
, env_file_3
, sizeof(env_file_3
)) == sizeof(env_file_3
));
595 r
= load_env_file(NULL
, name
, NULL
, &data
);
597 assert_se(data
== NULL
);
601 static void test_load_env_file_4(void) {
602 _cleanup_strv_free_
char **data
= NULL
;
603 char name
[] = "/tmp/test-load-env-file.XXXXXX";
604 _cleanup_close_
int fd
;
607 fd
= mkostemp_safe(name
);
609 assert_se(write(fd
, env_file_4
, sizeof(env_file_4
)) == sizeof(env_file_4
));
611 r
= load_env_file(NULL
, name
, NULL
, &data
);
613 assert_se(streq(data
[0], "HWMON_MODULES=coretemp f71882fg"));
614 assert_se(streq(data
[1], "MODULE_0=coretemp"));
615 assert_se(streq(data
[2], "MODULE_1=f71882fg"));
616 assert_se(data
[3] == NULL
);
620 static void test_load_env_file_5(void) {
621 _cleanup_strv_free_
char **data
= NULL
;
624 char name
[] = "/tmp/test-load-env-file.XXXXXX";
625 _cleanup_close_
int fd
;
627 fd
= mkostemp_safe(name
);
629 assert_se(write(fd
, env_file_5
, sizeof(env_file_5
)) == sizeof(env_file_5
));
631 r
= load_env_file(NULL
, name
, NULL
, &data
);
633 assert_se(streq(data
[0], "a="));
634 assert_se(streq(data
[1], "b="));
635 assert_se(data
[2] == NULL
);
639 static void test_install_printf(void) {
640 char name
[] = "name.service",
641 path
[] = "/run/systemd/system/name.service";
642 UnitFileInstallInfo i
= { .name
= name
, .path
= path
, };
643 UnitFileInstallInfo i2
= { .name
= name
, .path
= path
, };
644 char name3
[] = "name@inst.service",
645 path3
[] = "/run/systemd/system/name.service";
646 UnitFileInstallInfo i3
= { .name
= name3
, .path
= path3
, };
647 UnitFileInstallInfo i4
= { .name
= name3
, .path
= path3
, };
649 _cleanup_free_
char *mid
= NULL
, *bid
= NULL
, *host
= NULL
, *uid
= NULL
, *user
= NULL
;
651 assert_se(specifier_machine_id('m', NULL
, NULL
, &mid
) >= 0 && mid
);
652 assert_se(specifier_boot_id('b', NULL
, NULL
, &bid
) >= 0 && bid
);
653 assert_se((host
= gethostname_malloc()));
654 assert_se((user
= uid_to_name(getuid())));
655 assert_se(asprintf(&uid
, UID_FMT
, getuid()) >= 0);
657 #define expect(src, pattern, result) \
659 _cleanup_free_ char *t = NULL; \
660 _cleanup_free_ char \
661 *d1 = strdup(i.name), \
662 *d2 = strdup(i.path); \
663 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
664 memzero(i.name, strlen(i.name)); \
665 memzero(i.path, strlen(i.path)); \
666 assert_se(d1 && d2); \
669 assert_se(streq(t, result)); \
670 } else assert_se(t == NULL); \
671 strcpy(i.name, d1); \
672 strcpy(i.path, d2); \
675 expect(i
, "%n", "name.service");
676 expect(i
, "%N", "name");
677 expect(i
, "%p", "name");
679 expect(i
, "%u", user
);
680 expect(i
, "%U", uid
);
682 expect(i
, "%m", mid
);
683 expect(i
, "%b", bid
);
684 expect(i
, "%H", host
);
686 expect(i2
, "%u", user
);
687 expect(i2
, "%U", uid
);
689 expect(i3
, "%n", "name@inst.service");
690 expect(i3
, "%N", "name@inst");
691 expect(i3
, "%p", "name");
692 expect(i3
, "%u", user
);
693 expect(i3
, "%U", uid
);
695 expect(i3
, "%m", mid
);
696 expect(i3
, "%b", bid
);
697 expect(i3
, "%H", host
);
699 expect(i4
, "%u", user
);
700 expect(i4
, "%U", uid
);
703 static uint64_t make_cap(int cap
) {
704 return ((uint64_t) 1ULL << (uint64_t) cap
);
707 static void test_config_parse_capability_set(void) {
708 /* int config_parse_capability_set(
710 const char *filename,
713 unsigned section_line,
720 uint64_t capability_bounding_set
= 0;
722 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
723 "CapabilityBoundingSet", 0, "CAP_NET_RAW",
724 &capability_bounding_set
, NULL
);
726 assert_se(capability_bounding_set
== make_cap(CAP_NET_RAW
));
728 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
729 "CapabilityBoundingSet", 0, "CAP_NET_ADMIN",
730 &capability_bounding_set
, NULL
);
732 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
734 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
735 "CapabilityBoundingSet", 0, "~CAP_NET_ADMIN",
736 &capability_bounding_set
, NULL
);
738 assert_se(capability_bounding_set
== make_cap(CAP_NET_RAW
));
740 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
741 "CapabilityBoundingSet", 0, "",
742 &capability_bounding_set
, NULL
);
744 assert_se(capability_bounding_set
== UINT64_C(0));
746 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
747 "CapabilityBoundingSet", 0, "~",
748 &capability_bounding_set
, NULL
);
750 assert_se(cap_test_all(capability_bounding_set
));
752 capability_bounding_set
= 0;
753 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
754 "CapabilityBoundingSet", 0, " 'CAP_NET_RAW' WAT_CAP??? CAP_NET_ADMIN CAP'_trailing_garbage",
755 &capability_bounding_set
, NULL
);
757 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
760 static void test_config_parse_rlimit(void) {
761 struct rlimit
* rl
[_RLIMIT_MAX
] = {};
763 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55", rl
, NULL
) >= 0);
764 assert_se(rl
[RLIMIT_NOFILE
]);
765 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
766 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
768 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55:66", rl
, NULL
) >= 0);
769 assert_se(rl
[RLIMIT_NOFILE
]);
770 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
771 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 66);
773 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity", rl
, NULL
) >= 0);
774 assert_se(rl
[RLIMIT_NOFILE
]);
775 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
776 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
778 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity:infinity", rl
, NULL
) >= 0);
779 assert_se(rl
[RLIMIT_NOFILE
]);
780 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
781 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
783 rl
[RLIMIT_NOFILE
]->rlim_cur
= 10;
784 rl
[RLIMIT_NOFILE
]->rlim_max
= 20;
786 /* Invalid values don't change rl */
787 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "10:20:30", rl
, NULL
) >= 0);
788 assert_se(rl
[RLIMIT_NOFILE
]);
789 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
790 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
792 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "wat:wat", rl
, NULL
) >= 0);
793 assert_se(rl
[RLIMIT_NOFILE
]);
794 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
795 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
797 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "66:wat", rl
, NULL
) >= 0);
798 assert_se(rl
[RLIMIT_NOFILE
]);
799 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
800 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
802 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "200:100", rl
, NULL
) >= 0);
803 assert_se(rl
[RLIMIT_NOFILE
]);
804 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
805 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
807 rl
[RLIMIT_NOFILE
] = mfree(rl
[RLIMIT_NOFILE
]);
809 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "56", rl
, NULL
) >= 0);
810 assert_se(rl
[RLIMIT_CPU
]);
811 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 56);
812 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
814 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "57s", rl
, NULL
) >= 0);
815 assert_se(rl
[RLIMIT_CPU
]);
816 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 57);
817 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
819 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "40s:1m", rl
, NULL
) >= 0);
820 assert_se(rl
[RLIMIT_CPU
]);
821 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 40);
822 assert_se(rl
[RLIMIT_CPU
]->rlim_max
== 60);
824 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "infinity", rl
, NULL
) >= 0);
825 assert_se(rl
[RLIMIT_CPU
]);
826 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== RLIM_INFINITY
);
827 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
829 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "1234ms", rl
, NULL
) >= 0);
830 assert_se(rl
[RLIMIT_CPU
]);
831 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 2);
832 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
834 rl
[RLIMIT_CPU
] = mfree(rl
[RLIMIT_CPU
]);
836 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58", rl
, NULL
) >= 0);
837 assert_se(rl
[RLIMIT_RTTIME
]);
838 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
839 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
841 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58:60", rl
, NULL
) >= 0);
842 assert_se(rl
[RLIMIT_RTTIME
]);
843 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
844 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 60);
846 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s", rl
, NULL
) >= 0);
847 assert_se(rl
[RLIMIT_RTTIME
]);
848 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
849 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
851 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s:123s", rl
, NULL
) >= 0);
852 assert_se(rl
[RLIMIT_RTTIME
]);
853 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
854 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 123 * USEC_PER_SEC
);
856 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity", rl
, NULL
) >= 0);
857 assert_se(rl
[RLIMIT_RTTIME
]);
858 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
859 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
861 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity:infinity", rl
, NULL
) >= 0);
862 assert_se(rl
[RLIMIT_RTTIME
]);
863 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
864 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
866 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "2345ms", rl
, NULL
) >= 0);
867 assert_se(rl
[RLIMIT_RTTIME
]);
868 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 2345 * USEC_PER_MSEC
);
869 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
871 rl
[RLIMIT_RTTIME
] = mfree(rl
[RLIMIT_RTTIME
]);
874 static void test_config_parse_pass_environ(void) {
875 /* int config_parse_pass_environ(
877 const char *filename,
880 unsigned section_line,
887 _cleanup_strv_free_
char **passenv
= NULL
;
889 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
890 "PassEnvironment", 0, "A B",
893 assert_se(strv_length(passenv
) == 2);
894 assert_se(streq(passenv
[0], "A"));
895 assert_se(streq(passenv
[1], "B"));
897 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
898 "PassEnvironment", 0, "",
901 assert_se(strv_isempty(passenv
));
903 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
904 "PassEnvironment", 0, "'invalid name' 'normal_name' A=1 \\",
907 assert_se(strv_length(passenv
) == 1);
908 assert_se(streq(passenv
[0], "normal_name"));
912 static void test_unit_dump_config_items(void) {
913 unit_dump_config_items(stdout
);
916 int main(int argc
, char *argv
[]) {
917 _cleanup_(rm_rf_physical_and_freep
) char *runtime_dir
= NULL
;
920 log_parse_environment();
923 r
= enter_cgroup_subroot();
924 if (r
== -ENOMEDIUM
) {
925 log_notice_errno(r
, "Skipping test: cgroupfs not available");
926 return EXIT_TEST_SKIP
;
929 assert_se(runtime_dir
= setup_fake_runtime_dir());
931 r
= test_unit_file_get_set();
932 test_config_parse_exec();
933 test_config_parse_log_extra_fields();
934 test_config_parse_capability_set();
935 test_config_parse_rlimit();
936 test_config_parse_pass_environ();
937 test_load_env_file_1();
938 test_load_env_file_2();
939 test_load_env_file_3();
940 test_load_env_file_4();
941 test_load_env_file_5();
942 TEST_REQ_RUNNING_SYSTEMD(test_install_printf());
943 test_unit_dump_config_items();