1214117Sjamie%{
2214117Sjamie/*-
3330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4330449Seadler *
5223190Sjamie * Copyright (c) 2011 James Gritton
6214117Sjamie * All rights reserved.
7214117Sjamie *
8214117Sjamie * Redistribution and use in source and binary forms, with or without
9214117Sjamie * modification, are permitted provided that the following conditions
10214117Sjamie * are met:
11214117Sjamie * 1. Redistributions of source code must retain the above copyright
12214117Sjamie *    notice, this list of conditions and the following disclaimer.
13214117Sjamie * 2. Redistributions in binary form must reproduce the above copyright
14214117Sjamie *    notice, this list of conditions and the following disclaimer in the
15214117Sjamie *    documentation and/or other materials provided with the distribution.
16214117Sjamie *
17214117Sjamie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18214117Sjamie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19214117Sjamie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20214117Sjamie * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21214117Sjamie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22214117Sjamie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23214117Sjamie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24214117Sjamie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25214117Sjamie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26214117Sjamie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27214117Sjamie * SUCH DAMAGE.
28214117Sjamie */
29214117Sjamie
30214117Sjamie#include <sys/cdefs.h>
31214117Sjamie__FBSDID("$FreeBSD: stable/11/usr.sbin/jail/jailparse.y 330449 2018-03-05 07:26:05Z eadler $");
32214117Sjamie
33214117Sjamie#include <stdlib.h>
34214117Sjamie#include <string.h>
35214117Sjamie
36214117Sjamie#include "jailp.h"
37214117Sjamie
38214117Sjamie#ifdef DEBUG
39214117Sjamie#define YYDEBUG 1
40214117Sjamie#endif
41214117Sjamie%}
42214117Sjamie
43214117Sjamie%union {
44214117Sjamie	struct cfjail		*j;
45214117Sjamie	struct cfparams		*pp;
46214117Sjamie	struct cfparam		*p;
47214117Sjamie	struct cfstrings	*ss;
48214117Sjamie	struct cfstring		*s;
49214117Sjamie	char			*cs;
50214117Sjamie}
51214117Sjamie
52214117Sjamie%token      PLEQ
53214117Sjamie%token <cs> STR STR1 VAR VAR1
54214117Sjamie
55214117Sjamie%type <j>  jail
56214117Sjamie%type <pp> param_l
57214117Sjamie%type <p>  param name
58214117Sjamie%type <ss> value
59214117Sjamie%type <s>  string
60214117Sjamie
61214117Sjamie%%
62214117Sjamie
63214117Sjamie/*
64214117Sjamie * A config file is a series of jails (containing parameters) and jail-less
65298886Spfg * parameters which really belong to a global pseudo-jail.
66214117Sjamie */
67214117Sjamieconf	:
68214117Sjamie	;
69214117Sjamie	| conf jail
70214117Sjamie	;
71214117Sjamie	| conf param ';'
72214117Sjamie	{
73214117Sjamie		struct cfjail *j;
74214117Sjamie
75214117Sjamie		j = TAILQ_LAST(&cfjails, cfjails);
76214117Sjamie		if (!j || strcmp(j->name, "*")) {
77214117Sjamie			j = add_jail();
78214117Sjamie			j->name = estrdup("*");
79214117Sjamie		}
80214117Sjamie		TAILQ_INSERT_TAIL(&j->params, $2, tq);
81214117Sjamie	}
82214117Sjamie	| conf ';'
83214117Sjamie
84214117Sjamiejail	: STR '{' param_l '}'
85214117Sjamie	{
86214117Sjamie		$$ = add_jail();
87214117Sjamie		$$->name = $1;
88214117Sjamie		TAILQ_CONCAT(&$$->params, $3, tq);
89214117Sjamie		free($3);
90214117Sjamie	}
91214117Sjamie	;
92214117Sjamie
93214117Sjamieparam_l	:
94214117Sjamie	{
95214117Sjamie		$$ = emalloc(sizeof(struct cfparams));
96214117Sjamie		TAILQ_INIT($$);
97214117Sjamie	}
98214117Sjamie	| param_l param ';'
99214117Sjamie	{
100214117Sjamie		$$ = $1;
101214117Sjamie		TAILQ_INSERT_TAIL($$, $2, tq);
102214117Sjamie	}
103214117Sjamie	| param_l ';'
104214117Sjamie	;
105214117Sjamie
106214117Sjamie/*
107214117Sjamie * Parameters have a name and an optional list of value strings,
108289677Seadler * which may have "+=" or "=" preceding them.
109214117Sjamie */
110214117Sjamieparam	: name
111214117Sjamie	{
112214117Sjamie		$$ = $1;
113214117Sjamie	}
114214117Sjamie	| name '=' value
115214117Sjamie	{
116214117Sjamie		$$ = $1;
117223188Sjamie		TAILQ_CONCAT(&$$->val, $3, tq);
118214117Sjamie		free($3);
119214117Sjamie	}
120214117Sjamie	| name PLEQ value
121214117Sjamie	{
122214117Sjamie		$$ = $1;
123223188Sjamie		TAILQ_CONCAT(&$$->val, $3, tq);
124214117Sjamie		$$->flags |= PF_APPEND;
125214117Sjamie		free($3);
126214117Sjamie	}
127214117Sjamie	| name value
128214117Sjamie	{
129214117Sjamie		$$ = $1;
130223188Sjamie		TAILQ_CONCAT(&$$->val, $2, tq);
131214117Sjamie		free($2);
132214117Sjamie	}
133214117Sjamie	| error
134214117Sjamie	{
135214117Sjamie	}
136214117Sjamie	;
137214117Sjamie
138214117Sjamie/*
139214117Sjamie * A parameter has a fixed name.  A variable definition looks just like a
140214117Sjamie * parameter except that the name is a variable.
141214117Sjamie */
142214117Sjamiename	: STR
143214117Sjamie	{
144214117Sjamie		$$ = emalloc(sizeof(struct cfparam));
145214117Sjamie		$$->name = $1;
146223188Sjamie		TAILQ_INIT(&$$->val);
147214117Sjamie		$$->flags = 0;
148214117Sjamie	}
149214117Sjamie	| VAR
150214117Sjamie	{
151214117Sjamie		$$ = emalloc(sizeof(struct cfparam));
152214117Sjamie		$$->name = $1;
153223188Sjamie		TAILQ_INIT(&$$->val);
154214117Sjamie		$$->flags = PF_VAR;
155214117Sjamie	}
156214117Sjamie	;
157214117Sjamie
158214117Sjamievalue	: string
159214117Sjamie	{
160214117Sjamie		$$ = emalloc(sizeof(struct cfstrings));
161223188Sjamie		TAILQ_INIT($$);
162223188Sjamie		TAILQ_INSERT_TAIL($$, $1, tq);
163214117Sjamie	}
164214117Sjamie	| value ',' string
165214117Sjamie	{
166214117Sjamie		$$ = $1;
167223188Sjamie		TAILQ_INSERT_TAIL($$, $3, tq);
168214117Sjamie	}
169214117Sjamie	;
170214117Sjamie
171214117Sjamie/*
172214117Sjamie * Strings may be passed in pieces, because of quoting and/or variable
173214117Sjamie * interpolation.  Reassemble them into a single string.
174214117Sjamie */
175214117Sjamiestring	: STR
176214117Sjamie	{
177214117Sjamie		$$ = emalloc(sizeof(struct cfstring));
178214117Sjamie		$$->s = $1;
179214117Sjamie		$$->len = strlen($1);
180214117Sjamie		STAILQ_INIT(&$$->vars);
181214117Sjamie	}
182214117Sjamie	| VAR
183214117Sjamie	{
184214117Sjamie		struct cfvar *v;
185214117Sjamie
186214117Sjamie		$$ = emalloc(sizeof(struct cfstring));
187214117Sjamie		$$->s = estrdup("");
188214117Sjamie		$$->len = 0;
189214117Sjamie		STAILQ_INIT(&$$->vars);
190214117Sjamie		v = emalloc(sizeof(struct cfvar));
191214117Sjamie		v->name = $1;
192214117Sjamie		v->pos = 0;
193214117Sjamie		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
194214117Sjamie	}
195214117Sjamie	| string STR1
196214117Sjamie	{
197214117Sjamie		size_t len1;
198214117Sjamie
199214117Sjamie		$$ = $1;
200214117Sjamie		len1 = strlen($2);
201214117Sjamie		$$->s = erealloc($$->s, $$->len + len1 + 1);
202214117Sjamie		strcpy($$->s + $$->len, $2);
203214117Sjamie		free($2);
204214117Sjamie		$$->len += len1;
205214117Sjamie	}
206214117Sjamie	| string VAR1
207214117Sjamie	{
208214117Sjamie		struct cfvar *v;
209214117Sjamie
210214117Sjamie		$$ = $1;
211214117Sjamie		v = emalloc(sizeof(struct cfvar));
212214117Sjamie		v->name = $2;
213214117Sjamie		v->pos = $$->len;
214214117Sjamie		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
215214117Sjamie	}
216214117Sjamie	;
217214117Sjamie
218214117Sjamie%%
219