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