xref: /freebsd/usr.sbin/jail/jailparse.y (revision 097db30a8e0310ac28075787fb92ea40dad8b27b)
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 <stdlib.h>
34 #include <string.h>
35 
36 #include "jailp.h"
37 
38 #ifdef DEBUG
39 #define YYDEBUG 1
40 #endif
41 
42 static struct cfjail *current_jail;
43 static struct cfjail *global_jail;
44 %}
45 
46 %union {
47 	struct cfparam		*p;
48 	struct cfstrings	*ss;
49 	struct cfstring		*s;
50 	char			*cs;
51 }
52 
53 %token      PLEQ
54 %token <cs> STR STR1 VAR VAR1
55 
56 %type <p>  param name
57 %type <ss> value
58 %type <s>  string
59 
60 %%
61 
62 /*
63  * A config file is a list of jails and parameters.  Parameters are
64  * added to the current jail, otherwise to a global pesudo-jail.
65  */
66 conf	:
67 	| conf jail
68 	| conf param ';'
69 	{
70 		struct cfjail *j = current_jail;
71 
72 		if (j == NULL) {
73 			if (global_jail == NULL) {
74 				global_jail = add_jail();
75 				global_jail->name = estrdup("*");
76 			}
77 			j = global_jail;
78 		}
79 		TAILQ_INSERT_TAIL(&j->params, $2, tq);
80 	}
81 	| conf ';'
82 	;
83 
84 jail	: jail_name '{' conf '}'
85 	{
86 		current_jail = current_jail->cfparent;
87 	}
88 	;
89 
90 jail_name : STR
91 	{
92 		struct cfjail *j = add_jail();
93 
94 		if (current_jail == NULL)
95 			j->name = $1;
96 		else {
97 			/*
98 			 * A nested jail definition becomes
99 			 * a hierarchically-named sub-jail.
100 			 */
101 			size_t parentlen = strlen(current_jail->name);
102 			j->name = emalloc(parentlen + strlen($1) + 2);
103 			strcpy(j->name, current_jail->name);
104 			j->name[parentlen++] = '.';
105 			strcpy(j->name + parentlen, $1);
106 			free($1);
107 		}
108 		j->cfparent = current_jail;
109 		current_jail = j;
110 	}
111 	;
112 
113 /*
114  * Parameters have a name and an optional list of value strings,
115  * which may have "+=" or "=" preceding them.
116  */
117 param	: name
118 	{
119 		$$ = $1;
120 	}
121 	| name '=' value
122 	{
123 		$$ = $1;
124 		TAILQ_CONCAT(&$$->val, $3, tq);
125 		free($3);
126 	}
127 	| name PLEQ value
128 	{
129 		$$ = $1;
130 		TAILQ_CONCAT(&$$->val, $3, tq);
131 		$$->flags |= PF_APPEND;
132 		free($3);
133 	}
134 	| name value
135 	{
136 		$$ = $1;
137 		TAILQ_CONCAT(&$$->val, $2, tq);
138 		free($2);
139 	}
140 	| error
141 	;
142 
143 /*
144  * A parameter has a fixed name.  A variable definition looks just like a
145  * parameter except that the name is a variable.
146  */
147 name	: STR
148 	{
149 		$$ = emalloc(sizeof(struct cfparam));
150 		$$->name = $1;
151 		TAILQ_INIT(&$$->val);
152 		$$->flags = 0;
153 	}
154 	| VAR
155 	{
156 		$$ = emalloc(sizeof(struct cfparam));
157 		$$->name = $1;
158 		TAILQ_INIT(&$$->val);
159 		$$->flags = PF_VAR;
160 	}
161 	;
162 
163 value	: string
164 	{
165 		$$ = emalloc(sizeof(struct cfstrings));
166 		TAILQ_INIT($$);
167 		TAILQ_INSERT_TAIL($$, $1, tq);
168 	}
169 	| value ',' string
170 	{
171 		$$ = $1;
172 		TAILQ_INSERT_TAIL($$, $3, tq);
173 	}
174 	;
175 
176 /*
177  * Strings may be passed in pieces, because of quoting and/or variable
178  * interpolation.  Reassemble them into a single string.
179  */
180 string	: STR
181 	{
182 		$$ = emalloc(sizeof(struct cfstring));
183 		$$->s = $1;
184 		$$->len = strlen($1);
185 		STAILQ_INIT(&$$->vars);
186 	}
187 	| VAR
188 	{
189 		struct cfvar *v;
190 
191 		$$ = emalloc(sizeof(struct cfstring));
192 		$$->s = estrdup("");
193 		$$->len = 0;
194 		STAILQ_INIT(&$$->vars);
195 		v = emalloc(sizeof(struct cfvar));
196 		v->name = $1;
197 		v->pos = 0;
198 		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
199 	}
200 	| string STR1
201 	{
202 		size_t len1;
203 
204 		$$ = $1;
205 		len1 = strlen($2);
206 		$$->s = erealloc($$->s, $$->len + len1 + 1);
207 		strcpy($$->s + $$->len, $2);
208 		free($2);
209 		$$->len += len1;
210 	}
211 	| string VAR1
212 	{
213 		struct cfvar *v;
214 
215 		$$ = $1;
216 		v = emalloc(sizeof(struct cfvar));
217 		v->name = $2;
218 		v->pos = $$->len;
219 		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
220 	}
221 	;
222 
223 %%
224