]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/jail/jailparse.y
Merge OpenSSL 3.0.9
[FreeBSD/FreeBSD.git] / usr.sbin / jail / jailparse.y
1 %{
2 /*-
3  * SPDX-License-Identifier: BSD-2-Clause
4  *
5  * Copyright (c) 2011 James Gritton
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <err.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "jailp.h"
38
39 #ifdef DEBUG
40 #define YYDEBUG 1
41 #endif
42
43 static struct cfjail *current_jail;
44 static struct cfjail *global_jail;
45 %}
46
47 %union {
48         struct cfparam          *p;
49         struct cfstrings        *ss;
50         struct cfstring         *s;
51         char                    *cs;
52 }
53
54 %token      PLEQ
55 %token <cs> STR STR1 VAR VAR1
56
57 %type <p>  param name
58 %type <ss> value
59 %type <s>  string
60
61 %pure-parser
62
63 %lex-param { void *scanner }
64 %parse-param { void *scanner }
65
66 %%
67
68 /*
69  * A config file is a list of jails and parameters.  Parameters are
70  * added to the current jail, otherwise to a global pesudo-jail.
71  */
72 conf    :
73         | conf jail
74         | conf param ';'
75         {
76                 if (!special_param($2, scanner)) {
77                         struct cfjail *j = current_jail;
78
79                         if (j == NULL) {
80                                 if (global_jail == NULL) {
81                                         global_jail = add_jail();
82                                         global_jail->name = estrdup("*");
83                                 }
84                                 j = global_jail;
85                         }
86                         TAILQ_INSERT_TAIL(&j->params, $2, tq);
87                 }
88         }
89         | conf ';'
90         ;
91
92 jail    : jail_name '{' conf '}'
93         {
94                 current_jail = current_jail->cfparent;
95         }
96         ;
97
98 jail_name : STR
99         {
100                 struct cfjail *j = add_jail();
101
102                 if (current_jail == NULL)
103                         j->name = $1;
104                 else {
105                         /*
106                          * A nested jail definition becomes
107                          * a hierarchically-named sub-jail.
108                          */
109                         size_t parentlen = strlen(current_jail->name);
110                         j->name = emalloc(parentlen + strlen($1) + 2);
111                         strcpy(j->name, current_jail->name);
112                         j->name[parentlen++] = '.';
113                         strcpy(j->name + parentlen, $1);
114                         free($1);
115                 }
116                 j->cfparent = current_jail;
117                 current_jail = j;
118         }
119         ;
120
121 /*
122  * Parameters have a name and an optional list of value strings,
123  * which may have "+=" or "=" preceding them.
124  */
125 param   : name
126         {
127                 $$ = $1;
128         }
129         | name '=' value
130         {
131                 $$ = $1;
132                 TAILQ_CONCAT(&$$->val, $3, tq);
133                 free($3);
134         }
135         | name PLEQ value
136         {
137                 $$ = $1;
138                 TAILQ_CONCAT(&$$->val, $3, tq);
139                 $$->flags |= PF_APPEND;
140                 free($3);
141         }
142         | name value
143         {
144                 $$ = $1;
145                 TAILQ_CONCAT(&$$->val, $2, tq);
146                 $$->flags |= PF_NAMEVAL;
147                 free($2);
148         }
149         | error
150         ;
151
152 /*
153  * A parameter has a fixed name.  A variable definition looks just like a
154  * parameter except that the name is a variable.
155  */
156 name    : STR
157         {
158                 $$ = emalloc(sizeof(struct cfparam));
159                 $$->name = $1;
160                 TAILQ_INIT(&$$->val);
161                 $$->flags = 0;
162         }
163         | VAR
164         {
165                 $$ = emalloc(sizeof(struct cfparam));
166                 $$->name = $1;
167                 TAILQ_INIT(&$$->val);
168                 $$->flags = PF_VAR;
169         }
170         ;
171
172 value   : string
173         {
174                 $$ = emalloc(sizeof(struct cfstrings));
175                 TAILQ_INIT($$);
176                 TAILQ_INSERT_TAIL($$, $1, tq);
177         }
178         | value ',' string
179         {
180                 $$ = $1;
181                 TAILQ_INSERT_TAIL($$, $3, tq);
182         }
183         ;
184
185 /*
186  * Strings may be passed in pieces, because of quoting and/or variable
187  * interpolation.  Reassemble them into a single string.
188  */
189 string  : STR
190         {
191                 $$ = emalloc(sizeof(struct cfstring));
192                 $$->s = $1;
193                 $$->len = strlen($1);
194                 STAILQ_INIT(&$$->vars);
195         }
196         | VAR
197         {
198                 struct cfvar *v;
199
200                 $$ = emalloc(sizeof(struct cfstring));
201                 $$->s = estrdup("");
202                 $$->len = 0;
203                 STAILQ_INIT(&$$->vars);
204                 v = emalloc(sizeof(struct cfvar));
205                 v->name = $1;
206                 v->pos = 0;
207                 STAILQ_INSERT_TAIL(&$$->vars, v, tq);
208         }
209         | string STR1
210         {
211                 size_t len1;
212
213                 $$ = $1;
214                 len1 = strlen($2);
215                 $$->s = erealloc($$->s, $$->len + len1 + 1);
216                 strcpy($$->s + $$->len, $2);
217                 free($2);
218                 $$->len += len1;
219         }
220         | string VAR1
221         {
222                 struct cfvar *v;
223
224                 $$ = $1;
225                 v = emalloc(sizeof(struct cfvar));
226                 v->name = $2;
227                 v->pos = $$->len;
228                 STAILQ_INSERT_TAIL(&$$->vars, v, tq);
229         }
230         ;
231
232 %%
233
234 extern int YYLEX_DECL();
235
236 static void
237 YYERROR_DECL()
238 {
239         if (!yyget_text(scanner))
240                 warnx("%s line %d: %s",
241                     yyget_extra(scanner)->cfname, yyget_lineno(scanner), s);
242         else if (!yyget_text(scanner)[0])
243                 warnx("%s: unexpected EOF",
244                     yyget_extra(scanner)->cfname);
245         else
246                 warnx("%s line %d: %s: %s",
247                     yyget_extra(scanner)->cfname, yyget_lineno(scanner),
248                     yyget_text(scanner), s);
249 }
250
251 /* Handle special parameters (i.e. the include directive).
252  * Return true if the parameter was specially handled.
253  */
254 static int
255 special_param(struct cfparam *p, void *scanner)
256 {
257         if ((p->flags & (PF_VAR | PF_APPEND | PF_NAMEVAL)) != PF_NAMEVAL
258             || strcmp(p->name, ".include"))
259                 return 0;
260         struct cfstring *s;
261         TAILQ_FOREACH(s, &p->val, tq) {
262                 if (STAILQ_EMPTY(&s->vars))
263                         include_config(scanner, s->s);
264                 else {
265                         warnx("%s line %d: "
266                             "variables not permitted in '.include' filename",
267                             yyget_extra(scanner)->cfname,
268                             yyget_lineno(scanner));
269                         yyget_extra(scanner)->error = 1;
270                 }
271         }
272         free_param_strings(p);
273         free(p);
274         return 1;
275 }