%{
/*
- * Copyright (c) 1996, 1998-2005, 2007-2012
+ * Copyright (c) 1996, 1998-2005, 2007-2013
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
#include <config.h>
#include <sys/types.h>
-#include <sys/param.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#include "sudoers.h" /* XXX */
#include "parse.h"
#include "toke.h"
-#include "gram.h"
/*
* We must define SIZE_MAX for yacc's skeleton.c.
static void add_userspec(struct member *, struct privilege *);
static struct defaults *new_default(char *, char *, int);
static struct member *new_member(char *, int);
- void yyerror(const char *);
-
-void
-yyerror(const char *s)
-{
- debug_decl(yyerror, SUDO_DEBUG_PARSER)
-
- /* If we last saw a newline the error is on the preceding line. */
- if (last_token == COMMENT)
- sudolineno--;
-
- /* Save the line the first error occurred on. */
- if (errorlineno == -1) {
- errorlineno = sudolineno;
- errorfile = estrdup(sudoers);
- }
- if (sudoers_warnings && s != NULL) {
- LEXTRACE("<*> ");
-#ifndef TRACELEXER
- if (trace_print == NULL || trace_print == sudoers_trace_print)
- warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno);
-#endif
- }
- parse_error = true;
- debug_return;
-}
+static struct sudo_digest *new_digest(int, const char *);
%}
%union {
struct member *member;
struct runascontainer *runas;
struct privilege *privilege;
+ struct sudo_digest *digest;
struct sudo_command command;
struct cmndtag tag;
struct selinux_info seinfo;
%token <string> NETGROUP /* a netgroup (+NAME) */
%token <string> USERGROUP /* a usergroup (%NAME) */
%token <string> WORD /* a word */
+%token <string> DIGEST /* a SHA-2 digest */
%token <tok> DEFAULTS /* Defaults entry */
%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */
%token <tok> DEFAULTS_USER /* User-specific defaults entry */
%token <tok> PRIVS /* Solaris privileges */
%token <tok> LIMITPRIVS /* Solaris limit privileges */
%token <tok> MYSELF /* run as myself, not another user */
+%token <tok> SHA224 /* sha224 digest */
+%token <tok> SHA256 /* sha256 digest */
+%token <tok> SHA384 /* sha384 digest */
+%token <tok> SHA512 /* sha512 digest */
%type <cmndspec> cmndspec
%type <cmndspec> cmndspeclist
%type <defaults> defaults_list
%type <member> cmnd
%type <member> opcmnd
+%type <member> digcmnd
%type <member> cmndlist
%type <member> host
%type <member> hostlist
%type <privinfo> solarisprivs
%type <string> privsspec
%type <string> limitprivsspec
+%type <digest> digest
%%
}
;
-cmndspec : runasspec selinux solarisprivs cmndtag opcmnd {
+cmndspec : runasspec selinux solarisprivs cmndtag digcmnd {
struct cmndspec *cs = ecalloc(1, sizeof(*cs));
if ($1 != NULL) {
list2tq(&cs->runasuserlist, $1->runasusers);
}
;
+digest : SHA224 ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA224, $3);
+ }
+ | SHA256 ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA256, $3);
+ }
+ | SHA384 ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA384, $3);
+ }
+ | SHA512 ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA512, $3);
+ }
+ ;
+
+digcmnd : opcmnd {
+ $$ = $1;
+ }
+ | digest opcmnd {
+ /* XXX - yuck */
+ struct sudo_command *c = (struct sudo_command *)($2->name);
+ c->digest = $1;
+ $$ = $2;
+ }
+ ;
+
opcmnd : cmnd {
$$ = $1;
$$->negated = false;
| privsspec {
$$.privs = $1;
$$.limitprivs = NULL;
- }
+ }
| limitprivsspec {
$$.privs = NULL;
$$.limitprivs = $1;
- }
+ }
| privsspec limitprivsspec {
$$.privs = $1;
$$.limitprivs = $2;
- }
+ }
| limitprivsspec privsspec {
$$.limitprivs = $1;
$$.privs = $2;
- }
+ }
+ ;
runasspec : /* empty */ {
$$ = NULL;
hostalias : ALIAS '=' hostlist {
char *s;
if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) {
- yyerror(s);
+ sudoerserror(s);
YYERROR;
}
}
cmndalias : ALIAS '=' cmndlist {
char *s;
if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) {
- yyerror(s);
+ sudoerserror(s);
YYERROR;
}
}
;
-cmndlist : opcmnd
- | cmndlist ',' opcmnd {
+cmndlist : digcmnd
+ | cmndlist ',' digcmnd {
list_append($1, $3);
$$ = $1;
}
runasalias : ALIAS '=' userlist {
char *s;
if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) {
- yyerror(s);
+ sudoerserror(s);
YYERROR;
}
}
useralias : ALIAS '=' userlist {
char *s;
if ((s = alias_add($1, USERALIAS, $3)) != NULL) {
- yyerror(s);
+ sudoerserror(s);
YYERROR;
}
}
;
%%
+void
+sudoerserror(const char *s)
+{
+ debug_decl(sudoerserror, SUDO_DEBUG_PARSER)
+
+ /* If we last saw a newline the error is on the preceding line. */
+ if (last_token == COMMENT)
+ sudolineno--;
+
+ /* Save the line the first error occurred on. */
+ if (errorlineno == -1) {
+ errorlineno = sudolineno;
+ errorfile = estrdup(sudoers);
+ }
+ if (sudoers_warnings && s != NULL) {
+ LEXTRACE("<*> ");
+#ifndef TRACELEXER
+ if (trace_print == NULL || trace_print == sudoers_trace_print) {
+ const char fmt[] = ">>> %s: %s near line %d <<<\n";
+ int oldlocale;
+
+ /* Warnings are displayed in the user's locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
+ sudo_printf(SUDO_CONV_ERROR_MSG, _(fmt), sudoers, _(s), sudolineno);
+ sudoers_setlocale(oldlocale, NULL);
+ }
+#endif
+ }
+ parse_error = true;
+ debug_return;
+}
+
static struct defaults *
new_default(char *var, char *val, int op)
{
debug_return_ptr(m);
}
+struct sudo_digest *
+new_digest(int digest_type, const char *digest_str)
+{
+ struct sudo_digest *dig;
+ debug_decl(new_digest, SUDO_DEBUG_PARSER)
+
+ dig = emalloc(sizeof(*dig));
+ dig->digest_type = digest_type;
+ dig->digest_str = estrdup(digest_str);
+
+ debug_return_ptr(dig);
+}
+
/*
* Add a list of defaults structures to the defaults list.
* The binding, if non-NULL, specifies a list of hosts, users, or