X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=parse.y;h=f4309a3d0db0b61b95542b6e2dd03e4c20e787d3;hb=b82ffa68a6436ce3f4c4b480bc9c12ac284b0d99;hp=ee5f11d04ab8b8c5ae60dc7749b78b106b31bcfb;hpb=fcb93413226deaed752dd37ea42c830c1f57054f;p=opendoas.git diff --git a/parse.y b/parse.y index ee5f11d..f4309a3 100644 --- a/parse.y +++ b/parse.y @@ -16,14 +16,19 @@ */ %{ +#include "config.h" + #include #include -#include -#include +#include #include #include +#include +#include #include -#include +#include + +#include "openbsd.h" #include "doas.h" @@ -36,6 +41,7 @@ typedef struct { const char **cmdargs; const char **envlist; }; + const char **strlist; const char *str; }; int lineno; @@ -46,17 +52,30 @@ typedef struct { FILE *yyfp; struct rule **rules; -int nrules, maxrules; +int nrules; +static int 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 +%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV %token TSTRING %% @@ -97,15 +116,23 @@ action: TPERMIT options { $$.envlist = $2.envlist; } | TDENY { $$.action = DENY; + $$.options = 0; + $$.envlist = NULL; } ; -options: /* none */ - | options option { +options: /* none */ { + $$.options = 0; + $$.envlist = NULL; + } | 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("can't have two setenv sections"); YYERROR; } else $$.envlist = $2.envlist; @@ -113,24 +140,32 @@ options: /* none */ } ; option: TNOPASS { $$.options = NOPASS; + $$.envlist = NULL; + } | TNOLOG { + $$.options = NOLOG; + $$.envlist = NULL; + } | TPERSIST { + $$.options = PERSIST; + $$.envlist = NULL; } | TKEEPENV { $$.options = KEEPENV; - } | TKEEPENV '{' envlist '}' { - $$.options = KEEPENV; - $$.envlist = $3.envlist; + $$.envlist = NULL; + } | TSETENV '{' strlist '}' { + $$.options = 0; + $$.envlist = $3.strlist; } ; -envlist: /* empty */ { - 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; - } + errx(1, "can't allocate strlist"); + $$.strlist[nstr] = $2.str; + $$.strlist[nstr + 1] = NULL; + } ; ident: TSTRING { @@ -153,20 +188,8 @@ cmd: /* optional */ { args: /* empty */ { $$.cmdargs = NULL; - } | TARGS argslist { - $$.cmdargs = $2.cmdargs; - } ; - -argslist: /* empty */ { - 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; } ; %% @@ -176,6 +199,7 @@ yyerror(const char *fmt, ...) { va_list va; + fprintf(stderr, "doas: "); va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); @@ -183,7 +207,7 @@ yyerror(const char *fmt, ...) parse_errors++; } -struct keyword { +static struct keyword { const char *word; int token; } keywords[] = { @@ -193,14 +217,17 @@ struct keyword { { "cmd", TCMD }, { "args", TARGS }, { "nopass", TNOPASS }, + { "nolog", TNOLOG }, + { "persist", TPERSIST }, { "keepenv", TKEEPENV }, + { "setenv", TSETENV }, }; int yylex(void) { char buf[1024], *ebuf, *p, *str; - int i, c, quotes = 0, escape = 0, qpos = -1, nonkw = 0; + int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0; p = buf; ebuf = buf + sizeof(buf); @@ -303,13 +330,14 @@ 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; }