xref: /freebsd/usr.sbin/jail/jailparse.y (revision 768149ff)
12671ee73SJamie Gritton %{
22671ee73SJamie Gritton /*-
34d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
41de7b4b8SPedro F. Giffuni  *
5d8352076SJamie Gritton  * Copyright (c) 2011 James Gritton
62671ee73SJamie Gritton  * All rights reserved.
72671ee73SJamie Gritton  *
82671ee73SJamie Gritton  * Redistribution and use in source and binary forms, with or without
92671ee73SJamie Gritton  * modification, are permitted provided that the following conditions
102671ee73SJamie Gritton  * are met:
112671ee73SJamie Gritton  * 1. Redistributions of source code must retain the above copyright
122671ee73SJamie Gritton  *    notice, this list of conditions and the following disclaimer.
132671ee73SJamie Gritton  * 2. Redistributions in binary form must reproduce the above copyright
142671ee73SJamie Gritton  *    notice, this list of conditions and the following disclaimer in the
152671ee73SJamie Gritton  *    documentation and/or other materials provided with the distribution.
162671ee73SJamie Gritton  *
172671ee73SJamie Gritton  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
182671ee73SJamie Gritton  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192671ee73SJamie Gritton  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
202671ee73SJamie Gritton  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
212671ee73SJamie Gritton  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
222671ee73SJamie Gritton  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232671ee73SJamie Gritton  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242671ee73SJamie Gritton  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252671ee73SJamie Gritton  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262671ee73SJamie Gritton  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
272671ee73SJamie Gritton  * SUCH DAMAGE.
282671ee73SJamie Gritton  */
292671ee73SJamie Gritton 
302671ee73SJamie Gritton #include <sys/cdefs.h>
31086e0149SJamie Gritton #include <err.h>
322671ee73SJamie Gritton #include <stdlib.h>
332671ee73SJamie Gritton #include <string.h>
342671ee73SJamie Gritton 
352671ee73SJamie Gritton #include "jailp.h"
362671ee73SJamie Gritton 
372671ee73SJamie Gritton #ifdef DEBUG
382671ee73SJamie Gritton #define YYDEBUG 1
392671ee73SJamie Gritton #endif
40097db30aSJamie Gritton 
41097db30aSJamie Gritton static struct cfjail *current_jail;
42097db30aSJamie Gritton static struct cfjail *global_jail;
432671ee73SJamie Gritton %}
442671ee73SJamie Gritton 
452671ee73SJamie Gritton %union {
462671ee73SJamie Gritton 	struct cfparam		*p;
472671ee73SJamie Gritton 	struct cfstrings	*ss;
482671ee73SJamie Gritton 	struct cfstring		*s;
492671ee73SJamie Gritton 	char			*cs;
502671ee73SJamie Gritton }
512671ee73SJamie Gritton 
522671ee73SJamie Gritton %token      PLEQ
532671ee73SJamie Gritton %token <cs> STR STR1 VAR VAR1
542671ee73SJamie Gritton 
552671ee73SJamie Gritton %type <p>  param name
562671ee73SJamie Gritton %type <ss> value
572671ee73SJamie Gritton %type <s>  string
582671ee73SJamie Gritton 
59086e0149SJamie Gritton %pure-parser
60086e0149SJamie Gritton 
61086e0149SJamie Gritton %lex-param { void *scanner }
62086e0149SJamie Gritton %parse-param { void *scanner }
63086e0149SJamie Gritton 
642671ee73SJamie Gritton %%
652671ee73SJamie Gritton 
662671ee73SJamie Gritton /*
67097db30aSJamie Gritton  * A config file is a list of jails and parameters.  Parameters are
68097db30aSJamie Gritton  * added to the current jail, otherwise to a global pesudo-jail.
692671ee73SJamie Gritton  */
702671ee73SJamie Gritton conf	:
712671ee73SJamie Gritton 	| conf jail
722671ee73SJamie Gritton 	| conf param ';'
732671ee73SJamie Gritton 	{
74e82a6294SJamie Gritton 		if (!special_param($2, scanner)) {
75097db30aSJamie Gritton 			struct cfjail *j = current_jail;
762671ee73SJamie Gritton 
77097db30aSJamie Gritton 			if (j == NULL) {
78097db30aSJamie Gritton 				if (global_jail == NULL) {
79097db30aSJamie Gritton 					global_jail = add_jail();
80097db30aSJamie Gritton 					global_jail->name = estrdup("*");
81097db30aSJamie Gritton 				}
82097db30aSJamie Gritton 				j = global_jail;
832671ee73SJamie Gritton 			}
842671ee73SJamie Gritton 			TAILQ_INSERT_TAIL(&j->params, $2, tq);
852671ee73SJamie Gritton 		}
86e82a6294SJamie Gritton 	}
872671ee73SJamie Gritton 	| conf ';'
88097db30aSJamie Gritton 	;
892671ee73SJamie Gritton 
90097db30aSJamie Gritton jail	: jail_name '{' conf '}'
912671ee73SJamie Gritton 	{
92097db30aSJamie Gritton 		current_jail = current_jail->cfparent;
932671ee73SJamie Gritton 	}
942671ee73SJamie Gritton 	;
952671ee73SJamie Gritton 
96097db30aSJamie Gritton jail_name : STR
972671ee73SJamie Gritton 	{
98097db30aSJamie Gritton 		struct cfjail *j = add_jail();
99097db30aSJamie Gritton 
100097db30aSJamie Gritton 		if (current_jail == NULL)
101097db30aSJamie Gritton 			j->name = $1;
102097db30aSJamie Gritton 		else {
103097db30aSJamie Gritton 			/*
104097db30aSJamie Gritton 			 * A nested jail definition becomes
105097db30aSJamie Gritton 			 * a hierarchically-named sub-jail.
106097db30aSJamie Gritton 			 */
107097db30aSJamie Gritton 			size_t parentlen = strlen(current_jail->name);
108097db30aSJamie Gritton 			j->name = emalloc(parentlen + strlen($1) + 2);
109097db30aSJamie Gritton 			strcpy(j->name, current_jail->name);
110097db30aSJamie Gritton 			j->name[parentlen++] = '.';
111097db30aSJamie Gritton 			strcpy(j->name + parentlen, $1);
112097db30aSJamie Gritton 			free($1);
1132671ee73SJamie Gritton 		}
114097db30aSJamie Gritton 		j->cfparent = current_jail;
115097db30aSJamie Gritton 		current_jail = j;
1162671ee73SJamie Gritton 	}
1172671ee73SJamie Gritton 	;
1182671ee73SJamie Gritton 
1192671ee73SJamie Gritton /*
1202671ee73SJamie Gritton  * Parameters have a name and an optional list of value strings,
121463a577bSEitan Adler  * which may have "+=" or "=" preceding them.
1222671ee73SJamie Gritton  */
1232671ee73SJamie Gritton param	: name
1242671ee73SJamie Gritton 	{
1252671ee73SJamie Gritton 		$$ = $1;
1262671ee73SJamie Gritton 	}
1272671ee73SJamie Gritton 	| name '=' value
1282671ee73SJamie Gritton 	{
1292671ee73SJamie Gritton 		$$ = $1;
1302a194551SJamie Gritton 		TAILQ_CONCAT(&$$->val, $3, tq);
1312671ee73SJamie Gritton 		free($3);
1322671ee73SJamie Gritton 	}
1332671ee73SJamie Gritton 	| name PLEQ value
1342671ee73SJamie Gritton 	{
1352671ee73SJamie Gritton 		$$ = $1;
1362a194551SJamie Gritton 		TAILQ_CONCAT(&$$->val, $3, tq);
1372671ee73SJamie Gritton 		$$->flags |= PF_APPEND;
1382671ee73SJamie Gritton 		free($3);
1392671ee73SJamie Gritton 	}
1402671ee73SJamie Gritton 	| name value
1412671ee73SJamie Gritton 	{
1422671ee73SJamie Gritton 		$$ = $1;
1432a194551SJamie Gritton 		TAILQ_CONCAT(&$$->val, $2, tq);
144e82a6294SJamie Gritton 		$$->flags |= PF_NAMEVAL;
1452671ee73SJamie Gritton 		free($2);
1462671ee73SJamie Gritton 	}
1472671ee73SJamie Gritton 	| error
1482671ee73SJamie Gritton 	;
1492671ee73SJamie Gritton 
1502671ee73SJamie Gritton /*
1512671ee73SJamie Gritton  * A parameter has a fixed name.  A variable definition looks just like a
1522671ee73SJamie Gritton  * parameter except that the name is a variable.
1532671ee73SJamie Gritton  */
1542671ee73SJamie Gritton name	: STR
1552671ee73SJamie Gritton 	{
1562671ee73SJamie Gritton 		$$ = emalloc(sizeof(struct cfparam));
1572671ee73SJamie Gritton 		$$->name = $1;
1582a194551SJamie Gritton 		TAILQ_INIT(&$$->val);
1592671ee73SJamie Gritton 		$$->flags = 0;
1602671ee73SJamie Gritton 	}
1612671ee73SJamie Gritton 	| VAR
1622671ee73SJamie Gritton 	{
1632671ee73SJamie Gritton 		$$ = emalloc(sizeof(struct cfparam));
1642671ee73SJamie Gritton 		$$->name = $1;
1652a194551SJamie Gritton 		TAILQ_INIT(&$$->val);
1662671ee73SJamie Gritton 		$$->flags = PF_VAR;
1672671ee73SJamie Gritton 	}
1682671ee73SJamie Gritton 	;
1692671ee73SJamie Gritton 
1702671ee73SJamie Gritton value	: string
1712671ee73SJamie Gritton 	{
1722671ee73SJamie Gritton 		$$ = emalloc(sizeof(struct cfstrings));
1732a194551SJamie Gritton 		TAILQ_INIT($$);
1742a194551SJamie Gritton 		TAILQ_INSERT_TAIL($$, $1, tq);
1752671ee73SJamie Gritton 	}
1762671ee73SJamie Gritton 	| value ',' string
1772671ee73SJamie Gritton 	{
1782671ee73SJamie Gritton 		$$ = $1;
1792a194551SJamie Gritton 		TAILQ_INSERT_TAIL($$, $3, tq);
1802671ee73SJamie Gritton 	}
1812671ee73SJamie Gritton 	;
1822671ee73SJamie Gritton 
1832671ee73SJamie Gritton /*
1842671ee73SJamie Gritton  * Strings may be passed in pieces, because of quoting and/or variable
1852671ee73SJamie Gritton  * interpolation.  Reassemble them into a single string.
1862671ee73SJamie Gritton  */
1872671ee73SJamie Gritton string	: STR
1882671ee73SJamie Gritton 	{
1892671ee73SJamie Gritton 		$$ = emalloc(sizeof(struct cfstring));
1902671ee73SJamie Gritton 		$$->s = $1;
1912671ee73SJamie Gritton 		$$->len = strlen($1);
1922671ee73SJamie Gritton 		STAILQ_INIT(&$$->vars);
1932671ee73SJamie Gritton 	}
1942671ee73SJamie Gritton 	| VAR
1952671ee73SJamie Gritton 	{
1962671ee73SJamie Gritton 		struct cfvar *v;
1972671ee73SJamie Gritton 
1982671ee73SJamie Gritton 		$$ = emalloc(sizeof(struct cfstring));
1992671ee73SJamie Gritton 		$$->s = estrdup("");
2002671ee73SJamie Gritton 		$$->len = 0;
2012671ee73SJamie Gritton 		STAILQ_INIT(&$$->vars);
2022671ee73SJamie Gritton 		v = emalloc(sizeof(struct cfvar));
2032671ee73SJamie Gritton 		v->name = $1;
2042671ee73SJamie Gritton 		v->pos = 0;
2052671ee73SJamie Gritton 		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
2062671ee73SJamie Gritton 	}
2072671ee73SJamie Gritton 	| string STR1
2082671ee73SJamie Gritton 	{
2092671ee73SJamie Gritton 		size_t len1;
2102671ee73SJamie Gritton 
2112671ee73SJamie Gritton 		$$ = $1;
2122671ee73SJamie Gritton 		len1 = strlen($2);
2132671ee73SJamie Gritton 		$$->s = erealloc($$->s, $$->len + len1 + 1);
2142671ee73SJamie Gritton 		strcpy($$->s + $$->len, $2);
2152671ee73SJamie Gritton 		free($2);
2162671ee73SJamie Gritton 		$$->len += len1;
2172671ee73SJamie Gritton 	}
2182671ee73SJamie Gritton 	| string VAR1
2192671ee73SJamie Gritton 	{
2202671ee73SJamie Gritton 		struct cfvar *v;
2212671ee73SJamie Gritton 
2222671ee73SJamie Gritton 		$$ = $1;
2232671ee73SJamie Gritton 		v = emalloc(sizeof(struct cfvar));
2242671ee73SJamie Gritton 		v->name = $2;
2252671ee73SJamie Gritton 		v->pos = $$->len;
2262671ee73SJamie Gritton 		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
2272671ee73SJamie Gritton 	}
2282671ee73SJamie Gritton 	;
2292671ee73SJamie Gritton 
2302671ee73SJamie Gritton %%
231086e0149SJamie Gritton 
232086e0149SJamie Gritton extern int YYLEX_DECL();
233086e0149SJamie Gritton 
234086e0149SJamie Gritton static void
YYERROR_DECL()235086e0149SJamie Gritton YYERROR_DECL()
236086e0149SJamie Gritton {
237768149ffSJamie Gritton 	struct cflex *cflex = yyget_extra(scanner);
238768149ffSJamie Gritton 
239086e0149SJamie Gritton 	if (!yyget_text(scanner))
240086e0149SJamie Gritton 		warnx("%s line %d: %s",
241768149ffSJamie Gritton 		    cflex->cfname, yyget_lineno(scanner), s);
242086e0149SJamie Gritton 	else if (!yyget_text(scanner)[0])
243086e0149SJamie Gritton 		warnx("%s: unexpected EOF",
244768149ffSJamie Gritton 		    cflex->cfname);
245086e0149SJamie Gritton 	else
246086e0149SJamie Gritton 		warnx("%s line %d: %s: %s",
247768149ffSJamie Gritton 		    cflex->cfname, yyget_lineno(scanner),
248086e0149SJamie Gritton 		    yyget_text(scanner), s);
249768149ffSJamie Gritton 	cflex->error = 1;
250086e0149SJamie Gritton }
251e82a6294SJamie Gritton 
252e82a6294SJamie Gritton /* Handle special parameters (i.e. the include directive).
253e82a6294SJamie Gritton  * Return true if the parameter was specially handled.
254e82a6294SJamie Gritton  */
255e82a6294SJamie Gritton static int
special_param(struct cfparam * p,void * scanner)256e82a6294SJamie Gritton special_param(struct cfparam *p, void *scanner)
257e82a6294SJamie Gritton {
258e82a6294SJamie Gritton 	if ((p->flags & (PF_VAR | PF_APPEND | PF_NAMEVAL)) != PF_NAMEVAL
259e82a6294SJamie Gritton 	    || strcmp(p->name, ".include"))
260e82a6294SJamie Gritton 		return 0;
261e82a6294SJamie Gritton 	struct cfstring *s;
262e82a6294SJamie Gritton 	TAILQ_FOREACH(s, &p->val, tq) {
263e82a6294SJamie Gritton 		if (STAILQ_EMPTY(&s->vars))
264e82a6294SJamie Gritton 			include_config(scanner, s->s);
265e82a6294SJamie Gritton 		else {
266e82a6294SJamie Gritton 			warnx("%s line %d: "
267e82a6294SJamie Gritton 			    "variables not permitted in '.include' filename",
268e82a6294SJamie Gritton 			    yyget_extra(scanner)->cfname,
269e82a6294SJamie Gritton 			    yyget_lineno(scanner));
270e82a6294SJamie Gritton 			yyget_extra(scanner)->error = 1;
271e82a6294SJamie Gritton 		}
272e82a6294SJamie Gritton 	}
273e82a6294SJamie Gritton 	free_param_strings(p);
274e82a6294SJamie Gritton 	free(p);
275e82a6294SJamie Gritton 	return 1;
276e82a6294SJamie Gritton }
277