Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/jail/jailparse.y
Show All 24 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <err.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "jailp.h" | #include "jailp.h" | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
#define YYDEBUG 1 | #define YYDEBUG 1 | ||||
#endif | #endif | ||||
%} | %} | ||||
%union { | %union { | ||||
struct cfjail *j; | struct cfjail *j; | ||||
struct cfparams *pp; | struct cfparams *pp; | ||||
struct cfparam *p; | struct cfparam *p; | ||||
struct cfstrings *ss; | struct cfstrings *ss; | ||||
struct cfstring *s; | struct cfstring *s; | ||||
char *cs; | char *cs; | ||||
} | } | ||||
%token PLEQ | %token PLEQ | ||||
%token <cs> STR STR1 VAR VAR1 | %token <cs> STR STR1 VAR VAR1 | ||||
%type <j> jail | %type <j> jail jail_name | ||||
%type <pp> param_l | %type <pp> param_l | ||||
%type <p> param name | %type <p> param name | ||||
%type <ss> value | %type <ss> value | ||||
%type <s> string | %type <s> string | ||||
%pure-parser | |||||
%lex-param { void *scanner } | |||||
%parse-param { void *scanner } | |||||
%% | %% | ||||
/* | /* | ||||
* A config file is a series of jails (containing parameters) and jail-less | * A config file is a series of jails (containing parameters) and jail-less | ||||
* parameters which really belong to a global pseudo-jail. | * parameters which really belong to a global pseudo-jail. | ||||
*/ | */ | ||||
conf : | conf : | ||||
; | ; | ||||
| conf jail | | conf jail | ||||
; | ; | ||||
| conf param ';' | | conf param ';' | ||||
{ | { | ||||
struct cfjail *j; | if (!special_param($2, scanner)) { | ||||
struct cfjail *j = yyget_extra(scanner)->injail; | |||||
if (!j) | |||||
{ | |||||
j = TAILQ_LAST(&cfjails, cfjails); | j = TAILQ_LAST(&cfjails, cfjails); | ||||
if (!j || strcmp(j->name, "*")) { | if (!j || strcmp(j->name, "*")) { | ||||
j = add_jail(); | j = add_jail(); | ||||
j->name = estrdup("*"); | j->name = estrdup("*"); | ||||
} | } | ||||
} | |||||
TAILQ_INSERT_TAIL(&j->params, $2, tq); | TAILQ_INSERT_TAIL(&j->params, $2, tq); | ||||
} | } | ||||
} | |||||
| conf ';' | | conf ';' | ||||
jail : STR '{' param_l '}' | /* | ||||
* Allow nested jail definitions by prepending the outer jail name to | |||||
* the inner one. | |||||
*/ | |||||
jail : jail_name '{' param_l '}' | |||||
{ | { | ||||
$$ = add_jail(); | $$ = $1; | ||||
$$->name = $1; | |||||
TAILQ_CONCAT(&$$->params, $3, tq); | TAILQ_CONCAT(&$$->params, $3, tq); | ||||
free($3); | free($3); | ||||
yyget_extra(scanner)->injail = $1->cfparent; | |||||
} | } | ||||
; | ; | ||||
jail_name : STR | |||||
{ | |||||
$$ = add_jail(); | |||||
$$->cfparent = yyget_extra(scanner)->injail; | |||||
yyget_extra(scanner)->injail = $$; | |||||
if ($$->cfparent != NULL) { | |||||
size_t parentlen = strlen($$->cfparent->name); | |||||
$$->name = emalloc(parentlen + strlen($1) + 2); | |||||
strcpy($$->name, $$->cfparent->name); | |||||
$$->name[parentlen++] = '.'; | |||||
strcpy($$->name + parentlen, $1); | |||||
free($1); | |||||
} else | |||||
$$->name = $1; | |||||
} | |||||
param_l : | param_l : | ||||
{ | { | ||||
$$ = emalloc(sizeof(struct cfparams)); | $$ = emalloc(sizeof(struct cfparams)); | ||||
TAILQ_INIT($$); | TAILQ_INIT($$); | ||||
} | } | ||||
| param_l jail | |||||
; | |||||
| param_l param ';' | | param_l param ';' | ||||
{ | { | ||||
if (!special_param($2, scanner)) { | |||||
$$ = $1; | $$ = $1; | ||||
TAILQ_INSERT_TAIL($$, $2, tq); | TAILQ_INSERT_TAIL($$, $2, tq); | ||||
} | } | ||||
} | |||||
| param_l ';' | | param_l ';' | ||||
; | ; | ||||
/* | /* | ||||
* Parameters have a name and an optional list of value strings, | * Parameters have a name and an optional list of value strings, | ||||
* which may have "+=" or "=" preceding them. | * which may have "+=" or "=" preceding them. | ||||
*/ | */ | ||||
param : name | param : name | ||||
Show All 12 Lines | | name PLEQ value | ||||
TAILQ_CONCAT(&$$->val, $3, tq); | TAILQ_CONCAT(&$$->val, $3, tq); | ||||
$$->flags |= PF_APPEND; | $$->flags |= PF_APPEND; | ||||
free($3); | free($3); | ||||
} | } | ||||
| name value | | name value | ||||
{ | { | ||||
$$ = $1; | $$ = $1; | ||||
TAILQ_CONCAT(&$$->val, $2, tq); | TAILQ_CONCAT(&$$->val, $2, tq); | ||||
$$->flags |= PF_NAMEVAL; | |||||
free($2); | free($2); | ||||
} | } | ||||
| error | | error | ||||
{ | { | ||||
yyget_extra(scanner)->error = 1; | |||||
} | } | ||||
; | ; | ||||
/* | /* | ||||
* A parameter has a fixed name. A variable definition looks just like a | * A parameter has a fixed name. A variable definition looks just like a | ||||
* parameter except that the name is a variable. | * parameter except that the name is a variable. | ||||
*/ | */ | ||||
name : STR | name : STR | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | | string VAR1 | ||||
v = emalloc(sizeof(struct cfvar)); | v = emalloc(sizeof(struct cfvar)); | ||||
v->name = $2; | v->name = $2; | ||||
v->pos = $$->len; | v->pos = $$->len; | ||||
STAILQ_INSERT_TAIL(&$$->vars, v, tq); | STAILQ_INSERT_TAIL(&$$->vars, v, tq); | ||||
} | } | ||||
; | ; | ||||
%% | %% | ||||
extern int YYLEX_DECL(); | |||||
extern struct cflex *yyget_extra(void *scanner); | |||||
extern FILE *yyget_in(void *scanner); | |||||
extern int yyget_lineno(void *scanner); | |||||
extern char *yyget_text(void *scanner); | |||||
static void | |||||
YYERROR_DECL() | |||||
{ | |||||
if (!yyget_text(scanner)) | |||||
warnx("%s line %d: %s", | |||||
yyget_extra(scanner)->cfname, yyget_lineno(scanner), s); | |||||
else if (!yyget_text(scanner)[0]) | |||||
warnx("%s: unexpected EOF", | |||||
yyget_extra(scanner)->cfname); | |||||
else | |||||
warnx("%s line %d: %s: %s", | |||||
yyget_extra(scanner)->cfname, yyget_lineno(scanner), | |||||
yyget_text(scanner), s); | |||||
} | |||||
/* Handle special parameters (i.e. the include directive). | |||||
* Return true if the parameter was specially handled. | |||||
*/ | |||||
static int | |||||
special_param(struct cfparam *p, void *scanner) | |||||
{ | |||||
if ((p->flags & (PF_VAR | PF_NAMEVAL)) != PF_NAMEVAL | |||||
|| strcmp(p->name, ".include")) | |||||
return 0; | |||||
struct cfstring *s; | |||||
TAILQ_FOREACH(s, &p->val, tq) { | |||||
if (STAILQ_EMPTY(&s->vars)) | |||||
include_config(s->s, yyget_extra(scanner), | |||||
yyget_in(scanner) == stdin); | |||||
else { | |||||
warnx("%s line %d: " | |||||
"variables not permitted in '.include' filename", | |||||
yyget_extra(scanner)->cfname, | |||||
yyget_lineno(scanner)); | |||||
yyget_extra(scanner)->error = 1; | |||||
} | |||||
} | |||||
free_param_strings(p); | |||||
free(p); | |||||
return 1; | |||||
} |