chiark / gitweb /
specifier: when resolving specifier strings when loading configuration, don't misunde...
[elogind.git] / src / core / load-fragment.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2012 Holger Hans Peter Freyther
8
9   systemd is free software; you can redistribute it and/or modify it
10   under the terms of the GNU Lesser General Public License as published by
11   the Free Software Foundation; either version 2.1 of the License, or
12   (at your option) any later version.
13
14   systemd is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <linux/oom.h>
24 #include <assert.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sched.h>
30 #include <sys/prctl.h>
31 #include <sys/mount.h>
32 #include <linux/fs.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <sys/resource.h>
36
37 #include "unit.h"
38 #include "strv.h"
39 #include "conf-parser.h"
40 #include "load-fragment.h"
41 #include "log.h"
42 #include "ioprio.h"
43 #include "securebits.h"
44 #include "missing.h"
45 #include "unit-name.h"
46 #include "unit-printf.h"
47 #include "bus-errors.h"
48 #include "utf8.h"
49 #include "path-util.h"
50 #include "syscall-list.h"
51 #include "env-util.h"
52
53 #ifndef HAVE_SYSV_COMPAT
54 int config_parse_warn_compat(
55                 const char *filename,
56                 unsigned line,
57                 const char *section,
58                 const char *lvalue,
59                 int ltype,
60                 const char *rvalue,
61                 void *data,
62                 void *userdata) {
63
64         log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue);
65         return 0;
66 }
67 #endif
68
69 int config_parse_unit_deps(
70                 const char *filename,
71                 unsigned line,
72                 const char *section,
73                 const char *lvalue,
74                 int ltype,
75                 const char *rvalue,
76                 void *data,
77                 void *userdata) {
78
79         UnitDependency d = ltype;
80         Unit *u = userdata;
81         char *w;
82         size_t l;
83         char *state;
84
85         assert(filename);
86         assert(lvalue);
87         assert(rvalue);
88
89         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
90                 char _cleanup_free_ *t = NULL, *k = NULL;
91                 int r;
92
93                 t = strndup(w, l);
94                 if (!t)
95                         return log_oom();
96
97                 k = unit_name_printf(u, t);
98                 if (!k)
99                         return log_oom();
100
101                 r = unit_add_dependency_by_name(u, d, k, NULL, true);
102                 if (r < 0)
103                         log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s",
104                                   filename, line, k, strerror(-r));
105         }
106
107         return 0;
108 }
109
110 int config_parse_unit_string_printf(
111                 const char *filename,
112                 unsigned line,
113                 const char *section,
114                 const char *lvalue,
115                 int ltype,
116                 const char *rvalue,
117                 void *data,
118                 void *userdata) {
119
120         Unit *u = userdata;
121         _cleanup_free_ char *k = NULL;
122
123         assert(filename);
124         assert(lvalue);
125         assert(rvalue);
126         assert(u);
127
128         k = unit_full_printf(u, rvalue);
129         if (!k)
130                 log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
131                           filename, line, rvalue);
132
133         return config_parse_string(filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata);
134 }
135
136 int config_parse_unit_strv_printf(
137                 const char *filename,
138                 unsigned line,
139                 const char *section,
140                 const char *lvalue,
141                 int ltype,
142                 const char *rvalue,
143                 void *data,
144                 void *userdata) {
145
146         Unit *u = userdata;
147         _cleanup_free_ char *k = NULL;
148
149         assert(filename);
150         assert(lvalue);
151         assert(rvalue);
152         assert(u);
153
154         k = unit_full_printf(u, rvalue);
155         if (!k)
156                 log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
157                           filename, line, rvalue);
158
159         return config_parse_strv(filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata);
160 }
161
162 int config_parse_unit_path_printf(
163                 const char *filename,
164                 unsigned line,
165                 const char *section,
166                 const char *lvalue,
167                 int ltype,
168                 const char *rvalue,
169                 void *data,
170                 void *userdata) {
171
172         Unit *u = userdata;
173         _cleanup_free_ char *k = NULL;
174
175         assert(filename);
176         assert(lvalue);
177         assert(rvalue);
178         assert(u);
179
180         k = unit_full_printf(u, rvalue);
181         if (!k)
182                 log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
183                           filename, line, rvalue);
184
185         return config_parse_path(filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata);
186 }
187
188 int config_parse_socket_listen(
189                 const char *filename,
190                 unsigned line,
191                 const char *section,
192                 const char *lvalue,
193                 int ltype,
194                 const char *rvalue,
195                 void *data,
196                 void *userdata) {
197
198         SocketPort *p, *tail;
199         Socket *s;
200
201         assert(filename);
202         assert(lvalue);
203         assert(rvalue);
204         assert(data);
205
206         s = SOCKET(data);
207
208         if (isempty(rvalue)) {
209                 /* An empty assignment removes all ports */
210                 socket_free_ports(s);
211                 return 0;
212         }
213
214         p = new0(SocketPort, 1);
215         if (!p)
216                 return log_oom();
217
218         if (ltype != SOCKET_SOCKET) {
219
220                 p->type = ltype;
221                 p->path = unit_full_printf(UNIT(s), rvalue);
222                 if (!p->path) {
223                         p->path = strdup(rvalue);
224                         if (!p->path) {
225                                 free(p);
226                                 return log_oom();
227                         } else
228                                 log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
229                                           filename, line, rvalue);
230                 }
231
232                 path_kill_slashes(p->path);
233
234         } else if (streq(lvalue, "ListenNetlink")) {
235                 _cleanup_free_ char  *k = NULL;
236                 int r;
237
238                 p->type = SOCKET_SOCKET;
239                 k = unit_full_printf(UNIT(s), rvalue);
240                 if (!k)
241                         log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
242                                   filename, line, rvalue);
243
244                 r = socket_address_parse_netlink(&p->address, k ? k : rvalue);
245                 if (r < 0) {
246                         log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
247                         free(p);
248                         return 0;
249                 }
250
251         } else {
252                 _cleanup_free_ char *k = NULL;
253                 int r;
254
255                 p->type = SOCKET_SOCKET;
256                 k = unit_full_printf(UNIT(s), rvalue);
257                 if (!k)
258                         log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
259                                   filename, line, rvalue);
260
261                 r = socket_address_parse(&p->address, k ? k : rvalue);
262                 if (r < 0) {
263                         log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
264                         free(p);
265                         return 0;
266                 }
267
268                 if (streq(lvalue, "ListenStream"))
269                         p->address.type = SOCK_STREAM;
270                 else if (streq(lvalue, "ListenDatagram"))
271                         p->address.type = SOCK_DGRAM;
272                 else {
273                         assert(streq(lvalue, "ListenSequentialPacket"));
274                         p->address.type = SOCK_SEQPACKET;
275                 }
276
277                 if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
278                         log_error("[%s:%u] Address family not supported, ignoring: %s", filename, line, rvalue);
279                         free(p);
280                         return 0;
281                 }
282         }
283
284         p->fd = -1;
285
286         if (s->ports) {
287                 LIST_FIND_TAIL(SocketPort, port, s->ports, tail);
288                 LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p);
289         } else
290                 LIST_PREPEND(SocketPort, port, s->ports, p);
291
292         return 0;
293 }
294
295 int config_parse_socket_bind(
296                 const char *filename,
297                 unsigned line,
298                 const char *section,
299                 const char *lvalue,
300                 int ltype,
301                 const char *rvalue,
302                 void *data,
303                 void *userdata) {
304
305         Socket *s;
306         SocketAddressBindIPv6Only b;
307
308         assert(filename);
309         assert(lvalue);
310         assert(rvalue);
311         assert(data);
312
313         s = SOCKET(data);
314
315         b = socket_address_bind_ipv6_only_from_string(rvalue);
316         if (b < 0) {
317                 int r;
318
319                 r = parse_boolean(rvalue);
320                 if (r < 0) {
321                         log_error("[%s:%u] Failed to parse bind IPv6 only value, ignoring: %s", filename, line, rvalue);
322                         return 0;
323                 }
324
325                 s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
326         } else
327                 s->bind_ipv6_only = b;
328
329         return 0;
330 }
331
332 int config_parse_exec_nice(
333                 const char *filename,
334                 unsigned line,
335                 const char *section,
336                 const char *lvalue,
337                 int ltype,
338                 const char *rvalue,
339                 void *data,
340                 void *userdata) {
341
342         ExecContext *c = data;
343         int priority;
344
345         assert(filename);
346         assert(lvalue);
347         assert(rvalue);
348         assert(data);
349
350         if (safe_atoi(rvalue, &priority) < 0) {
351                 log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue);
352                 return 0;
353         }
354
355         if (priority < PRIO_MIN || priority >= PRIO_MAX) {
356                 log_error("[%s:%u] Nice priority out of range, ignoring: %s", filename, line, rvalue);
357                 return 0;
358         }
359
360         c->nice = priority;
361         c->nice_set = true;
362
363         return 0;
364 }
365
366 int config_parse_exec_oom_score_adjust(
367                 const char *filename,
368                 unsigned line,
369                 const char *section,
370                 const char *lvalue,
371                 int ltype,
372                 const char *rvalue,
373                 void *data,
374                 void *userdata) {
375
376         ExecContext *c = data;
377         int oa;
378
379         assert(filename);
380         assert(lvalue);
381         assert(rvalue);
382         assert(data);
383
384         if (safe_atoi(rvalue, &oa) < 0) {
385                 log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue);
386                 return 0;
387         }
388
389         if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) {
390                 log_error("[%s:%u] OOM score adjust value out of range, ignoring: %s", filename, line, rvalue);
391                 return 0;
392         }
393
394         c->oom_score_adjust = oa;
395         c->oom_score_adjust_set = true;
396
397         return 0;
398 }
399
400 int config_parse_exec(
401                 const char *filename,
402                 unsigned line,
403                 const char *section,
404                 const char *lvalue,
405                 int ltype,
406                 const char *rvalue,
407                 void *data,
408                 void *userdata) {
409
410         ExecCommand **e = data, *nce;
411         char *path, **n;
412         unsigned k;
413         int r;
414
415         assert(filename);
416         assert(lvalue);
417         assert(rvalue);
418         assert(e);
419
420         e += ltype;
421
422         if (isempty(rvalue)) {
423                 /* An empty assignment resets the list */
424                 exec_command_free_list(*e);
425                 *e = NULL;
426                 return 0;
427         }
428
429         /* We accept an absolute path as first argument, or
430          * alternatively an absolute prefixed with @ to allow
431          * overriding of argv[0]. */
432         for (;;) {
433                 int i;
434                 char *w;
435                 size_t l;
436                 char *state;
437                 bool honour_argv0 = false, ignore = false;
438
439                 path = NULL;
440                 nce = NULL;
441                 n = NULL;
442
443                 rvalue += strspn(rvalue, WHITESPACE);
444
445                 if (rvalue[0] == 0)
446                         break;
447
448                 for (i = 0; i < 2; i++) {
449                         if (rvalue[0] == '-' && !ignore) {
450                                 ignore = true;
451                                 rvalue ++;
452                         }
453
454                         if (rvalue[0] == '@' && !honour_argv0) {
455                                 honour_argv0 = true;
456                                 rvalue ++;
457                         }
458                 }
459
460                 if (*rvalue != '/') {
461                         log_error("[%s:%u] Executable path is not absolute, ignoring: %s",
462                                   filename, line, rvalue);
463                         return 0;
464                 }
465
466                 k = 0;
467                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
468                         if (strneq(w, ";", MAX(l, 1U)))
469                                 break;
470
471                         k++;
472                 }
473
474                 n = new(char*, k + !honour_argv0);
475                 if (!n)
476                         return log_oom();
477
478                 k = 0;
479                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
480                         if (strneq(w, ";", MAX(l, 1U)))
481                                 break;
482                         else if (strneq(w, "\\;", MAX(l, 1U)))
483                                 w ++;
484
485                         if (honour_argv0 && w == rvalue) {
486                                 assert(!path);
487
488                                 path = strndup(w, l);
489                                 if (!path) {
490                                         r = log_oom();
491                                         goto fail;
492                                 }
493
494                                 if (!utf8_is_valid(path)) {
495                                         log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
496                                         r = 0;
497                                         goto fail;
498                                 }
499
500                         } else {
501                                 char *c;
502
503                                 c = n[k++] = cunescape_length(w, l);
504                                 if (!c) {
505                                         r = log_oom();
506                                         goto fail;
507                                 }
508
509                                 if (!utf8_is_valid(c)) {
510                                         log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
511                                         r = 0;
512                                         goto fail;
513                                 }
514                         }
515                 }
516
517                 n[k] = NULL;
518
519                 if (!n[0]) {
520                         log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue);
521                         r = 0;
522                         goto fail;
523                 }
524
525                 if (!path) {
526                         path = strdup(n[0]);
527                         if (!path) {
528                                 r = log_oom();
529                                 goto fail;
530                         }
531                 }
532
533                 assert(path_is_absolute(path));
534
535                 nce = new0(ExecCommand, 1);
536                 if (!nce) {
537                         r = log_oom();
538                         goto fail;
539                 }
540
541                 nce->argv = n;
542                 nce->path = path;
543                 nce->ignore = ignore;
544
545                 path_kill_slashes(nce->path);
546
547                 exec_command_append_list(e, nce);
548
549                 rvalue = state;
550         }
551
552         return 0;
553
554 fail:
555         n[k] = NULL;
556         strv_free(n);
557         free(path);
558         free(nce);
559
560         return r;
561 }
562
563 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
564 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
565
566 int config_parse_socket_bindtodevice(
567                 const char *filename,
568                 unsigned line,
569                 const char *section,
570                 const char *lvalue,
571                 int ltype,
572                 const char *rvalue,
573                 void *data,
574                 void *userdata) {
575
576         Socket *s = data;
577         char *n;
578
579         assert(filename);
580         assert(lvalue);
581         assert(rvalue);
582         assert(data);
583
584         if (rvalue[0] && !streq(rvalue, "*")) {
585                 n = strdup(rvalue);
586                 if (!n)
587                         return log_oom();
588         } else
589                 n = NULL;
590
591         free(s->bind_to_device);
592         s->bind_to_device = n;
593
594         return 0;
595 }
596
597 DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
598 DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
599
600 int config_parse_exec_io_class(
601                 const char *filename,
602                 unsigned line,
603                 const char *section,
604                 const char *lvalue,
605                 int ltype,
606                 const char *rvalue,
607                 void *data,
608                 void *userdata) {
609
610         ExecContext *c = data;
611         int x;
612
613         assert(filename);
614         assert(lvalue);
615         assert(rvalue);
616         assert(data);
617
618         x = ioprio_class_from_string(rvalue);
619         if (x < 0) {
620                 log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue);
621                 return 0;
622         }
623
624         c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
625         c->ioprio_set = true;
626
627         return 0;
628 }
629
630 int config_parse_exec_io_priority(
631                 const char *filename,
632                 unsigned line,
633                 const char *section,
634                 const char *lvalue,
635                 int ltype,
636                 const char *rvalue,
637                 void *data,
638                 void *userdata) {
639
640         ExecContext *c = data;
641         int i;
642
643         assert(filename);
644         assert(lvalue);
645         assert(rvalue);
646         assert(data);
647
648         if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) {
649                 log_error("[%s:%u] Failed to parse io priority, ignoring: %s", filename, line, rvalue);
650                 return 0;
651         }
652
653         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
654         c->ioprio_set = true;
655
656         return 0;
657 }
658
659 int config_parse_exec_cpu_sched_policy(
660                 const char *filename,
661                 unsigned line,
662                 const char *section,
663                 const char *lvalue,
664                 int ltype,
665                 const char *rvalue,
666                 void *data,
667                 void *userdata) {
668
669
670         ExecContext *c = data;
671         int x;
672
673         assert(filename);
674         assert(lvalue);
675         assert(rvalue);
676         assert(data);
677
678         x = sched_policy_from_string(rvalue);
679         if (x < 0) {
680                 log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue);
681                 return 0;
682         }
683
684         c->cpu_sched_policy = x;
685         /* Moving to or from real-time policy? We need to adjust the priority */
686         c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(x), sched_get_priority_max(x));
687         c->cpu_sched_set = true;
688
689         return 0;
690 }
691
692 int config_parse_exec_cpu_sched_prio(
693                 const char *filename,
694                 unsigned line,
695                 const char *section,
696                 const char *lvalue,
697                 int ltype,
698                 const char *rvalue,
699                 void *data,
700                 void *userdata) {
701
702         ExecContext *c = data;
703         int i, min, max;
704
705         assert(filename);
706         assert(lvalue);
707         assert(rvalue);
708         assert(data);
709
710         if (safe_atoi(rvalue, &i) < 0) {
711                 log_error("[%s:%u] Failed to parse CPU scheduling priority, ignoring: %s", filename, line, rvalue);
712                 return 0;
713         }
714
715         /* On Linux RR/FIFO range from 1 to 99 and OTHER/BATCH may only be 0 */
716         min = sched_get_priority_min(c->cpu_sched_policy);
717         max = sched_get_priority_max(c->cpu_sched_policy);
718
719         if (i < min || i > max) {
720                 log_error("[%s:%u] CPU scheduling priority is out of range, ignoring: %s", filename, line, rvalue);
721                 return 0;
722         }
723
724         c->cpu_sched_priority = i;
725         c->cpu_sched_set = true;
726
727         return 0;
728 }
729
730 int config_parse_exec_cpu_affinity(
731                 const char *filename,
732                 unsigned line,
733                 const char *section,
734                 const char *lvalue,
735                 int ltype,
736                 const char *rvalue,
737                 void *data,
738                 void *userdata) {
739
740         ExecContext *c = data;
741         char *w;
742         size_t l;
743         char *state;
744
745         assert(filename);
746         assert(lvalue);
747         assert(rvalue);
748         assert(data);
749
750         if (isempty(rvalue)) {
751                 /* An empty assignment resets the CPU list */
752                 if (c->cpuset)
753                         CPU_FREE(c->cpuset);
754                 c->cpuset = NULL;
755                 return 0;
756         }
757
758         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
759                 char _cleanup_free_ *t = NULL;
760                 int r;
761                 unsigned cpu;
762
763                 t = strndup(w, l);
764                 if (!t)
765                         return log_oom();
766
767                 r = safe_atou(t, &cpu);
768
769                 if (!c->cpuset) {
770                         c->cpuset = cpu_set_malloc(&c->cpuset_ncpus);
771                         if (!c->cpuset)
772                                 return log_oom();
773                 }
774
775                 if (r < 0 || cpu >= c->cpuset_ncpus) {
776                         log_error("[%s:%u] Failed to parse CPU affinity %s, ignoring: %s",
777                                   filename, line, t, rvalue);
778                         return 0;
779                 }
780
781                 CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
782         }
783
784         return 0;
785 }
786
787 int config_parse_exec_capabilities(
788                 const char *filename,
789                 unsigned line,
790                 const char *section,
791                 const char *lvalue,
792                 int ltype,
793                 const char *rvalue,
794                 void *data,
795                 void *userdata) {
796
797         ExecContext *c = data;
798         cap_t cap;
799
800         assert(filename);
801         assert(lvalue);
802         assert(rvalue);
803         assert(data);
804
805         cap = cap_from_text(rvalue);
806         if (!cap) {
807                 if (errno == ENOMEM)
808                         return log_oom();
809
810                 log_error("[%s:%u] Failed to parse capabilities, ignoring: %s", filename, line, rvalue);
811                 return 0;
812         }
813
814         if (c->capabilities)
815                 cap_free(c->capabilities);
816         c->capabilities = cap;
817
818         return 0;
819 }
820
821 int config_parse_exec_secure_bits(
822                 const char *filename,
823                 unsigned line,
824                 const char *section,
825                 const char *lvalue,
826                 int ltype,
827                 const char *rvalue,
828                 void *data,
829                 void *userdata) {
830
831         ExecContext *c = data;
832         char *w;
833         size_t l;
834         char *state;
835
836         assert(filename);
837         assert(lvalue);
838         assert(rvalue);
839         assert(data);
840
841         if (isempty(rvalue)) {
842                 /* An empty assignment resets the field */
843                 c->secure_bits = 0;
844                 return 0;
845         }
846
847         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
848                 if (first_word(w, "keep-caps"))
849                         c->secure_bits |= SECURE_KEEP_CAPS;
850                 else if (first_word(w, "keep-caps-locked"))
851                         c->secure_bits |= SECURE_KEEP_CAPS_LOCKED;
852                 else if (first_word(w, "no-setuid-fixup"))
853                         c->secure_bits |= SECURE_NO_SETUID_FIXUP;
854                 else if (first_word(w, "no-setuid-fixup-locked"))
855                         c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED;
856                 else if (first_word(w, "noroot"))
857                         c->secure_bits |= SECURE_NOROOT;
858                 else if (first_word(w, "noroot-locked"))
859                         c->secure_bits |= SECURE_NOROOT_LOCKED;
860                 else {
861                         log_error("[%s:%u] Failed to parse secure bits, ignoring: %s",
862                                   filename, line, rvalue);
863                         return 0;
864                 }
865         }
866
867         return 0;
868 }
869
870 int config_parse_bounding_set(
871                 const char *filename,
872                 unsigned line,
873                 const char *section,
874                 const char *lvalue,
875                 int ltype,
876                 const char *rvalue,
877                 void *data,
878                 void *userdata) {
879
880         uint64_t *capability_bounding_set_drop = data;
881         char *w;
882         size_t l;
883         char *state;
884         bool invert = false;
885         uint64_t sum = 0;
886
887         assert(filename);
888         assert(lvalue);
889         assert(rvalue);
890         assert(data);
891
892         if (isempty(rvalue)) {
893                 /* An empty assignment resets */
894                 *capability_bounding_set_drop = 0;
895                 return 0;
896         }
897
898         if (rvalue[0] == '~') {
899                 invert = true;
900                 rvalue++;
901         }
902
903         /* Note that we store this inverted internally, since the
904          * kernel wants it like this. But we actually expose it
905          * non-inverted everywhere to have a fully normalized
906          * interface. */
907
908         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
909                 char _cleanup_free_ *t = NULL;
910                 int r;
911                 cap_value_t cap;
912
913                 t = strndup(w, l);
914                 if (!t)
915                         return log_oom();
916
917                 r = cap_from_name(t, &cap);
918                 if (r < 0) {
919                         log_error("[%s:%u] Failed to parse capability in bounding set, ignoring: %s",
920                                   filename, line, t);
921                         continue;
922                 }
923
924                 sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
925         }
926
927         if (invert)
928                 *capability_bounding_set_drop |= sum;
929         else
930                 *capability_bounding_set_drop |= ~sum;
931
932         return 0;
933 }
934
935 int config_parse_limit(
936                 const char *filename,
937                 unsigned line,
938                 const char *section,
939                 const char *lvalue,
940                 int ltype,
941                 const char *rvalue,
942                 void *data,
943                 void *userdata) {
944
945         struct rlimit **rl = data;
946         unsigned long long u;
947
948         assert(filename);
949         assert(lvalue);
950         assert(rvalue);
951         assert(data);
952
953         rl += ltype;
954
955         if (streq(rvalue, "infinity"))
956                 u = (unsigned long long) RLIM_INFINITY;
957         else if (safe_atollu(rvalue, &u) < 0) {
958                 log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue);
959                 return 0;
960         }
961
962         if (!*rl) {
963                 *rl = new(struct rlimit, 1);
964                 if (!*rl)
965                         return log_oom();
966         }
967
968         (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
969         return 0;
970 }
971
972 int config_parse_unit_cgroup(
973                 const char *filename,
974                 unsigned line,
975                 const char *section,
976                 const char *lvalue,
977                 int ltype,
978                 const char *rvalue,
979                 void *data,
980                 void *userdata) {
981
982         Unit *u = userdata;
983         char *w;
984         size_t l;
985         char *state;
986
987         if (isempty(rvalue)) {
988                 /* An empty assignment resets the list */
989                 cgroup_bonding_free_list(u->cgroup_bondings, false);
990                 u->cgroup_bondings = NULL;
991                 return 0;
992         }
993
994         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
995                 char _cleanup_free_ *t = NULL, *k = NULL, *ku = NULL;
996                 int r;
997
998                 t = strndup(w, l);
999                 if (!t)
1000                         return log_oom();
1001
1002                 k = unit_full_printf(u, t);
1003                 if (!k)
1004                         log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
1005                                   filename, line, t);
1006
1007                 ku = cunescape(k ? k : t);
1008                 if (!ku)
1009                         return log_oom();
1010
1011                 r = unit_add_cgroup_from_text(u, ku, true, NULL);
1012                 if (r < 0) {
1013                         log_error("[%s:%u] Failed to parse cgroup value %s, ignoring: %s",
1014                                   filename, line, k, rvalue);
1015                         return 0;
1016                 }
1017         }
1018
1019         return 0;
1020 }
1021
1022 #ifdef HAVE_SYSV_COMPAT
1023 int config_parse_sysv_priority(
1024                 const char *filename,
1025                 unsigned line,
1026                 const char *section,
1027                 const char *lvalue,
1028                 int ltype,
1029                 const char *rvalue,
1030                 void *data,
1031                 void *userdata) {
1032
1033         int *priority = data;
1034         int i;
1035
1036         assert(filename);
1037         assert(lvalue);
1038         assert(rvalue);
1039         assert(data);
1040
1041         if (safe_atoi(rvalue, &i) < 0 || i < 0) {
1042                 log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue);
1043                 return 0;
1044         }
1045
1046         *priority = (int) i;
1047         return 0;
1048 }
1049 #endif
1050
1051 int config_parse_fsck_passno(
1052                 const char *filename,
1053                 unsigned line,
1054                 const char *section,
1055                 const char *lvalue,
1056                 int ltype,
1057                 const char *rvalue,
1058                 void *data,
1059                 void *userdata) {
1060
1061         int *passno = data;
1062         int i;
1063
1064         assert(filename);
1065         assert(lvalue);
1066         assert(rvalue);
1067         assert(data);
1068
1069         if (safe_atoi(rvalue, &i) || i < 0) {
1070                 log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue);
1071                 return 0;
1072         }
1073
1074         *passno = (int) i;
1075         return 0;
1076 }
1077
1078 DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
1079
1080 int config_parse_kill_signal(
1081                 const char *filename,
1082                 unsigned line,
1083                 const char *section,
1084                 const char *lvalue,
1085                 int ltype,
1086                 const char *rvalue,
1087                 void *data,
1088                 void *userdata) {
1089
1090         int *sig = data;
1091         int r;
1092
1093         assert(filename);
1094         assert(lvalue);
1095         assert(rvalue);
1096         assert(sig);
1097
1098         r = signal_from_string_try_harder(rvalue);
1099         if (r <= 0) {
1100                 log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue);
1101                 return 0;
1102         }
1103
1104         *sig = r;
1105         return 0;
1106 }
1107
1108 int config_parse_exec_mount_flags(
1109                 const char *filename,
1110                 unsigned line,
1111                 const char *section,
1112                 const char *lvalue,
1113                 int ltype,
1114                 const char *rvalue,
1115                 void *data,
1116                 void *userdata) {
1117
1118         ExecContext *c = data;
1119         char *w;
1120         size_t l;
1121         char *state;
1122         unsigned long flags = 0;
1123
1124         assert(filename);
1125         assert(lvalue);
1126         assert(rvalue);
1127         assert(data);
1128
1129         FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) {
1130                 char _cleanup_free_ *t;
1131
1132                 t = strndup(w, l);
1133                 if (!t)
1134                         return log_oom();
1135
1136                 if (streq(t, "shared"))
1137                         flags |= MS_SHARED;
1138                 else if (streq(t, "slave"))
1139                         flags |= MS_SLAVE;
1140                 else if (streq(w, "private"))
1141                         flags |= MS_PRIVATE;
1142                 else {
1143                         log_error("[%s:%u] Failed to parse mount flag %s, ignoring: %s",
1144                                   filename, line, t, rvalue);
1145                         return 0;
1146                 }
1147         }
1148
1149         c->mount_flags = flags;
1150         return 0;
1151 }
1152
1153 int config_parse_timer(
1154                 const char *filename,
1155                 unsigned line,
1156                 const char *section,
1157                 const char *lvalue,
1158                 int ltype,
1159                 const char *rvalue,
1160                 void *data,
1161                 void *userdata) {
1162
1163         Timer *t = data;
1164         usec_t u = 0;
1165         TimerValue *v;
1166         TimerBase b;
1167         CalendarSpec *c = NULL;
1168         clockid_t id;
1169
1170         assert(filename);
1171         assert(lvalue);
1172         assert(rvalue);
1173         assert(data);
1174
1175         if (isempty(rvalue)) {
1176                 /* Empty assignment resets list */
1177                 timer_free_values(t);
1178                 return 0;
1179         }
1180
1181         b = timer_base_from_string(lvalue);
1182         if (b < 0) {
1183                 log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue);
1184                 return 0;
1185         }
1186
1187         if (b == TIMER_CALENDAR) {
1188                 if (calendar_spec_from_string(rvalue, &c) < 0) {
1189                         log_error("[%s:%u] Failed to parse calendar specification, ignoring: %s", filename, line, rvalue);
1190                         return 0;
1191                 }
1192
1193                 id = CLOCK_REALTIME;
1194         } else {
1195                 if (parse_usec(rvalue, &u) < 0) {
1196                         log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue);
1197                         return 0;
1198                 }
1199
1200                 id = CLOCK_MONOTONIC;
1201         }
1202
1203         v = new0(TimerValue, 1);
1204         if (!v)
1205                 return log_oom();
1206
1207         v->base = b;
1208         v->clock_id = id;
1209         v->value = u;
1210         v->calendar_spec = c;
1211
1212         LIST_PREPEND(TimerValue, value, t->values, v);
1213
1214         return 0;
1215 }
1216
1217 int config_parse_timer_unit(
1218                 const char *filename,
1219                 unsigned line,
1220                 const char *section,
1221                 const char *lvalue,
1222                 int ltype,
1223                 const char *rvalue,
1224                 void *data,
1225                 void *userdata) {
1226
1227         Timer *t = data;
1228         int r;
1229         DBusError error;
1230         Unit *u;
1231         _cleanup_free_ char *p = NULL;
1232
1233         assert(filename);
1234         assert(lvalue);
1235         assert(rvalue);
1236         assert(data);
1237
1238         dbus_error_init(&error);
1239
1240         p = unit_name_printf(UNIT(t), rvalue);
1241         if (!p)
1242                 return log_oom();
1243
1244         if (endswith(p, ".timer")) {
1245                 log_error("[%s:%u] Unit cannot be of type timer, ignoring: %s", filename, line, rvalue);
1246                 return 0;
1247         }
1248
1249         r = manager_load_unit(UNIT(t)->manager, p, NULL, NULL, &u);
1250         if (r < 0) {
1251                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
1252                 dbus_error_free(&error);
1253                 return 0;
1254         }
1255
1256         unit_ref_set(&t->unit, u);
1257
1258         return 0;
1259 }
1260
1261 int config_parse_path_spec(
1262                 const char *filename,
1263                 unsigned line,
1264                 const char *section,
1265                 const char *lvalue,
1266                 int ltype,
1267                 const char *rvalue,
1268                 void *data,
1269                 void *userdata) {
1270
1271         Path *p = data;
1272         PathSpec *s;
1273         PathType b;
1274         char *k;
1275
1276         assert(filename);
1277         assert(lvalue);
1278         assert(rvalue);
1279         assert(data);
1280
1281         if (isempty(rvalue)) {
1282                 /* Empty assignment clears list */
1283                 path_free_specs(p);
1284                 return 0;
1285         }
1286
1287         b = path_type_from_string(lvalue);
1288         if (b < 0) {
1289                 log_error("[%s:%u] Failed to parse path type, ignoring: %s", filename, line, lvalue);
1290                 return 0;
1291         }
1292
1293         k = unit_full_printf(UNIT(p), rvalue);
1294         if (!k) {
1295                 k = strdup(rvalue);
1296                 if (!k)
1297                         return log_oom();
1298                 else
1299                         log_error("[%s:%u] Failed to resolve unit specifiers on %s. Ignoring.",
1300                                   filename, line, rvalue);
1301         }
1302
1303         if (!path_is_absolute(k)) {
1304                 log_error("[%s:%u] Path is not absolute, ignoring: %s", filename, line, k);
1305                 free(k);
1306                 return 0;
1307         }
1308
1309         s = new0(PathSpec, 1);
1310         if (!s) {
1311                 free(k);
1312                 return log_oom();
1313         }
1314
1315         s->path = path_kill_slashes(k);
1316         s->type = b;
1317         s->inotify_fd = -1;
1318
1319         LIST_PREPEND(PathSpec, spec, p->specs, s);
1320
1321         return 0;
1322 }
1323
1324 int config_parse_path_unit(
1325                 const char *filename,
1326                 unsigned line,
1327                 const char *section,
1328                 const char *lvalue,
1329                 int ltype,
1330                 const char *rvalue,
1331                 void *data,
1332                 void *userdata) {
1333
1334         Path *t = data;
1335         int r;
1336         DBusError error;
1337         Unit *u;
1338         _cleanup_free_ char *p = NULL;
1339
1340         assert(filename);
1341         assert(lvalue);
1342         assert(rvalue);
1343         assert(data);
1344
1345         dbus_error_init(&error);
1346
1347         p = unit_name_printf(UNIT(t), rvalue);
1348         if (!p)
1349                 return log_oom();
1350
1351         if (endswith(p, ".path")) {
1352                 log_error("[%s:%u] Unit cannot be of type path, ignoring: %s", filename, line, p);
1353                 return 0;
1354         }
1355
1356         r = manager_load_unit(UNIT(t)->manager, p, NULL, &error, &u);
1357         if (r < 0) {
1358                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, p, bus_error(&error, r));
1359                 dbus_error_free(&error);
1360                 return 0;
1361         }
1362
1363         unit_ref_set(&t->unit, u);
1364
1365         return 0;
1366 }
1367
1368 int config_parse_socket_service(
1369                 const char *filename,
1370                 unsigned line,
1371                 const char *section,
1372                 const char *lvalue,
1373                 int ltype,
1374                 const char *rvalue,
1375                 void *data,
1376                 void *userdata) {
1377
1378         Socket *s = data;
1379         int r;
1380         DBusError error;
1381         Unit *x;
1382         _cleanup_free_ char *p = NULL;
1383
1384         assert(filename);
1385         assert(lvalue);
1386         assert(rvalue);
1387         assert(data);
1388
1389         dbus_error_init(&error);
1390
1391         p = unit_name_printf(UNIT(s), rvalue);
1392         if (!p)
1393                 return log_oom();
1394
1395         if (!endswith(p, ".service")) {
1396                 log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue);
1397                 return 0;
1398         }
1399
1400         r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x);
1401         if (r < 0) {
1402                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
1403                 dbus_error_free(&error);
1404                 return 0;
1405         }
1406
1407         unit_ref_set(&s->service, x);
1408
1409         return 0;
1410 }
1411
1412 int config_parse_service_sockets(
1413                 const char *filename,
1414                 unsigned line,
1415                 const char *section,
1416                 const char *lvalue,
1417                 int ltype,
1418                 const char *rvalue,
1419                 void *data,
1420                 void *userdata) {
1421
1422         Service *s = data;
1423         int r;
1424         char *state, *w;
1425         size_t l;
1426
1427         assert(filename);
1428         assert(lvalue);
1429         assert(rvalue);
1430         assert(data);
1431
1432         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
1433                 char _cleanup_free_ *t = NULL, *k = NULL;
1434
1435                 t = strndup(w, l);
1436                 if (!t)
1437                         return log_oom();
1438
1439                 k = unit_name_printf(UNIT(s), t);
1440                 if (!k)
1441                         return log_oom();
1442
1443                 if (!endswith(k, ".socket")) {
1444                         log_error("[%s:%u] Unit must be of type socket, ignoring: %s",
1445                                   filename, line, k);
1446                         continue;
1447                 }
1448
1449                 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true);
1450                 if (r < 0)
1451                         log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s",
1452                                   filename, line, k, strerror(-r));
1453
1454                 r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true);
1455                 if (r < 0)
1456                         return r;
1457         }
1458
1459         return 0;
1460 }
1461
1462 int config_parse_service_timeout(
1463                 const char *filename,
1464                 unsigned line,
1465                 const char *section,
1466                 const char *lvalue,
1467                 int ltype,
1468                 const char *rvalue,
1469                 void *data,
1470                 void *userdata) {
1471
1472         Service *s = userdata;
1473         int r;
1474
1475         assert(filename);
1476         assert(lvalue);
1477         assert(rvalue);
1478         assert(s);
1479
1480         r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
1481         if (r < 0)
1482                 return r;
1483
1484         if (streq(lvalue, "TimeoutSec")) {
1485                 s->start_timeout_defined = true;
1486                 s->timeout_stop_usec = s->timeout_start_usec;
1487         } else if (streq(lvalue, "TimeoutStartSec"))
1488                 s->start_timeout_defined = true;
1489
1490         return 0;
1491 }
1492
1493 int config_parse_unit_env_file(
1494                 const char *filename,
1495                 unsigned line,
1496                 const char *section,
1497                 const char *lvalue,
1498                 int ltype,
1499                 const char *rvalue,
1500                 void *data,
1501                 void *userdata) {
1502
1503         char ***env = data;
1504         Unit *u = userdata;
1505         _cleanup_free_ char *s = NULL;
1506         int r;
1507
1508         assert(filename);
1509         assert(lvalue);
1510         assert(rvalue);
1511         assert(data);
1512
1513         if (isempty(rvalue)) {
1514                 /* Empty assignment frees the list */
1515                 strv_free(*env);
1516                 *env = NULL;
1517                 return 0;
1518         }
1519
1520         s = unit_full_printf(u, rvalue);
1521         if (!s)
1522                 return log_oom();
1523
1524         if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) {
1525                 log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s);
1526                 return 0;
1527         }
1528
1529         r = strv_extend(env, s);
1530         if (r < 0)
1531                 return log_oom();
1532
1533         return 0;
1534 }
1535
1536 int config_parse_environ(
1537                 const char *filename,
1538                 unsigned line,
1539                 const char *section,
1540                 const char *lvalue,
1541                 int ltype,
1542                 const char *rvalue,
1543                 void *data,
1544                 void *userdata) {
1545
1546         Unit *u = userdata;
1547         char*** env = data, *w, *state;
1548         size_t l;
1549         _cleanup_free_ char *k = NULL;
1550
1551         assert(filename);
1552         assert(lvalue);
1553         assert(rvalue);
1554         assert(u);
1555
1556         if (isempty(rvalue)) {
1557                 /* Empty assignment resets the list */
1558                 strv_free(*env);
1559                 *env = NULL;
1560                 return 0;
1561         }
1562
1563         k = unit_full_printf(u, rvalue);
1564         if (!k)
1565                 return log_oom();
1566
1567         FOREACH_WORD_QUOTED(w, l, k, state) {
1568                 _cleanup_free_ char *n;
1569                 char **x;
1570
1571                 n = cunescape_length(w, l);
1572                 if (!n)
1573                         return log_oom();
1574
1575                 if (!env_assignment_is_valid(n)) {
1576                         log_error("[%s:%u] Invalid environment assignment, ignoring: %s", filename, line, rvalue);
1577                         continue;
1578                 }
1579
1580                 x = strv_env_set(*env, n);
1581                 if (!x)
1582                         return log_oom();
1583
1584                 strv_free(*env);
1585                 *env = x;
1586         }
1587
1588         return 0;
1589 }
1590
1591 int config_parse_ip_tos(
1592                 const char *filename,
1593                 unsigned line,
1594                 const char *section,
1595                 const char *lvalue,
1596                 int ltype,
1597                 const char *rvalue,
1598                 void *data,
1599                 void *userdata) {
1600
1601         int *ip_tos = data, x;
1602
1603         assert(filename);
1604         assert(lvalue);
1605         assert(rvalue);
1606         assert(data);
1607
1608         x = ip_tos_from_string(rvalue);
1609         if (x < 0) {
1610                 log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue);
1611                 return 0;
1612         }
1613
1614         *ip_tos = x;
1615         return 0;
1616 }
1617
1618 int config_parse_unit_condition_path(
1619                 const char *filename,
1620                 unsigned line,
1621                 const char *section,
1622                 const char *lvalue,
1623                 int ltype,
1624                 const char *rvalue,
1625                 void *data,
1626                 void *userdata) {
1627
1628         ConditionType cond = ltype;
1629         Unit *u = data;
1630         bool trigger, negate;
1631         Condition *c;
1632         _cleanup_free_ char *p = NULL;
1633
1634         assert(filename);
1635         assert(lvalue);
1636         assert(rvalue);
1637         assert(data);
1638
1639         if (isempty(rvalue)) {
1640                 /* Empty assignment resets the list */
1641                 condition_free_list(u->conditions);
1642                 u->conditions = NULL;
1643                 return 0;
1644         }
1645
1646         trigger = rvalue[0] == '|';
1647         if (trigger)
1648                 rvalue++;
1649
1650         negate = rvalue[0] == '!';
1651         if (negate)
1652                 rvalue++;
1653
1654         p = unit_full_printf(u, rvalue);
1655         if (!p)
1656                 return log_oom();
1657
1658         if (!path_is_absolute(p)) {
1659                 log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, p);
1660                 return 0;
1661         }
1662
1663         c = condition_new(cond, p, trigger, negate);
1664         if (!c)
1665                 return log_oom();
1666
1667         LIST_PREPEND(Condition, conditions, u->conditions, c);
1668         return 0;
1669 }
1670
1671 int config_parse_unit_condition_string(
1672                 const char *filename,
1673                 unsigned line,
1674                 const char *section,
1675                 const char *lvalue,
1676                 int ltype,
1677                 const char *rvalue,
1678                 void *data,
1679                 void *userdata) {
1680
1681         ConditionType cond = ltype;
1682         Unit *u = data;
1683         bool trigger, negate;
1684         Condition *c;
1685         _cleanup_free_ char *s = NULL;
1686
1687         assert(filename);
1688         assert(lvalue);
1689         assert(rvalue);
1690         assert(data);
1691
1692         if (isempty(rvalue)) {
1693                 /* Empty assignment resets the list */
1694                 condition_free_list(u->conditions);
1695                 u->conditions = NULL;
1696                 return 0;
1697         }
1698
1699         trigger = rvalue[0] == '|';
1700         if (trigger)
1701                 rvalue++;
1702
1703         negate = rvalue[0] == '!';
1704         if (negate)
1705                 rvalue++;
1706
1707         s = unit_full_printf(u, rvalue);
1708         if (!s)
1709                 return log_oom();
1710
1711         c = condition_new(cond, s, trigger, negate);
1712         if (!c)
1713                 return log_oom();
1714
1715         LIST_PREPEND(Condition, conditions, u->conditions, c);
1716         return 0;
1717 }
1718
1719 int config_parse_unit_condition_null(
1720                 const char *filename,
1721                 unsigned line,
1722                 const char *section,
1723                 const char *lvalue,
1724                 int ltype,
1725                 const char *rvalue,
1726                 void *data,
1727                 void *userdata) {
1728
1729         Unit *u = data;
1730         Condition *c;
1731         bool trigger, negate;
1732         int b;
1733
1734         assert(filename);
1735         assert(lvalue);
1736         assert(rvalue);
1737         assert(data);
1738
1739         if (isempty(rvalue)) {
1740                 /* Empty assignment resets the list */
1741                 condition_free_list(u->conditions);
1742                 u->conditions = NULL;
1743                 return 0;
1744         }
1745
1746         trigger = rvalue[0] == '|';
1747         if (trigger)
1748                 rvalue++;
1749
1750         negate = rvalue[0] == '!';
1751         if (negate)
1752                 rvalue++;
1753
1754         b = parse_boolean(rvalue);
1755         if (b < 0) {
1756                 log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
1757                 return 0;
1758         }
1759
1760         if (!b)
1761                 negate = !negate;
1762
1763         c = condition_new(CONDITION_NULL, NULL, trigger, negate);
1764         if (!c)
1765                 return log_oom();
1766
1767         LIST_PREPEND(Condition, conditions, u->conditions, c);
1768         return 0;
1769 }
1770
1771 DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
1772 DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
1773
1774 int config_parse_unit_cgroup_attr(
1775                 const char *filename,
1776                 unsigned line,
1777                 const char *section,
1778                 const char *lvalue,
1779                 int ltype,
1780                 const char *rvalue,
1781                 void *data,
1782                 void *userdata) {
1783
1784         Unit *u = data;
1785         size_t a, b;
1786         _cleanup_free_ char *n = NULL, *v = NULL;
1787         const CGroupSemantics *s;
1788         int r;
1789
1790         assert(filename);
1791         assert(lvalue);
1792         assert(rvalue);
1793         assert(data);
1794
1795         if (isempty(rvalue)) {
1796                 /* Empty assignment clears the list */
1797                 cgroup_attribute_free_list(u->cgroup_attributes);
1798                 u->cgroup_attributes = NULL;
1799                 return 0;
1800         }
1801
1802         a = strcspn(rvalue, WHITESPACE);
1803         b = strspn(rvalue + a, WHITESPACE);
1804         if (a <= 0 || b <= 0) {
1805                 log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
1806                 return 0;
1807         }
1808
1809         n = strndup(rvalue, a);
1810         if (!n)
1811                 return log_oom();
1812
1813         r = cgroup_semantics_find(NULL, n, rvalue + a + b, &v, &s);
1814         if (r < 0) {
1815                 log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
1816                 return 0;
1817         }
1818
1819         r = unit_add_cgroup_attribute(u, s, NULL, n, v ? v : rvalue + a + b, NULL);
1820         if (r < 0) {
1821                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1822                 return 0;
1823         }
1824
1825         return 0;
1826 }
1827
1828 int config_parse_unit_cgroup_attr_pretty(
1829                 const char *filename,
1830                 unsigned line,
1831                 const char *section,
1832                 const char *lvalue,
1833                 int ltype,
1834                 const char *rvalue,
1835                 void *data,
1836                 void *userdata) {
1837
1838         Unit *u = data;
1839         _cleanup_free_ char *v = NULL;
1840         const CGroupSemantics *s;
1841         int r;
1842
1843         assert(filename);
1844         assert(lvalue);
1845         assert(rvalue);
1846         assert(data);
1847
1848         r = cgroup_semantics_find(NULL, lvalue, rvalue, &v, &s);
1849         if (r < 0) {
1850                 log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
1851                 return 0;
1852         } else if (r == 0) {
1853                 log_error("[%s:%u] Unknown or unsupported cgroup attribute %s, ignoring: %s", filename, line, lvalue, rvalue);
1854                 return 0;
1855         }
1856
1857         r = unit_add_cgroup_attribute(u, s, NULL, NULL, v, NULL);
1858         if (r < 0) {
1859                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1860                 return 0;
1861         }
1862
1863         return 0;
1864 }
1865
1866 int config_parse_unit_requires_mounts_for(
1867                 const char *filename,
1868                 unsigned line,
1869                 const char *section,
1870                 const char *lvalue,
1871                 int ltype,
1872                 const char *rvalue,
1873                 void *data,
1874                 void *userdata) {
1875
1876         Unit *u = userdata;
1877         int r;
1878         bool empty_before;
1879
1880         assert(filename);
1881         assert(lvalue);
1882         assert(rvalue);
1883         assert(data);
1884
1885         empty_before = !u->requires_mounts_for;
1886
1887         r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
1888
1889         /* Make it easy to find units with requires_mounts set */
1890         if (empty_before && u->requires_mounts_for)
1891                 LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
1892
1893         return r;
1894 }
1895
1896 int config_parse_documentation(
1897                 const char *filename,
1898                 unsigned line,
1899                 const char *section,
1900                 const char *lvalue,
1901                 int ltype,
1902                 const char *rvalue,
1903                 void *data,
1904                 void *userdata) {
1905
1906         Unit *u = userdata;
1907         int r;
1908         char **a, **b;
1909
1910         assert(filename);
1911         assert(lvalue);
1912         assert(rvalue);
1913         assert(u);
1914
1915         if (isempty(rvalue)) {
1916                 /* Empty assignment resets the list */
1917                 strv_free(u->documentation);
1918                 u->documentation = NULL;
1919                 return 0;
1920         }
1921
1922         r = config_parse_unit_strv_printf(filename, line, section, lvalue, ltype, rvalue, data, userdata);
1923         if (r < 0)
1924                 return r;
1925
1926         for (a = b = u->documentation; a && *a; a++) {
1927
1928                 if (is_valid_documentation_url(*a))
1929                         *(b++) = *a;
1930                 else {
1931                         log_error("[%s:%u] Invalid URL, ignoring: %s", filename, line, *a);
1932                         free(*a);
1933                 }
1934         }
1935         *b = NULL;
1936
1937         return r;
1938 }
1939
1940 static void syscall_set(uint32_t *p, int nr) {
1941         nr = SYSCALL_TO_INDEX(nr);
1942         p[nr >> 4] |= 1 << (nr & 31);
1943 }
1944
1945 static void syscall_unset(uint32_t *p, int nr) {
1946         nr = SYSCALL_TO_INDEX(nr);
1947         p[nr >> 4] &= ~(1 << (nr & 31));
1948 }
1949
1950 int config_parse_syscall_filter(
1951                 const char *filename,
1952                 unsigned line,
1953                 const char *section,
1954                 const char *lvalue,
1955                 int ltype,
1956                 const char *rvalue,
1957                 void *data,
1958                 void *userdata) {
1959
1960         ExecContext *c = data;
1961         Unit *u = userdata;
1962         bool invert = false;
1963         char *w;
1964         size_t l;
1965         char *state;
1966
1967         assert(filename);
1968         assert(lvalue);
1969         assert(rvalue);
1970         assert(u);
1971
1972         if (isempty(rvalue)) {
1973                 /* Empty assignment resets the list */
1974                 free(c->syscall_filter);
1975                 c->syscall_filter = NULL;
1976                 return 0;
1977         }
1978
1979         if (rvalue[0] == '~') {
1980                 invert = true;
1981                 rvalue++;
1982         }
1983
1984         if (!c->syscall_filter) {
1985                 size_t n;
1986
1987                 n = (syscall_max() + 31) >> 4;
1988                 c->syscall_filter = new(uint32_t, n);
1989                 if (!c->syscall_filter)
1990                         return log_oom();
1991
1992                 memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t));
1993
1994                 /* Add these by default */
1995                 syscall_set(c->syscall_filter, __NR_execve);
1996                 syscall_set(c->syscall_filter, __NR_rt_sigreturn);
1997 #ifdef __NR_sigreturn
1998                 syscall_set(c->syscall_filter, __NR_sigreturn);
1999 #endif
2000                 syscall_set(c->syscall_filter, __NR_exit_group);
2001                 syscall_set(c->syscall_filter, __NR_exit);
2002         }
2003
2004         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
2005                 int id;
2006                 char _cleanup_free_ *t = NULL;
2007
2008                 t = strndup(w, l);
2009                 if (!t)
2010                         return log_oom();
2011
2012                 id = syscall_from_name(t);
2013                 if (id < 0)  {
2014                         log_error("[%s:%u] Failed to parse syscall, ignoring: %s",
2015                                   filename, line, t);
2016                         continue;
2017                 }
2018
2019                 if (invert)
2020                         syscall_unset(c->syscall_filter, id);
2021                 else
2022                         syscall_set(c->syscall_filter, id);
2023         }
2024
2025         c->no_new_privileges = true;
2026
2027         return 0;
2028 }
2029
2030 #define FOLLOW_MAX 8
2031
2032 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
2033         unsigned c = 0;
2034         int fd, r;
2035         FILE *f;
2036         char *id = NULL;
2037
2038         assert(filename);
2039         assert(*filename);
2040         assert(_f);
2041         assert(names);
2042
2043         /* This will update the filename pointer if the loaded file is
2044          * reached by a symlink. The old string will be freed. */
2045
2046         for (;;) {
2047                 char *target, *name;
2048
2049                 if (c++ >= FOLLOW_MAX)
2050                         return -ELOOP;
2051
2052                 path_kill_slashes(*filename);
2053
2054                 /* Add the file name we are currently looking at to
2055                  * the names of this unit, but only if it is a valid
2056                  * unit name. */
2057                 name = path_get_file_name(*filename);
2058
2059                 if (unit_name_is_valid(name, true)) {
2060
2061                         id = set_get(names, name);
2062                         if (!id) {
2063                                 id = strdup(name);
2064                                 if (!id)
2065                                         return -ENOMEM;
2066
2067                                 r = set_put(names, id);
2068                                 if (r < 0) {
2069                                         free(id);
2070                                         return r;
2071                                 }
2072                         }
2073                 }
2074
2075                 /* Try to open the file name, but don't if its a symlink */
2076                 fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
2077                 if (fd >= 0)
2078                         break;
2079
2080                 if (errno != ELOOP)
2081                         return -errno;
2082
2083                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
2084                 r = readlink_and_make_absolute(*filename, &target);
2085                 if (r < 0)
2086                         return r;
2087
2088                 free(*filename);
2089                 *filename = target;
2090         }
2091
2092         f = fdopen(fd, "re");
2093         if (!f) {
2094                 r = -errno;
2095                 close_nointr_nofail(fd);
2096                 return r;
2097         }
2098
2099         *_f = f;
2100         *_final = id;
2101         return 0;
2102 }
2103
2104 static int merge_by_names(Unit **u, Set *names, const char *id) {
2105         char *k;
2106         int r;
2107
2108         assert(u);
2109         assert(*u);
2110         assert(names);
2111
2112         /* Let's try to add in all symlink names we found */
2113         while ((k = set_steal_first(names))) {
2114
2115                 /* First try to merge in the other name into our
2116                  * unit */
2117                 r = unit_merge_by_name(*u, k);
2118                 if (r < 0) {
2119                         Unit *other;
2120
2121                         /* Hmm, we couldn't merge the other unit into
2122                          * ours? Then let's try it the other way
2123                          * round */
2124
2125                         other = manager_get_unit((*u)->manager, k);
2126                         free(k);
2127
2128                         if (other) {
2129                                 r = unit_merge(other, *u);
2130                                 if (r >= 0) {
2131                                         *u = other;
2132                                         return merge_by_names(u, names, NULL);
2133                                 }
2134                         }
2135
2136                         return r;
2137                 }
2138
2139                 if (id == k)
2140                         unit_choose_id(*u, id);
2141
2142                 free(k);
2143         }
2144
2145         return 0;
2146 }
2147
2148 static int load_from_path(Unit *u, const char *path) {
2149         int r;
2150         Set *symlink_names;
2151         FILE *f = NULL;
2152         char *filename = NULL, *id = NULL;
2153         Unit *merged;
2154         struct stat st;
2155
2156         assert(u);
2157         assert(path);
2158
2159         symlink_names = set_new(string_hash_func, string_compare_func);
2160         if (!symlink_names)
2161                 return -ENOMEM;
2162
2163         if (path_is_absolute(path)) {
2164
2165                 filename = strdup(path);
2166                 if (!filename) {
2167                         r = -ENOMEM;
2168                         goto finish;
2169                 }
2170
2171                 r = open_follow(&filename, &f, symlink_names, &id);
2172                 if (r < 0) {
2173                         free(filename);
2174                         filename = NULL;
2175
2176                         if (r != -ENOENT)
2177                                 goto finish;
2178                 }
2179
2180         } else  {
2181                 char **p;
2182
2183                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
2184
2185                         /* Instead of opening the path right away, we manually
2186                          * follow all symlinks and add their name to our unit
2187                          * name set while doing so */
2188                         filename = path_make_absolute(path, *p);
2189                         if (!filename) {
2190                                 r = -ENOMEM;
2191                                 goto finish;
2192                         }
2193
2194                         if (u->manager->unit_path_cache &&
2195                             !set_get(u->manager->unit_path_cache, filename))
2196                                 r = -ENOENT;
2197                         else
2198                                 r = open_follow(&filename, &f, symlink_names, &id);
2199
2200                         if (r < 0) {
2201                                 free(filename);
2202                                 filename = NULL;
2203
2204                                 if (r != -ENOENT)
2205                                         goto finish;
2206
2207                                 /* Empty the symlink names for the next run */
2208                                 set_clear_free(symlink_names);
2209                                 continue;
2210                         }
2211
2212                         break;
2213                 }
2214         }
2215
2216         if (!filename) {
2217                 /* Hmm, no suitable file found? */
2218                 r = 0;
2219                 goto finish;
2220         }
2221
2222         merged = u;
2223         r = merge_by_names(&merged, symlink_names, id);
2224         if (r < 0)
2225                 goto finish;
2226
2227         if (merged != u) {
2228                 u->load_state = UNIT_MERGED;
2229                 r = 0;
2230                 goto finish;
2231         }
2232
2233         if (fstat(fileno(f), &st) < 0) {
2234                 r = -errno;
2235                 goto finish;
2236         }
2237
2238         if (null_or_empty(&st))
2239                 u->load_state = UNIT_MASKED;
2240         else {
2241                 /* Now, parse the file contents */
2242                 r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
2243                 if (r < 0)
2244                         goto finish;
2245
2246                 u->load_state = UNIT_LOADED;
2247         }
2248
2249         free(u->fragment_path);
2250         u->fragment_path = filename;
2251         filename = NULL;
2252
2253         u->fragment_mtime = timespec_load(&st.st_mtim);
2254
2255         if (u->source_path) {
2256                 if (stat(u->source_path, &st) >= 0)
2257                         u->source_mtime = timespec_load(&st.st_mtim);
2258                 else
2259                         u->source_mtime = 0;
2260         }
2261
2262         r = 0;
2263
2264 finish:
2265         set_free_free(symlink_names);
2266         free(filename);
2267
2268         if (f)
2269                 fclose(f);
2270
2271         return r;
2272 }
2273
2274 int unit_load_fragment(Unit *u) {
2275         int r;
2276         Iterator i;
2277         const char *t;
2278
2279         assert(u);
2280         assert(u->load_state == UNIT_STUB);
2281         assert(u->id);
2282
2283         /* First, try to find the unit under its id. We always look
2284          * for unit files in the default directories, to make it easy
2285          * to override things by placing things in /etc/systemd/system */
2286         r = load_from_path(u, u->id);
2287         if (r < 0)
2288                 return r;
2289
2290         /* Try to find an alias we can load this with */
2291         if (u->load_state == UNIT_STUB)
2292                 SET_FOREACH(t, u->names, i) {
2293
2294                         if (t == u->id)
2295                                 continue;
2296
2297                         r = load_from_path(u, t);
2298                         if (r < 0)
2299                                 return r;
2300
2301                         if (u->load_state != UNIT_STUB)
2302                                 break;
2303                 }
2304
2305         /* And now, try looking for it under the suggested (originally linked) path */
2306         if (u->load_state == UNIT_STUB && u->fragment_path) {
2307
2308                 r = load_from_path(u, u->fragment_path);
2309                 if (r < 0)
2310                         return r;
2311
2312                 if (u->load_state == UNIT_STUB) {
2313                         /* Hmm, this didn't work? Then let's get rid
2314                          * of the fragment path stored for us, so that
2315                          * we don't point to an invalid location. */
2316                         free(u->fragment_path);
2317                         u->fragment_path = NULL;
2318                 }
2319         }
2320
2321         /* Look for a template */
2322         if (u->load_state == UNIT_STUB && u->instance) {
2323                 char *k;
2324
2325                 k = unit_name_template(u->id);
2326                 if (!k)
2327                         return -ENOMEM;
2328
2329                 r = load_from_path(u, k);
2330                 free(k);
2331
2332                 if (r < 0)
2333                         return r;
2334
2335                 if (u->load_state == UNIT_STUB)
2336                         SET_FOREACH(t, u->names, i) {
2337
2338                                 if (t == u->id)
2339                                         continue;
2340
2341                                 k = unit_name_template(t);
2342                                 if (!k)
2343                                         return -ENOMEM;
2344
2345                                 r = load_from_path(u, k);
2346                                 free(k);
2347
2348                                 if (r < 0)
2349                                         return r;
2350
2351                                 if (u->load_state != UNIT_STUB)
2352                                         break;
2353                         }
2354         }
2355
2356         return 0;
2357 }
2358
2359 void unit_dump_config_items(FILE *f) {
2360         static const struct {
2361                 const ConfigParserCallback callback;
2362                 const char *rvalue;
2363         } table[] = {
2364                 { config_parse_int,                   "INTEGER" },
2365                 { config_parse_unsigned,              "UNSIGNED" },
2366                 { config_parse_bytes_size,            "SIZE" },
2367                 { config_parse_bool,                  "BOOLEAN" },
2368                 { config_parse_string,                "STRING" },
2369                 { config_parse_path,                  "PATH" },
2370                 { config_parse_unit_path_printf,      "PATH" },
2371                 { config_parse_strv,                  "STRING [...]" },
2372                 { config_parse_exec_nice,             "NICE" },
2373                 { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
2374                 { config_parse_exec_io_class,         "IOCLASS" },
2375                 { config_parse_exec_io_priority,      "IOPRIORITY" },
2376                 { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
2377                 { config_parse_exec_cpu_sched_prio,   "CPUSCHEDPRIO" },
2378                 { config_parse_exec_cpu_affinity,     "CPUAFFINITY" },
2379                 { config_parse_mode,                  "MODE" },
2380                 { config_parse_unit_env_file,         "FILE" },
2381                 { config_parse_output,                "OUTPUT" },
2382                 { config_parse_input,                 "INPUT" },
2383                 { config_parse_facility,              "FACILITY" },
2384                 { config_parse_level,                 "LEVEL" },
2385                 { config_parse_exec_capabilities,     "CAPABILITIES" },
2386                 { config_parse_exec_secure_bits,      "SECUREBITS" },
2387                 { config_parse_bounding_set,          "BOUNDINGSET" },
2388                 { config_parse_limit,                 "LIMIT" },
2389                 { config_parse_unit_cgroup,           "CGROUP [...]" },
2390                 { config_parse_unit_deps,             "UNIT [...]" },
2391                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
2392                 { config_parse_service_type,          "SERVICETYPE" },
2393                 { config_parse_service_restart,       "SERVICERESTART" },
2394 #ifdef HAVE_SYSV_COMPAT
2395                 { config_parse_sysv_priority,         "SYSVPRIORITY" },
2396 #else
2397                 { config_parse_warn_compat,           "NOTSUPPORTED" },
2398 #endif
2399                 { config_parse_kill_mode,             "KILLMODE" },
2400                 { config_parse_kill_signal,           "SIGNAL" },
2401                 { config_parse_socket_listen,         "SOCKET [...]" },
2402                 { config_parse_socket_bind,           "SOCKETBIND" },
2403                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
2404                 { config_parse_usec,                  "SECONDS" },
2405                 { config_parse_nsec,                  "NANOSECONDS" },
2406                 { config_parse_path_strv,             "PATH [...]" },
2407                 { config_parse_unit_requires_mounts_for, "PATH [...]" },
2408                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
2409                 { config_parse_unit_string_printf,    "STRING" },
2410                 { config_parse_timer,                 "TIMER" },
2411                 { config_parse_timer_unit,            "NAME" },
2412                 { config_parse_path_spec,             "PATH" },
2413                 { config_parse_path_unit,             "UNIT" },
2414                 { config_parse_notify_access,         "ACCESS" },
2415                 { config_parse_ip_tos,                "TOS" },
2416                 { config_parse_unit_condition_path,   "CONDITION" },
2417                 { config_parse_unit_condition_string, "CONDITION" },
2418                 { config_parse_unit_condition_null,   "CONDITION" },
2419         };
2420
2421         const char *prev = NULL;
2422         const char *i;
2423
2424         assert(f);
2425
2426         NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
2427                 const char *rvalue = "OTHER", *lvalue;
2428                 unsigned j;
2429                 size_t prefix_len;
2430                 const char *dot;
2431                 const ConfigPerfItem *p;
2432
2433                 assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
2434
2435                 dot = strchr(i, '.');
2436                 lvalue = dot ? dot + 1 : i;
2437                 prefix_len = dot-i;
2438
2439                 if (dot)
2440                         if (!prev || !strneq(prev, i, prefix_len+1)) {
2441                                 if (prev)
2442                                         fputc('\n', f);
2443
2444                                 fprintf(f, "[%.*s]\n", (int) prefix_len, i);
2445                         }
2446
2447                 for (j = 0; j < ELEMENTSOF(table); j++)
2448                         if (p->parse == table[j].callback) {
2449                                 rvalue = table[j].rvalue;
2450                                 break;
2451                         }
2452
2453                 fprintf(f, "%s=%s\n", lvalue, rvalue);
2454                 prev = i;
2455         }
2456 }