X-Git-Url: https://git.armaanb.net/?p=opendoas.git;a=blobdiff_plain;f=parse.y;h=b5ba234db7e3f6f1f3abf1e90c1eaf74ddd2b53d;hp=6166ceef908353e56ff965b7110dff68aa43f66e;hb=HEAD;hpb=7f11114f0f07c653e0ea3d4ae093d7dcdda4a4ef diff --git a/parse.y b/parse.y index 6166cee..b5ba234 100644 --- a/parse.y +++ b/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.16 2016/06/05 00:46:34 djm Exp $ */ +/* $OpenBSD: parse.y,v 1.10 2015/07/24 06:36:42 zhuk Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -16,15 +16,17 @@ */ %{ +#include "config.h" + #include #include -#include -#include +#include #include #include +#include #include #include -#include +#include #include "openbsd.h" @@ -38,8 +40,8 @@ typedef struct { const char *cmd; const char **cmdargs; const char **envlist; - const char **setenvlist; }; + const char **strlist; const char *str; }; int lineno; @@ -50,17 +52,30 @@ typedef struct { FILE *yyfp; struct rule **rules; -int nrules, maxrules; +size_t nrules; +static size_t maxrules; + int parse_errors = 0; -void yyerror(const char *, ...); -int yylex(void); -int yyparse(void); +static void yyerror(const char *, ...); +static int yylex(void); + +static size_t +arraylen(const char **arr) +{ + size_t cnt = 0; + + while (*arr) { + cnt++; + arr++; + } + return cnt; +} %} %token TPERMIT TDENY TAS TCMD TARGS -%token TNOPASS TKEEPENV TSETENV +%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV TINSULT %token TSTRING %% @@ -79,19 +94,18 @@ rule: action ident target cmd { r->action = $1.action; r->options = $1.options; r->envlist = $1.envlist; - r->setenvlist = $1.setenvlist; r->ident = $2.str; r->target = $3.str; r->cmd = $4.cmd; r->cmdargs = $4.cmdargs; if (nrules == maxrules) { if (maxrules == 0) - maxrules = 63; - else - maxrules *= 2; - if (!(rules = reallocarray(rules, maxrules, - sizeof(*rules)))) + maxrules = 32; + rules = reallocarray(rules, maxrules, + 2 * sizeof(*rules)); + if (!rules) errx(1, "can't allocate rules"); + maxrules *= 2; } rules[nrules++] = r; } ; @@ -100,9 +114,10 @@ action: TPERMIT options { $$.action = PERMIT; $$.options = $2.options; $$.envlist = $2.envlist; - $$.setenvlist = $2.setenvlist; } | TDENY { $$.action = DENY; + $$.options = 0; + $$.envlist = NULL; } ; options: /* none */ { @@ -111,71 +126,49 @@ options: /* none */ { } | options option { $$.options = $1.options | $2.options; $$.envlist = $1.envlist; + if (($$.options & (NOPASS|PERSIST)) == (NOPASS|PERSIST)) { + yyerror("can't combine nopass and persist"); + YYERROR; + } if ($2.envlist) { if ($$.envlist) { - yyerror("can't have two keepenv sections"); - YYERROR; - } else - $$.envlist = $2.envlist; - } - $$.setenvlist = $1.setenvlist; - if ($2.setenvlist) { - if ($$.setenvlist) { yyerror("can't have two setenv sections"); YYERROR; } else - $$.setenvlist = $2.setenvlist; + $$.envlist = $2.envlist; } } ; option: TNOPASS { $$.options = NOPASS; $$.envlist = NULL; + } | TNOLOG { + $$.options = NOLOG; + $$.envlist = NULL; + } | TPERSIST { + $$.options = PERSIST; + $$.envlist = NULL; } | TKEEPENV { $$.options = KEEPENV; $$.envlist = NULL; - } | TKEEPENV '{' envlist '}' { - $$.options = KEEPENV; - $$.envlist = $3.envlist; - } | TSETENV '{' setenvlist '}' { - $$.options = SETENV; - $$.setenvlist = NULL; - $$.setenvlist = $3.setenvlist; + } | TINSULT { + $$.options = INSULT; + $$.envlist = NULL; + } | TSETENV '{' strlist '}' { + $$.options = 0; + $$.envlist = $3.strlist; } ; -envlist: /* empty */ { - $$.envlist = NULL; - if (!($$.envlist = calloc(1, sizeof(char *)))) - errx(1, "can't allocate envlist"); - } | envlist TSTRING { - int nenv = arraylen($1.envlist); - if (!($$.envlist = reallocarray($1.envlist, nenv + 2, +strlist: /* empty */ { + if (!($$.strlist = calloc(1, sizeof(char *)))) + errx(1, "can't allocate strlist"); + } | strlist TSTRING { + int nstr = arraylen($1.strlist); + if (!($$.strlist = reallocarray($1.strlist, nstr + 2, sizeof(char *)))) - errx(1, "can't allocate envlist"); - $$.envlist[nenv] = $2.str; - $$.envlist[nenv + 1] = NULL; - } - -setenvlist: /* empty */ { - if (!($$.setenvlist = calloc(1, sizeof(char *)))) - errx(1, "can't allocate setenvlist"); - } | setenvlist TSTRING '=' TSTRING { - int nenv = arraylen($1.setenvlist); - char *cp = NULL; - - if (*$2.str == '\0' || strchr($2.str, '=') != NULL) { - yyerror("invalid setenv expression"); - YYERROR; - } - if (!($$.setenvlist = reallocarray($1.setenvlist, - nenv + 2, sizeof(char *)))) - errx(1, "can't allocate envlist"); - $$.setenvlist[nenv] = NULL; - if (asprintf(&cp, "%s=%s", $2.str, $4.str) <= 0 || - cp == NULL) - errx(1,"asprintf failed"); - $$.setenvlist[nenv] = cp; - $$.setenvlist[nenv + 1] = NULL; - } + errx(1, "can't allocate strlist"); + $$.strlist[nstr] = $2.str; + $$.strlist[nstr + 1] = NULL; + } ; ident: TSTRING { @@ -198,21 +191,8 @@ cmd: /* optional */ { args: /* empty */ { $$.cmdargs = NULL; - } | TARGS argslist { - $$.cmdargs = $2.cmdargs; - } ; - -argslist: /* empty */ { - $$.cmdargs = NULL; - if (!($$.cmdargs = calloc(1, sizeof(char *)))) - errx(1, "can't allocate args"); - } | argslist TSTRING { - int nargs = arraylen($1.cmdargs); - if (!($$.cmdargs = reallocarray($1.cmdargs, nargs + 2, - sizeof(char *)))) - errx(1, "can't allocate args"); - $$.cmdargs[nargs] = $2.str; - $$.cmdargs[nargs + 1] = NULL; + } | TARGS strlist { + $$.cmdargs = $2.strlist; } ; %% @@ -230,7 +210,7 @@ yyerror(const char *fmt, ...) parse_errors++; } -struct keyword { +static struct keyword { const char *word; int token; } keywords[] = { @@ -240,8 +220,11 @@ struct keyword { { "cmd", TCMD }, { "args", TARGS }, { "nopass", TNOPASS }, + { "nolog", TNOLOG }, + { "persist", TPERSIST }, { "keepenv", TKEEPENV }, { "setenv", TSETENV }, + { "insult", TINSULT }, }; int @@ -249,6 +232,7 @@ yylex(void) { char buf[1024], *ebuf, *p, *str; int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0; + size_t i; p = buf; ebuf = buf + sizeof(buf); @@ -266,7 +250,6 @@ repeat: /* FALLTHROUGH */ case '{': case '}': - case '=': return c; case '#': /* skip comments; NUL is allowed; no continuation */ @@ -319,7 +302,6 @@ repeat: case '#': case ' ': case '\t': - case '=': if (!escape && !quotes) goto eow; break; @@ -357,14 +339,13 @@ eow: goto repeat; } if (!nonkw) { - size_t i; for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) { if (strcmp(buf, keywords[i].word) == 0) return keywords[i].token; } } if ((str = strdup(buf)) == NULL) - err(1, "strdup"); + err(1, "%s", __func__); yylval.str = str; return TSTRING;