#include <config.h>
#define YYBISON 30802
#define YYBISON_VERSION "3.8.2"
#define YYSKELETON_NAME "yacc.c"
#define YYPURE 0
#define YYPUSH 0
#define YYPULL 1
#define yyparse sudoersparse
#define yylex sudoerslex
#define yyerror sudoerserror
#define yydebug sudoersdebug
#define yynerrs sudoersnerrs
#define yylval sudoerslval
#define yychar sudoerschar
#line 1 "gram.y"
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sudoers.h>
#include <sudo_digest.h>
#include <toke.h>
#ifdef YYBISON
# define YYERROR_VERBOSE
#endif
#define this_lineno (sudoerschar == '\n' ? sudolineno - 1 : sudolineno)
bool parse_error = false;
static struct sudoers_parser_config parser_conf =
SUDOERS_PARSER_CONFIG_INITIALIZER;
sudoers_logger_t sudoers_error_hook;
static int alias_line, alias_column;
#ifdef NO_LEAKS
static struct parser_leak_list parser_leak_list =
SLIST_HEAD_INITIALIZER(parser_leak_list);
#endif
struct sudoers_parse_tree parsed_policy = {
{ NULL, NULL },
TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
NULL,
NULL,
NULL,
NULL,
NULL
};
static bool add_defaults(short, struct member *, struct defaults *);
static bool add_userspec(struct member *, struct privilege *);
static struct command_digest *new_digest(unsigned int, char *);
static struct defaults *new_default(char *, char *, short);
static struct member *new_member(char *, short);
static struct sudo_command *new_command(char *, char *);
static void alias_error(const char *name, short type, int errnum);
static void init_options(struct command_options *opts);
static void propagate_cmndspec(struct cmndspec *cs, const struct cmndspec *prev);
#line 168 "gram.c"
# ifndef YY_CAST
# ifdef __cplusplus
# define YY_CAST(Type, Val) static_cast<Type> (Val)
# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
# else
# define YY_CAST(Type, Val) ((Type) (Val))
# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
# endif
# endif
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
# define YY_NULLPTR nullptr
# else
# define YY_NULLPTR 0
# endif
# else
# define YY_NULLPTR ((void*)0)
# endif
# endif
#ifndef YY_SUDOERS_Y_TAB_H_INCLUDED
# define YY_SUDOERS_Y_TAB_H_INCLUDED
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int sudoersdebug;
#endif
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
YYEMPTY = -2,
YYEOF = 0,
YYerror = 256,
YYUNDEF = 257,
COMMAND = 258,
ALIAS = 259,
DEFVAR = 260,
NTWKADDR = 261,
NETGROUP = 262,
USERGROUP = 263,
WORD = 264,
DIGEST = 265,
INCLUDE = 266,
INCLUDEDIR = 267,
DEFAULTS = 268,
DEFAULTS_HOST = 269,
DEFAULTS_USER = 270,
DEFAULTS_RUNAS = 271,
DEFAULTS_CMND = 272,
NOPASSWD = 273,
PASSWD = 274,
NOEXEC = 275,
EXEC = 276,
SETENV = 277,
NOSETENV = 278,
LOG_INPUT = 279,
NOLOG_INPUT = 280,
LOG_OUTPUT = 281,
NOLOG_OUTPUT = 282,
MAIL = 283,
NOMAIL = 284,
FOLLOWLNK = 285,
NOFOLLOWLNK = 286,
INTERCEPT = 287,
NOINTERCEPT = 288,
ALL = 289,
HOSTALIAS = 290,
CMNDALIAS = 291,
USERALIAS = 292,
RUNASALIAS = 293,
ERROR = 294,
NOMATCH = 295,
CHROOT = 296,
CWD = 297,
TYPE = 298,
ROLE = 299,
APPARMOR_PROFILE = 300,
PRIVS = 301,
LIMITPRIVS = 302,
CMND_TIMEOUT = 303,
NOTBEFORE = 304,
NOTAFTER = 305,
MYSELF = 306,
SHA224_TOK = 307,
SHA256_TOK = 308,
SHA384_TOK = 309,
SHA512_TOK = 310
};
typedef enum yytokentype yytoken_kind_t;
#endif
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
#define COMMAND 258
#define ALIAS 259
#define DEFVAR 260
#define NTWKADDR 261
#define NETGROUP 262
#define USERGROUP 263
#define WORD 264
#define DIGEST 265
#define INCLUDE 266
#define INCLUDEDIR 267
#define DEFAULTS 268
#define DEFAULTS_HOST 269
#define DEFAULTS_USER 270
#define DEFAULTS_RUNAS 271
#define DEFAULTS_CMND 272
#define NOPASSWD 273
#define PASSWD 274
#define NOEXEC 275
#define EXEC 276
#define SETENV 277
#define NOSETENV 278
#define LOG_INPUT 279
#define NOLOG_INPUT 280
#define LOG_OUTPUT 281
#define NOLOG_OUTPUT 282
#define MAIL 283
#define NOMAIL 284
#define FOLLOWLNK 285
#define NOFOLLOWLNK 286
#define INTERCEPT 287
#define NOINTERCEPT 288
#define ALL 289
#define HOSTALIAS 290
#define CMNDALIAS 291
#define USERALIAS 292
#define RUNASALIAS 293
#define ERROR 294
#define NOMATCH 295
#define CHROOT 296
#define CWD 297
#define TYPE 298
#define ROLE 299
#define APPARMOR_PROFILE 300
#define PRIVS 301
#define LIMITPRIVS 302
#define CMND_TIMEOUT 303
#define NOTBEFORE 304
#define NOTAFTER 305
#define MYSELF 306
#define SHA224_TOK 307
#define SHA256_TOK 308
#define SHA384_TOK 309
#define SHA512_TOK 310
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 91 "gram.y"
struct cmndspec *cmndspec;
struct defaults *defaults;
struct member *member;
struct runascontainer *runas;
struct privilege *privilege;
struct command_digest *digest;
struct sudo_command command;
struct command_options options;
struct cmndtag tag;
char *string;
const char *cstring;
int tok;
#line 346 "gram.c"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE sudoerslval;
int sudoersparse (void);
#endif
enum yysymbol_kind_t
{
YYSYMBOL_YYEMPTY = -2,
YYSYMBOL_YYEOF = 0,
YYSYMBOL_YYerror = 1,
YYSYMBOL_YYUNDEF = 2,
YYSYMBOL_COMMAND = 3,
YYSYMBOL_ALIAS = 4,
YYSYMBOL_DEFVAR = 5,
YYSYMBOL_NTWKADDR = 6,
YYSYMBOL_NETGROUP = 7,
YYSYMBOL_USERGROUP = 8,
YYSYMBOL_WORD = 9,
YYSYMBOL_DIGEST = 10,
YYSYMBOL_INCLUDE = 11,
YYSYMBOL_INCLUDEDIR = 12,
YYSYMBOL_DEFAULTS = 13,
YYSYMBOL_DEFAULTS_HOST = 14,
YYSYMBOL_DEFAULTS_USER = 15,
YYSYMBOL_DEFAULTS_RUNAS = 16,
YYSYMBOL_DEFAULTS_CMND = 17,
YYSYMBOL_NOPASSWD = 18,
YYSYMBOL_PASSWD = 19,
YYSYMBOL_NOEXEC = 20,
YYSYMBOL_EXEC = 21,
YYSYMBOL_SETENV = 22,
YYSYMBOL_NOSETENV = 23,
YYSYMBOL_LOG_INPUT = 24,
YYSYMBOL_NOLOG_INPUT = 25,
YYSYMBOL_LOG_OUTPUT = 26,
YYSYMBOL_NOLOG_OUTPUT = 27,
YYSYMBOL_MAIL = 28,
YYSYMBOL_NOMAIL = 29,
YYSYMBOL_FOLLOWLNK = 30,
YYSYMBOL_NOFOLLOWLNK = 31,
YYSYMBOL_INTERCEPT = 32,
YYSYMBOL_NOINTERCEPT = 33,
YYSYMBOL_ALL = 34,
YYSYMBOL_HOSTALIAS = 35,
YYSYMBOL_CMNDALIAS = 36,
YYSYMBOL_USERALIAS = 37,
YYSYMBOL_RUNASALIAS = 38,
YYSYMBOL_39_ = 39,
YYSYMBOL_40_ = 40,
YYSYMBOL_41_ = 41,
YYSYMBOL_42_ = 42,
YYSYMBOL_43_ = 43,
YYSYMBOL_44_ = 44,
YYSYMBOL_45_ = 45,
YYSYMBOL_46_ = 46,
YYSYMBOL_47_n_ = 47,
YYSYMBOL_ERROR = 48,
YYSYMBOL_NOMATCH = 49,
YYSYMBOL_CHROOT = 50,
YYSYMBOL_CWD = 51,
YYSYMBOL_TYPE = 52,
YYSYMBOL_ROLE = 53,
YYSYMBOL_APPARMOR_PROFILE = 54,
YYSYMBOL_PRIVS = 55,
YYSYMBOL_LIMITPRIVS = 56,
YYSYMBOL_CMND_TIMEOUT = 57,
YYSYMBOL_NOTBEFORE = 58,
YYSYMBOL_NOTAFTER = 59,
YYSYMBOL_MYSELF = 60,
YYSYMBOL_SHA224_TOK = 61,
YYSYMBOL_SHA256_TOK = 62,
YYSYMBOL_SHA384_TOK = 63,
YYSYMBOL_SHA512_TOK = 64,
YYSYMBOL_YYACCEPT = 65,
YYSYMBOL_file = 66,
YYSYMBOL_line = 67,
YYSYMBOL_entry = 68,
YYSYMBOL_include = 69,
YYSYMBOL_includedir = 70,
YYSYMBOL_defaults_list = 71,
YYSYMBOL_defaults_entry = 72,
YYSYMBOL_privileges = 73,
YYSYMBOL_privilege = 74,
YYSYMBOL_ophost = 75,
YYSYMBOL_host = 76,
YYSYMBOL_cmndspeclist = 77,
YYSYMBOL_cmndspec = 78,
YYSYMBOL_digestspec = 79,
YYSYMBOL_digestlist = 80,
YYSYMBOL_digcmnd = 81,
YYSYMBOL_opcmnd = 82,
YYSYMBOL_chdirspec = 83,
YYSYMBOL_chrootspec = 84,
YYSYMBOL_timeoutspec = 85,
YYSYMBOL_notbeforespec = 86,
YYSYMBOL_notafterspec = 87,
YYSYMBOL_rolespec = 88,
YYSYMBOL_typespec = 89,
YYSYMBOL_apparmor_profilespec = 90,
YYSYMBOL_privsspec = 91,
YYSYMBOL_limitprivsspec = 92,
YYSYMBOL_runasspec = 93,
YYSYMBOL_runaslist = 94,
YYSYMBOL_reserved_word = 95,
YYSYMBOL_reserved_alias = 96,
YYSYMBOL_options = 97,
YYSYMBOL_cmndtag = 98,
YYSYMBOL_cmnd = 99,
YYSYMBOL_hostaliases = 100,
YYSYMBOL_hostalias = 101,
YYSYMBOL_102_1 = 102,
YYSYMBOL_hostlist = 103,
YYSYMBOL_cmndaliases = 104,
YYSYMBOL_cmndalias = 105,
YYSYMBOL_106_2 = 106,
YYSYMBOL_cmndlist = 107,
YYSYMBOL_runasaliases = 108,
YYSYMBOL_runasalias = 109,
YYSYMBOL_110_3 = 110,
YYSYMBOL_useraliases = 111,
YYSYMBOL_useralias = 112,
YYSYMBOL_113_4 = 113,
YYSYMBOL_userlist = 114,
YYSYMBOL_opuser = 115,
YYSYMBOL_user = 116,
YYSYMBOL_grouplist = 117,
YYSYMBOL_opgroup = 118,
YYSYMBOL_group = 119
};
typedef enum yysymbol_kind_t yysymbol_kind_t;
#ifdef short
# undef short
#endif
#ifndef __PTRDIFF_MAX__
# include <limits.h>
# if defined HAVE_STDINT_H
# include <stdint.h>
# define YY_STDINT_H
# endif
#endif
#ifdef __INT_LEAST8_MAX__
typedef __INT_LEAST8_TYPE__ yytype_int8;
#elif defined YY_STDINT_H
typedef int_least8_t yytype_int8;
#else
typedef signed char yytype_int8;
#endif
#ifdef __INT_LEAST16_MAX__
typedef __INT_LEAST16_TYPE__ yytype_int16;
#elif defined YY_STDINT_H
typedef int_least16_t yytype_int16;
#else
typedef short yytype_int16;
#endif
#ifdef __hpux
# undef UINT_LEAST8_MAX
# undef UINT_LEAST16_MAX
# define UINT_LEAST8_MAX 255
# define UINT_LEAST16_MAX 65535
#endif
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
&& UINT_LEAST8_MAX <= INT_MAX)
typedef uint_least8_t yytype_uint8;
#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
typedef unsigned char yytype_uint8;
#else
typedef short yytype_uint8;
#endif
#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
typedef __UINT_LEAST16_TYPE__ yytype_uint16;
#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
&& UINT_LEAST16_MAX <= INT_MAX)
typedef uint_least16_t yytype_uint16;
#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
typedef unsigned short yytype_uint16;
#else
typedef int yytype_uint16;
#endif
#ifndef YYPTRDIFF_T
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
# define YYPTRDIFF_T __PTRDIFF_TYPE__
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined PTRDIFF_MAX
# ifndef ptrdiff_t
# include <stddef.h>
# endif
# define YYPTRDIFF_T ptrdiff_t
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
# define YYPTRDIFF_T long
# define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif
#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h>
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned
# endif
#endif
#define YYSIZE_MAXIMUM \
YY_CAST (YYPTRDIFF_T, \
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
? YYPTRDIFF_MAXIMUM \
: YY_CAST (YYSIZE_T, -1)))
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
typedef yytype_uint8 yy_state_t;
typedef int yy_state_fast_t;
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h>
# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
# define YY_(Msgid) Msgid
# endif
#endif
#ifndef YY_ATTRIBUTE_PURE
# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
# define YY_ATTRIBUTE_PURE
# endif
#endif
#ifndef YY_ATTRIBUTE_UNUSED
# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
# else
# define YY_ATTRIBUTE_UNUSED
# endif
#endif
#if ! defined lint || defined __GNUC__
# define YY_USE(E) ((void) (E))
#else
# define YY_USE(E)
#endif
#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
# else
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value)
#endif
#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
# define YY_IGNORE_USELESS_CAST_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
# define YY_IGNORE_USELESS_CAST_END \
_Pragma ("GCC diagnostic pop")
#endif
#ifndef YY_IGNORE_USELESS_CAST_BEGIN
# define YY_IGNORE_USELESS_CAST_BEGIN
# define YY_IGNORE_USELESS_CAST_END
#endif
#define YY_ASSERT(E) ((void) (0 && (E)))
#if !defined yyoverflow
# ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
# elif defined __BUILTIN_VA_ARG_INCR
# include <alloca.h>
# elif defined _AIX
# define YYSTACK_ALLOC __alloca
# elif defined _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# include <stdlib.h>
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
# define YYSTACK_FREE(Ptr) do { ; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM 4032
# endif
# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h>
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T);
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined EXIT_SUCCESS
void free (void *);
# endif
# endif
# endif
#endif
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
union yyalloc
{
yy_state_t yyss_alloc;
YYSTYPE yyvs_alloc;
};
# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
# define YYSTACK_BYTES(N) \
((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
# define YYCOPY_NEEDED 1
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYPTRDIFF_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / YYSIZEOF (*yyptr); \
} \
while (0)
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(Dst, Src, Count) \
__builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
# else
# define YYCOPY(Dst, Src, Count) \
do \
{ \
YYPTRDIFF_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \
while (0)
# endif
# endif
#endif
#define YYFINAL 90
#define YYLAST 332
#define YYNTOKENS 65
#define YYNNTS 55
#define YYNRULES 155
#define YYNSTATES 256
#define YYMAXUTOK 310
#define YYTRANSLATE(YYX) \
(0 <= (YYX) && (YYX) <= YYMAXUTOK \
? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
: YYSYMBOL_YYUNDEF)
static const yytype_int8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
47, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 42, 2, 2, 2, 2, 2, 2,
45, 46, 2, 43, 41, 44, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 39, 2,
2, 40, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64
};
#if YYDEBUG
static const yytype_int16 yyrline[] =
{
0, 205, 205, 208, 211, 212, 215, 218, 221, 229,
237, 243, 246, 249, 252, 255, 259, 263, 267, 271,
277, 280, 286, 289, 295, 296, 303, 312, 321, 331,
341, 353, 354, 359, 365, 382, 386, 392, 401, 409,
418, 427, 438, 439, 449, 513, 522, 531, 540, 551,
552, 559, 562, 576, 580, 586, 602, 624, 629, 633,
638, 643, 648, 653, 657, 662, 665, 670, 687, 699,
715, 733, 752, 753, 754, 755, 756, 757, 758, 759,
760, 761, 762, 765, 771, 774, 779, 784, 793, 802,
814, 819, 824, 829, 834, 841, 844, 847, 850, 853,
856, 859, 862, 865, 868, 871, 874, 877, 880, 883,
886, 889, 894, 908, 917, 938, 961, 962, 965, 965,
977, 980, 981, 988, 989, 992, 992, 1004, 1007, 1008,
1015, 1016, 1019, 1019, 1031, 1034, 1035, 1038, 1038, 1050,
1053, 1054, 1061, 1065, 1071, 1080, 1088, 1097, 1106, 1117,
1118, 1125, 1129, 1135, 1144, 1152
};
#endif
#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
#if YYDEBUG || 0
static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
static const char *const yytname[] =
{
"\"end of file\"", "error", "\"invalid token\"", "COMMAND", "ALIAS",
"DEFVAR", "NTWKADDR", "NETGROUP", "USERGROUP", "WORD", "DIGEST",
"INCLUDE", "INCLUDEDIR", "DEFAULTS", "DEFAULTS_HOST", "DEFAULTS_USER",
"DEFAULTS_RUNAS", "DEFAULTS_CMND", "NOPASSWD", "PASSWD", "NOEXEC",
"EXEC", "SETENV", "NOSETENV", "LOG_INPUT", "NOLOG_INPUT", "LOG_OUTPUT",
"NOLOG_OUTPUT", "MAIL", "NOMAIL", "FOLLOWLNK", "NOFOLLOWLNK",
"INTERCEPT", "NOINTERCEPT", "ALL", "HOSTALIAS", "CMNDALIAS", "USERALIAS",
"RUNASALIAS", "':'", "'='", "','", "'!'", "'+'", "'-'", "'('", "')'",
"'\\n'", "ERROR", "NOMATCH", "CHROOT", "CWD", "TYPE", "ROLE",
"APPARMOR_PROFILE", "PRIVS", "LIMITPRIVS", "CMND_TIMEOUT", "NOTBEFORE",
"NOTAFTER", "MYSELF", "SHA224_TOK", "SHA256_TOK", "SHA384_TOK",
"SHA512_TOK", "$accept", "file", "line", "entry", "include",
"includedir", "defaults_list", "defaults_entry", "privileges",
"privilege", "ophost", "host", "cmndspeclist", "cmndspec", "digestspec",
"digestlist", "digcmnd", "opcmnd", "chdirspec", "chrootspec",
"timeoutspec", "notbeforespec", "notafterspec", "rolespec", "typespec",
"apparmor_profilespec", "privsspec", "limitprivsspec", "runasspec",
"runaslist", "reserved_word", "reserved_alias", "options", "cmndtag",
"cmnd", "hostaliases", "hostalias", "$@1", "hostlist", "cmndaliases",
"cmndalias", "$@2", "cmndlist", "runasaliases", "runasalias", "$@3",
"useraliases", "useralias", "$@4", "userlist", "opuser", "user",
"grouplist", "opgroup", "group", YY_NULLPTR
};
static const char *
yysymbol_name (yysymbol_kind_t yysymbol)
{
return yytname[yysymbol];
}
#endif
#define YYPACT_NINF (-116)
#define yypact_value_is_default(Yyn) \
((Yyn) == YYPACT_NINF)
#define YYTABLE_NINF (-4)
#define yytable_value_is_error(Yyn) \
0
static const yytype_int16 yypact[] =
{
174, -29, -116, -116, -116, -116, 35, 38, 11, 239,
150, 150, 8, -116, 32, 76, 88, 114, 254, -116,
58, 218, -116, -116, -116, 70, -116, -116, -116, 12,
13, 136, 73, 14, -116, -116, -116, -116, -116, -116,
276, -116, -116, 4, 10, 10, -116, -116, -116, -116,
190, 42, 81, 85, 97, -116, 64, -116, -116, -116,
52, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -116, -116, -116, 57, 2, -116, -116, 111, 9,
-116, -116, 112, 56, -116, -116, 123, 61, -116, -116,
-116, -116, 150, 62, -116, 75, 90, -116, 130, -116,
188, 204, 205, -116, 11, -116, -116, 239, 55, 66,
108, -116, 207, 210, 213, 228, 143, -116, 8, 155,
175, 239, 32, -116, 209, 8, 76, -116, 211, 150,
88, -116, 217, 150, 114, -116, -116, 194, -116, 202,
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -116, -116, -116, -116, -116, -116, 239, 225, -116,
8, 227, -116, 150, 229, -116, 150, 229, -116, -116,
-116, 233, 230, -116, -116, 225, 227, 229, 229, 235,
232, 121, 202, 240, -116, -116, -116, 255, 238, -116,
-116, -116, 235, -116, 234, 236, 244, 246, 247, 260,
261, 262, 263, 264, -116, -116, -116, -116, -116, -116,
-116, -116, -116, -116, 1, -116, 235, 238, 241, 296,
297, 298, 299, 300, 302, 303, 304, 305, -116, -116,
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -116, -116, -116, -116, -116
};
static const yytype_uint8 yydefact[] =
{
0, 0, 144, 146, 147, 148, 0, 0, 0, 0,
0, 0, 0, 145, 0, 0, 0, 0, 0, 6,
0, 0, 4, 8, 9, 0, 140, 142, 7, 0,
0, 26, 0, 0, 24, 37, 40, 39, 41, 38,
0, 121, 35, 0, 0, 0, 114, 113, 115, 112,
0, 0, 0, 0, 0, 49, 0, 128, 51, 53,
0, 118, 72, 73, 74, 79, 78, 82, 80, 81,
75, 76, 77, 83, 0, 0, 116, 125, 0, 0,
123, 137, 0, 0, 135, 132, 0, 0, 130, 143,
1, 5, 0, 0, 31, 0, 0, 20, 0, 22,
0, 0, 0, 27, 0, 15, 36, 0, 0, 0,
0, 54, 0, 0, 0, 0, 0, 52, 0, 0,
0, 0, 0, 12, 0, 0, 0, 13, 0, 0,
0, 11, 0, 0, 0, 14, 141, 0, 10, 65,
21, 23, 28, 29, 30, 25, 122, 18, 16, 17,
45, 46, 47, 48, 50, 129, 19, 0, 120, 117,
0, 127, 124, 0, 139, 136, 0, 134, 131, 33,
32, 67, 34, 42, 84, 119, 126, 138, 133, 71,
0, 68, 65, 95, 153, 155, 154, 0, 70, 149,
151, 66, 0, 43, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 85, 86, 89, 87, 88, 90,
91, 92, 93, 94, 0, 152, 0, 69, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 96, 97,
98, 99, 102, 103, 104, 105, 106, 107, 110, 111,
108, 109, 100, 101, 44, 150, 56, 55, 61, 60,
62, 63, 64, 57, 58, 59
};
static const yytype_int16 yypgoto[] =
{
-116, -116, -116, 294, -116, -116, -6, 212, -116, 180,
214, 278, -116, 137, 206, -116, -115, 267, -116, -116,
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -9, -116, -116, 270, -116, 203, -116, -7, -116,
198, -116, -85, -116, 192, -116, -116, 197, -116, -10,
237, 310, 138, 115, 145
};
static const yytype_uint8 yydefgoto[] =
{
0, 20, 21, 22, 23, 24, 33, 34, 93, 94,
41, 42, 172, 173, 55, 56, 57, 58, 204, 205,
206, 207, 208, 209, 210, 211, 212, 213, 174, 180,
73, 74, 183, 214, 59, 75, 76, 120, 95, 79,
80, 124, 60, 87, 88, 132, 83, 84, 128, 25,
26, 27, 188, 189, 190
};
static const yytype_int16 yytable[] =
{
44, 45, 43, 155, 46, 47, 78, 82, 86, 31,
48, 46, 47, 96, 98, 31, 31, 48, 28, 228,
229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
239, 240, 241, 242, 243, 49, 61, 108, 109, 110,
161, 122, 49, 50, 29, 107, 32, 30, 126, 123,
50, 92, 32, 32, 119, 104, 127, 31, 90, 97,
99, 105, 51, 52, 53, 54, 62, 46, 47, 51,
52, 53, 54, 48, 35, 176, 36, 37, 103, 38,
77, 112, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 81, 118, 32, 130, 104, 121, 49, 244,
134, 137, 147, 131, 39, 116, 50, 104, 135, 138,
62, 92, 40, 148, 158, 139, 107, 78, 85, 164,
113, 82, 62, 167, 114, 86, 63, 64, 65, 66,
67, 68, 69, 70, 71, 72, 115, 140, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 62, 104,
175, 125, 129, 177, 2, 149, 178, 3, 4, 5,
192, 181, 92, 133, 63, 64, 65, 66, 67, 68,
69, 70, 71, 72, -2, 1, 100, 141, 2, 101,
102, 3, 4, 5, 13, 6, 7, 8, 9, 10,
11, 12, 18, 46, 47, 169, 104, 142, 35, 48,
36, 37, 156, 38, 51, 52, 53, 54, 13, 14,
15, 16, 17, 143, 144, 157, 18, 150, -3, 1,
151, 19, 2, 152, 49, 3, 4, 5, 39, 6,
7, 8, 9, 10, 11, 12, 40, 2, 153, 184,
3, 4, 5, 35, 185, 36, 37, 171, 38, 160,
246, 163, 13, 14, 15, 16, 17, 166, 2, 184,
18, 3, 4, 5, 185, 19, 107, 13, 118, 186,
92, 182, 179, 39, 218, 18, 219, 187, 191, 216,
35, 40, 36, 37, 220, 38, 221, 222, 13, 186,
194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
223, 224, 225, 226, 227, 247, 248, 249, 250, 251,
39, 252, 253, 254, 255, 91, 145, 170, 106, 193,
111, 146, 154, 117, 162, 159, 168, 165, 89, 136,
217, 245, 215
};
static const yytype_uint8 yycheck[] =
{
10, 11, 9, 118, 3, 4, 15, 16, 17, 5,
9, 3, 4, 1, 1, 5, 5, 9, 47, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 4, 43, 44, 45,
125, 39, 34, 42, 9, 41, 42, 9, 39, 47,
42, 41, 42, 42, 60, 41, 47, 5, 0, 47,
47, 47, 61, 62, 63, 64, 34, 3, 4, 61,
62, 63, 64, 9, 4, 160, 6, 7, 5, 9,
4, 39, 50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 4, 41, 42, 39, 41, 40, 34, 214,
39, 39, 47, 47, 34, 41, 42, 41, 47, 47,
34, 41, 42, 47, 121, 40, 41, 126, 4, 129,
39, 130, 34, 133, 39, 134, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 39, 47, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 34, 41,
157, 40, 40, 163, 4, 47, 166, 7, 8, 9,
39, 171, 41, 40, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 0, 1, 40, 47, 4, 43,
44, 7, 8, 9, 34, 11, 12, 13, 14, 15,
16, 17, 42, 3, 4, 1, 41, 9, 4, 9,
6, 7, 47, 9, 61, 62, 63, 64, 34, 35,
36, 37, 38, 9, 9, 40, 42, 10, 0, 1,
10, 47, 4, 10, 34, 7, 8, 9, 34, 11,
12, 13, 14, 15, 16, 17, 42, 4, 10, 4,
7, 8, 9, 4, 9, 6, 7, 45, 9, 40,
9, 40, 34, 35, 36, 37, 38, 40, 4, 4,
42, 7, 8, 9, 9, 47, 41, 34, 41, 34,
41, 41, 39, 34, 40, 42, 40, 42, 46, 41,
4, 42, 6, 7, 40, 9, 40, 40, 34, 34,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
40, 40, 40, 40, 40, 9, 9, 9, 9, 9,
34, 9, 9, 9, 9, 21, 104, 137, 40, 182,
50, 107, 116, 56, 126, 122, 134, 130, 18, 92,
192, 216, 187
};
static const yytype_int8 yystos[] =
{
0, 1, 4, 7, 8, 9, 11, 12, 13, 14,
15, 16, 17, 34, 35, 36, 37, 38, 42, 47,
66, 67, 68, 69, 70, 114, 115, 116, 47, 9,
9, 5, 42, 71, 72, 4, 6, 7, 9, 34,
42, 75, 76, 103, 114, 114, 3, 4, 9, 34,
42, 61, 62, 63, 64, 79, 80, 81, 82, 99,
107, 4, 34, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 95, 96, 100, 101, 4, 96, 104,
105, 4, 96, 111, 112, 4, 96, 108, 109, 116,
0, 68, 41, 73, 74, 103, 1, 47, 1, 47,
40, 43, 44, 5, 41, 47, 76, 41, 71, 71,
71, 99, 39, 39, 39, 39, 41, 82, 41, 71,
102, 40, 39, 47, 106, 40, 39, 47, 113, 40,
39, 47, 110, 40, 39, 47, 115, 39, 47, 40,
47, 47, 9, 9, 9, 72, 75, 47, 47, 47,
10, 10, 10, 10, 79, 81, 47, 40, 103, 101,
40, 107, 105, 40, 114, 112, 40, 114, 109, 1,
74, 45, 77, 78, 93, 103, 107, 114, 114, 39,
94, 114, 41, 97, 4, 9, 34, 42, 117, 118,
119, 46, 39, 78, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 98, 119, 41, 117, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 81, 118, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9
};
static const yytype_int8 yyr1[] =
{
0, 65, 66, 66, 67, 67, 68, 68, 68, 68,
68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
69, 69, 70, 70, 71, 71, 72, 72, 72, 72,
72, 73, 73, 73, 74, 75, 75, 76, 76, 76,
76, 76, 77, 77, 78, 79, 79, 79, 79, 80,
80, 81, 81, 82, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 93, 94, 94, 94,
94, 94, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 96, 97, 97, 97, 97, 97, 97,
97, 97, 97, 97, 97, 98, 98, 98, 98, 98,
98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
98, 98, 99, 99, 99, 99, 100, 100, 102, 101,
101, 103, 103, 104, 104, 106, 105, 105, 107, 107,
108, 108, 110, 109, 109, 111, 111, 113, 112, 112,
114, 114, 115, 115, 116, 116, 116, 116, 116, 117,
117, 118, 118, 119, 119, 119
};
static const yytype_int8 yyr2[] =
{
0, 2, 0, 1, 1, 2, 1, 2, 1, 1,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
3, 4, 3, 4, 1, 3, 1, 2, 3, 3,
3, 1, 3, 3, 3, 1, 2, 1, 1, 1,
1, 1, 1, 3, 4, 3, 3, 3, 3, 1,
3, 1, 2, 1, 2, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 0, 3, 0, 1, 3,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 1, 1, 1, 1, 1, 3, 0, 4,
3, 1, 3, 1, 3, 0, 4, 3, 1, 3,
1, 3, 0, 4, 3, 1, 3, 0, 4, 3,
1, 3, 1, 2, 1, 1, 1, 1, 1, 1,
3, 1, 2, 1, 1, 1
};
enum { YYENOMEM = -2 };
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \
do \
if (yychar == YYEMPTY) \
{ \
yychar = (Token); \
yylval = (Value); \
YYPOPSTACK (yylen); \
yystate = *yyssp; \
goto yybackup; \
} \
else \
{ \
yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (0)
#define YYERRCODE YYUNDEF
#if YYDEBUG
# ifndef YYFPRINTF
# include <stdio.h>
# define YYFPRINTF fprintf
# endif
# define YYDPRINTF(Args) \
do { \
if (yydebug) \
YYFPRINTF Args; \
} while (0)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Kind, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
static void
yy_symbol_value_print (FILE *yyo,
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
FILE *yyoutput = yyo;
YY_USE (yyoutput);
if (!yyvaluep)
return;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
static void
yy_symbol_print (FILE *yyo,
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
YYFPRINTF (yyo, "%s %s (",
yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
yy_symbol_value_print (yyo, yykind, yyvaluep);
YYFPRINTF (yyo, ")");
}
static void
yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
{
int yybot = *yybottom;
YYFPRINTF (stderr, " %d", yybot);
}
YYFPRINTF (stderr, "\n");
}
# define YY_STACK_PRINT(Bottom, Top) \
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
} while (0)
static void
yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
int yyrule)
{
int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
yyrule - 1, yylno);
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
&yyvsp[(yyi + 1) - (yynrhs)]);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
yy_reduce_print (yyssp, yyvsp, Rule); \
} while (0)
int yydebug;
#else
# define YYDPRINTF(Args) ((void) 0)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
{
YY_USE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
int yychar;
YYSTYPE yylval;
int yynerrs;
int
yyparse (void)
{
yy_state_fast_t yystate = 0;
int yyerrstatus = 0;
YYPTRDIFF_T yystacksize = YYINITDEPTH;
yy_state_t yyssa[YYINITDEPTH];
yy_state_t *yyss = yyssa;
yy_state_t *yyssp = yyss;
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
YYSTYPE *yyvsp = yyvs;
int yyn;
int yyresult;
yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
YYSTYPE yyval;
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY;
goto yysetstate;
yynewstate:
yyssp++;
yysetstate:
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
YY_IGNORE_USELESS_CAST_BEGIN
*yyssp = YY_CAST (yy_state_t, yystate);
YY_IGNORE_USELESS_CAST_END
YY_STACK_PRINT (yyss, yyssp);
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
YYNOMEM;
#else
{
YYPTRDIFF_T yysize = yyssp - yyss + 1;
# if defined yyoverflow
{
yy_state_t *yyss1 = yyss;
YYSTYPE *yyvs1 = yyvs;
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * YYSIZEOF (*yyssp),
&yyvs1, yysize * YYSIZEOF (*yyvsp),
&yystacksize);
yyss = yyss1;
yyvs = yyvs1;
}
# else
if (YYMAXDEPTH <= yystacksize)
YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
yy_state_t *yyss1 = yyss;
union yyalloc *yyptr =
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YY_IGNORE_USELESS_CAST_BEGIN
YYDPRINTF ((stderr, "Stack size increased to %ld\n",
YY_CAST (long, yystacksize)));
YY_IGNORE_USELESS_CAST_END
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
#endif
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
yybackup:
yyn = yypact[yystate];
if (yypact_value_is_default (yyn))
goto yydefault;
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token\n"));
yychar = yylex ();
}
if (yychar <= YYEOF)
{
yychar = YYEOF;
yytoken = YYSYMBOL_YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else if (yychar == YYerror)
{
yychar = YYUNDEF;
yytoken = YYSYMBOL_YYerror;
goto yyerrlab1;
}
else
{
yytoken = YYTRANSLATE (yychar);
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
yyn += yytoken;
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault;
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
if (yyerrstatus)
yyerrstatus--;
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
yystate = yyn;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
yychar = YYEMPTY;
goto yynewstate;
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
goto yyreduce;
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen];
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
case 2:
#line 205 "gram.y"
{
;
}
#line 1654 "gram.c"
break;
case 6:
#line 215 "gram.y"
{
;
}
#line 1662 "gram.c"
break;
case 7:
#line 218 "gram.y"
{
yyerrok;
}
#line 1670 "gram.c"
break;
case 8:
#line 221 "gram.y"
{
const bool success = push_include((yyvsp[0].string),
parsed_policy.ctx->user.shost, &parser_conf);
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
if (!success && !parser_conf.recovery)
YYERROR;
}
#line 1683 "gram.c"
break;
case 9:
#line 229 "gram.y"
{
const bool success = push_includedir((yyvsp[0].string),
parsed_policy.ctx->user.shost, &parser_conf);
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
if (!success && !parser_conf.recovery)
YYERROR;
}
#line 1696 "gram.c"
break;
case 10:
#line 237 "gram.y"
{
if (!add_userspec((yyvsp[-2].member), (yyvsp[-1].privilege))) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
}
#line 1707 "gram.c"
break;
case 11:
#line 243 "gram.y"
{
;
}
#line 1715 "gram.c"
break;
case 12:
#line 246 "gram.y"
{
;
}
#line 1723 "gram.c"
break;
case 13:
#line 249 "gram.y"
{
;
}
#line 1731 "gram.c"
break;
case 14:
#line 252 "gram.y"
{
;
}
#line 1739 "gram.c"
break;
case 15:
#line 255 "gram.y"
{
if (!add_defaults(DEFAULTS, NULL, (yyvsp[-1].defaults)))
YYERROR;
}
#line 1748 "gram.c"
break;
case 16:
#line 259 "gram.y"
{
if (!add_defaults(DEFAULTS_USER, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
#line 1757 "gram.c"
break;
case 17:
#line 263 "gram.y"
{
if (!add_defaults(DEFAULTS_RUNAS, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
#line 1766 "gram.c"
break;
case 18:
#line 267 "gram.y"
{
if (!add_defaults(DEFAULTS_HOST, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
#line 1775 "gram.c"
break;
case 19:
#line 271 "gram.y"
{
if (!add_defaults(DEFAULTS_CMND, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
#line 1784 "gram.c"
break;
case 20:
#line 277 "gram.y"
{
(yyval.string) = (yyvsp[-1].string);
}
#line 1792 "gram.c"
break;
case 21:
#line 280 "gram.y"
{
yyerrok;
(yyval.string) = (yyvsp[-2].string);
}
#line 1801 "gram.c"
break;
case 22:
#line 286 "gram.y"
{
(yyval.string) = (yyvsp[-1].string);
}
#line 1809 "gram.c"
break;
case 23:
#line 289 "gram.y"
{
yyerrok;
(yyval.string) = (yyvsp[-2].string);
}
#line 1818 "gram.c"
break;
case 25:
#line 296 "gram.y"
{
parser_leak_remove(LEAK_DEFAULTS, (yyvsp[0].defaults));
HLTQ_CONCAT((yyvsp[-2].defaults), (yyvsp[0].defaults), entries);
(yyval.defaults) = (yyvsp[-2].defaults);
}
#line 1828 "gram.c"
break;
case 26:
#line 303 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[0].string), NULL, true);
if ((yyval.defaults) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
#line 1842 "gram.c"
break;
case 27:
#line 312 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[0].string), NULL, false);
if ((yyval.defaults) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
#line 1856 "gram.c"
break;
case 28:
#line 321 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), true);
if ((yyval.defaults) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
#line 1871 "gram.c"
break;
case 29:
#line 331 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '+');
if ((yyval.defaults) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
#line 1886 "gram.c"
break;
case 30:
#line 341 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '-');
if ((yyval.defaults) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
#line 1901 "gram.c"
break;
case 32:
#line 354 "gram.y"
{
parser_leak_remove(LEAK_PRIVILEGE, (yyvsp[0].privilege));
HLTQ_CONCAT((yyvsp[-2].privilege), (yyvsp[0].privilege), entries);
(yyval.privilege) = (yyvsp[-2].privilege);
}
#line 1911 "gram.c"
break;
case 33:
#line 359 "gram.y"
{
yyerrok;
(yyval.privilege) = (yyvsp[-2].privilege);
}
#line 1920 "gram.c"
break;
case 34:
#line 365 "gram.y"
{
struct privilege *p = calloc(1, sizeof(*p));
if (p == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_PRIVILEGE, p);
TAILQ_INIT(&p->defaults);
parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member));
HLTQ_TO_TAILQ(&p->hostlist, (yyvsp[-2].member), entries);
parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec));
HLTQ_TO_TAILQ(&p->cmndlist, (yyvsp[0].cmndspec), entries);
HLTQ_INIT(p, entries);
(yyval.privilege) = p;
}
#line 1940 "gram.c"
break;
case 35:
#line 382 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
#line 1949 "gram.c"
break;
case 36:
#line 386 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
#line 1958 "gram.c"
break;
case 37:
#line 392 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 1972 "gram.c"
break;
case 38:
#line 401 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 1985 "gram.c"
break;
case 39:
#line 409 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 1999 "gram.c"
break;
case 40:
#line 418 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NTWKADDR);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 2013 "gram.c"
break;
case 41:
#line 427 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 2027 "gram.c"
break;
case 43:
#line 439 "gram.y"
{
const struct cmndspec *prev =
HLTQ_LAST((yyvsp[-2].cmndspec), cmndspec, entries);
propagate_cmndspec((yyvsp[0].cmndspec), prev);
parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec));
HLTQ_CONCAT((yyvsp[-2].cmndspec), (yyvsp[0].cmndspec), entries);
(yyval.cmndspec) = (yyvsp[-2].cmndspec);
}
#line 2040 "gram.c"
break;
case 44:
#line 449 "gram.y"
{
struct cmndspec *cs = calloc(1, sizeof(*cs));
if (cs == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_CMNDSPEC, cs);
if ((yyvsp[-3].runas) != NULL) {
if ((yyvsp[-3].runas)->runasusers != NULL) {
cs->runasuserlist =
malloc(sizeof(*cs->runasuserlist));
if (cs->runasuserlist == NULL) {
free(cs);
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
HLTQ_TO_TAILQ(cs->runasuserlist,
(yyvsp[-3].runas)->runasusers, entries);
}
if ((yyvsp[-3].runas)->runasgroups != NULL) {
cs->runasgrouplist =
malloc(sizeof(*cs->runasgrouplist));
if (cs->runasgrouplist == NULL) {
free(cs);
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
HLTQ_TO_TAILQ(cs->runasgrouplist,
(yyvsp[-3].runas)->runasgroups, entries);
}
parser_leak_remove(LEAK_RUNAS, (yyvsp[-3].runas));
free((yyvsp[-3].runas));
}
cs->role = (yyvsp[-2].options).role;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).role);
cs->type = (yyvsp[-2].options).type;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).type);
cs->apparmor_profile = (yyvsp[-2].options).apparmor_profile;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).apparmor_profile);
cs->privs = (yyvsp[-2].options).privs;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).privs);
cs->limitprivs = (yyvsp[-2].options).limitprivs;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).limitprivs);
cs->notbefore = (yyvsp[-2].options).notbefore;
cs->notafter = (yyvsp[-2].options).notafter;
cs->timeout = (yyvsp[-2].options).timeout;
cs->runcwd = (yyvsp[-2].options).runcwd;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runcwd);
cs->runchroot = (yyvsp[-2].options).runchroot;
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runchroot);
cs->tags = (yyvsp[-1].tag);
cs->cmnd = (yyvsp[0].member);
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_INIT(cs, entries);
if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
cs->tags.setenv == UNSPEC)
cs->tags.setenv = IMPLIED;
(yyval.cmndspec) = cs;
}
#line 2107 "gram.c"
break;
case 45:
#line 513 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
#line 2121 "gram.c"
break;
case 46:
#line 522 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
#line 2135 "gram.c"
break;
case 47:
#line 531 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
#line 2149 "gram.c"
break;
case 48:
#line 540 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
#line 2163 "gram.c"
break;
case 50:
#line 552 "gram.y"
{
parser_leak_remove(LEAK_DIGEST, (yyvsp[0].digest));
HLTQ_CONCAT((yyvsp[-2].digest), (yyvsp[0].digest), entries);
(yyval.digest) = (yyvsp[-2].digest);
}
#line 2173 "gram.c"
break;
case 51:
#line 559 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
}
#line 2181 "gram.c"
break;
case 52:
#line 562 "gram.y"
{
struct sudo_command *c =
(struct sudo_command *) (yyvsp[0].member)->name;
if ((yyvsp[0].member)->type != COMMAND && (yyvsp[0].member)->type != ALL) {
sudoerserror(N_("a digest requires a path name"));
YYERROR;
}
parser_leak_remove(LEAK_DIGEST, (yyvsp[-1].digest));
HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries);
(yyval.member) = (yyvsp[0].member);
}
#line 2198 "gram.c"
break;
case 53:
#line 576 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
#line 2207 "gram.c"
break;
case 54:
#line 580 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
#line 2216 "gram.c"
break;
case 55:
#line 586 "gram.y"
{
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
if (strcmp((yyvsp[0].string), "*") != 0) {
sudoerserror(N_("values for \"CWD\" must"
" start with a '/', '~', or '*'"));
YYERROR;
}
}
if (strlen((yyvsp[0].string)) >= PATH_MAX) {
sudoerserror(N_("\"CWD\" path too long"));
YYERROR;
}
(yyval.string) = (yyvsp[0].string);
}
#line 2235 "gram.c"
break;
case 56:
#line 602 "gram.y"
{
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
if (strcmp((yyvsp[0].string), "*") != 0) {
sudoerserror(N_("values for \"CHROOT\" must"
" start with a '/', '~', or '*'"));
YYERROR;
}
}
if (strlen((yyvsp[0].string)) >= PATH_MAX) {
sudoerserror(N_("\"CHROOT\" path too long"));
YYERROR;
}
if (parser_conf.strict > 2) {
sudoerserror(N_("\"CHROOT\" is deprecated"));
YYERROR;
} else if (parser_conf.verbose > 0) {
parser_warnx(parsed_policy.ctx, sudoers, this_lineno, sudolinebuf.toke_start + 1, false, false, N_("\"CHROOT\" is deprecated"));
}
(yyval.string) = (yyvsp[0].string);
}
#line 2260 "gram.c"
break;
case 57:
#line 624 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2268 "gram.c"
break;
case 58:
#line 629 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2276 "gram.c"
break;
case 59:
#line 633 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2284 "gram.c"
break;
case 60:
#line 638 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2292 "gram.c"
break;
case 61:
#line 643 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2300 "gram.c"
break;
case 62:
#line 648 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2308 "gram.c"
break;
case 63:
#line 653 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2316 "gram.c"
break;
case 64:
#line 657 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
#line 2324 "gram.c"
break;
case 65:
#line 662 "gram.y"
{
(yyval.runas) = NULL;
}
#line 2332 "gram.c"
break;
case 66:
#line 665 "gram.y"
{
(yyval.runas) = (yyvsp[-1].runas);
}
#line 2340 "gram.c"
break;
case 67:
#line 670 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) != NULL) {
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
if ((yyval.runas)->runasusers == NULL) {
free((yyval.runas));
(yyval.runas) = NULL;
}
}
if ((yyval.runas) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
}
#line 2362 "gram.c"
break;
case 68:
#line 687 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
(yyval.runas)->runasusers = (yyvsp[0].member);
}
#line 2379 "gram.c"
break;
case 69:
#line 699 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
(yyval.runas)->runasusers = (yyvsp[-2].member);
(yyval.runas)->runasgroups = (yyvsp[0].member);
}
#line 2400 "gram.c"
break;
case 70:
#line 715 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) != NULL) {
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
if ((yyval.runas)->runasusers == NULL) {
free((yyval.runas));
(yyval.runas) = NULL;
}
}
if ((yyval.runas) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
(yyval.runas)->runasgroups = (yyvsp[0].member);
}
#line 2423 "gram.c"
break;
case 71:
#line 733 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) != NULL) {
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
if ((yyval.runas)->runasusers == NULL) {
free((yyval.runas));
(yyval.runas) = NULL;
}
}
if ((yyval.runas) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
}
#line 2445 "gram.c"
break;
case 72:
#line 752 "gram.y"
{ (yyval.cstring) = "ALL"; }
#line 2451 "gram.c"
break;
case 73:
#line 753 "gram.y"
{ (yyval.cstring) = "CHROOT"; }
#line 2457 "gram.c"
break;
case 74:
#line 754 "gram.y"
{ (yyval.cstring) = "CWD"; }
#line 2463 "gram.c"
break;
case 75:
#line 755 "gram.y"
{ (yyval.cstring) = "CMND_TIMEOUT"; }
#line 2469 "gram.c"
break;
case 76:
#line 756 "gram.y"
{ (yyval.cstring) = "NOTBEFORE"; }
#line 2475 "gram.c"
break;
case 77:
#line 757 "gram.y"
{ (yyval.cstring) = "NOTAFTER"; }
#line 2481 "gram.c"
break;
case 78:
#line 758 "gram.y"
{ (yyval.cstring) = "ROLE"; }
#line 2487 "gram.c"
break;
case 79:
#line 759 "gram.y"
{ (yyval.cstring) = "TYPE"; }
#line 2493 "gram.c"
break;
case 80:
#line 760 "gram.y"
{ (yyval.cstring) = "PRIVS"; }
#line 2499 "gram.c"
break;
case 81:
#line 761 "gram.y"
{ (yyval.cstring) = "LIMITPRIVS"; }
#line 2505 "gram.c"
break;
case 82:
#line 762 "gram.y"
{ (yyval.cstring) = "APPARMOR_PROFILE"; }
#line 2511 "gram.c"
break;
case 83:
#line 765 "gram.y"
{
sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].cstring));
YYERROR;
}
#line 2520 "gram.c"
break;
case 84:
#line 771 "gram.y"
{
init_options(&(yyval.options));
}
#line 2528 "gram.c"
break;
case 85:
#line 774 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).runcwd);
free((yyval.options).runcwd);
(yyval.options).runcwd = (yyvsp[0].string);
}
#line 2538 "gram.c"
break;
case 86:
#line 779 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).runchroot);
free((yyval.options).runchroot);
(yyval.options).runchroot = (yyvsp[0].string);
}
#line 2548 "gram.c"
break;
case 87:
#line 784 "gram.y"
{
(yyval.options).notbefore = parse_gentime((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
if ((yyval.options).notbefore == -1) {
sudoerserror(N_("invalid notbefore value"));
YYERROR;
}
}
#line 2562 "gram.c"
break;
case 88:
#line 793 "gram.y"
{
(yyval.options).notafter = parse_gentime((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
if ((yyval.options).notafter == -1) {
sudoerserror(N_("invalid notafter value"));
YYERROR;
}
}
#line 2576 "gram.c"
break;
case 89:
#line 802 "gram.y"
{
(yyval.options).timeout = parse_timeout((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
if ((yyval.options).timeout == -1) {
if (errno == ERANGE)
sudoerserror(N_("timeout value too large"));
else
sudoerserror(N_("invalid timeout value"));
YYERROR;
}
}
#line 2593 "gram.c"
break;
case 90:
#line 814 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).role);
free((yyval.options).role);
(yyval.options).role = (yyvsp[0].string);
}
#line 2603 "gram.c"
break;
case 91:
#line 819 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).type);
free((yyval.options).type);
(yyval.options).type = (yyvsp[0].string);
}
#line 2613 "gram.c"
break;
case 92:
#line 824 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).apparmor_profile);
free((yyval.options).apparmor_profile);
(yyval.options).apparmor_profile = (yyvsp[0].string);
}
#line 2623 "gram.c"
break;
case 93:
#line 829 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).privs);
free((yyval.options).privs);
(yyval.options).privs = (yyvsp[0].string);
}
#line 2633 "gram.c"
break;
case 94:
#line 834 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).limitprivs);
free((yyval.options).limitprivs);
(yyval.options).limitprivs = (yyvsp[0].string);
}
#line 2643 "gram.c"
break;
case 95:
#line 841 "gram.y"
{
TAGS_INIT(&(yyval.tag));
}
#line 2651 "gram.c"
break;
case 96:
#line 844 "gram.y"
{
(yyval.tag).nopasswd = true;
}
#line 2659 "gram.c"
break;
case 97:
#line 847 "gram.y"
{
(yyval.tag).nopasswd = false;
}
#line 2667 "gram.c"
break;
case 98:
#line 850 "gram.y"
{
(yyval.tag).noexec = true;
}
#line 2675 "gram.c"
break;
case 99:
#line 853 "gram.y"
{
(yyval.tag).noexec = false;
}
#line 2683 "gram.c"
break;
case 100:
#line 856 "gram.y"
{
(yyval.tag).intercept = true;
}
#line 2691 "gram.c"
break;
case 101:
#line 859 "gram.y"
{
(yyval.tag).intercept = false;
}
#line 2699 "gram.c"
break;
case 102:
#line 862 "gram.y"
{
(yyval.tag).setenv = true;
}
#line 2707 "gram.c"
break;
case 103:
#line 865 "gram.y"
{
(yyval.tag).setenv = false;
}
#line 2715 "gram.c"
break;
case 104:
#line 868 "gram.y"
{
(yyval.tag).log_input = true;
}
#line 2723 "gram.c"
break;
case 105:
#line 871 "gram.y"
{
(yyval.tag).log_input = false;
}
#line 2731 "gram.c"
break;
case 106:
#line 874 "gram.y"
{
(yyval.tag).log_output = true;
}
#line 2739 "gram.c"
break;
case 107:
#line 877 "gram.y"
{
(yyval.tag).log_output = false;
}
#line 2747 "gram.c"
break;
case 108:
#line 880 "gram.y"
{
(yyval.tag).follow = true;
}
#line 2755 "gram.c"
break;
case 109:
#line 883 "gram.y"
{
(yyval.tag).follow = false;
}
#line 2763 "gram.c"
break;
case 110:
#line 886 "gram.y"
{
(yyval.tag).send_mail = true;
}
#line 2771 "gram.c"
break;
case 111:
#line 889 "gram.y"
{
(yyval.tag).send_mail = false;
}
#line 2779 "gram.c"
break;
case 112:
#line 894 "gram.y"
{
struct sudo_command *c;
if ((c = new_command(NULL, NULL)) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
(yyval.member) = new_member((char *)c, ALL);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 2798 "gram.c"
break;
case 113:
#line 908 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 2812 "gram.c"
break;
case 114:
#line 917 "gram.y"
{
struct sudo_command *c;
if (strlen((yyvsp[0].command).cmnd) >= PATH_MAX) {
sudoerserror(N_("command too long"));
YYERROR;
}
if ((c = new_command((yyvsp[0].command).cmnd, (yyvsp[0].command).args)) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
(yyval.member) = new_member((char *)c, COMMAND);
if ((yyval.member) == NULL) {
free(c);
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].command).cmnd);
parser_leak_remove(LEAK_PTR, (yyvsp[0].command).args);
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 2838 "gram.c"
break;
case 115:
#line 938 "gram.y"
{
if (strcmp((yyvsp[0].string), "list") == 0) {
struct sudo_command *c;
if ((c = new_command((yyvsp[0].string), NULL)) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
(yyval.member) = new_member((char *)c, COMMAND);
if ((yyval.member) == NULL) {
free(c);
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
} else {
sudoerserror(N_("expected a fully-qualified path name"));
YYERROR;
}
}
#line 2864 "gram.c"
break;
case 118:
#line 965 "gram.y"
{
alias_line = this_lineno;
alias_column = (int)sudolinebuf.toke_start + 1;
}
#line 2873 "gram.c"
break;
case 119:
#line 968 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), HOSTALIAS, errno);
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
#line 2887 "gram.c"
break;
case 122:
#line 981 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
#line 2897 "gram.c"
break;
case 125:
#line 992 "gram.y"
{
alias_line = this_lineno;
alias_column = (int)sudolinebuf.toke_start + 1;
}
#line 2906 "gram.c"
break;
case 126:
#line 995 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), CMNDALIAS, errno);
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
#line 2920 "gram.c"
break;
case 129:
#line 1008 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
#line 2930 "gram.c"
break;
case 132:
#line 1019 "gram.y"
{
alias_line = this_lineno;
alias_column = (int)sudolinebuf.toke_start + 1;
}
#line 2939 "gram.c"
break;
case 133:
#line 1022 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), RUNASALIAS, errno);
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
#line 2953 "gram.c"
break;
case 137:
#line 1038 "gram.y"
{
alias_line = this_lineno;
alias_column = (int)sudolinebuf.toke_start + 1;
}
#line 2962 "gram.c"
break;
case 138:
#line 1041 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), USERALIAS, errno);
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
#line 2976 "gram.c"
break;
case 141:
#line 1054 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
#line 2986 "gram.c"
break;
case 142:
#line 1061 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
#line 2995 "gram.c"
break;
case 143:
#line 1065 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
#line 3004 "gram.c"
break;
case 144:
#line 1071 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3018 "gram.c"
break;
case 145:
#line 1080 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3031 "gram.c"
break;
case 146:
#line 1088 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3045 "gram.c"
break;
case 147:
#line 1097 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), USERGROUP);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3059 "gram.c"
break;
case 148:
#line 1106 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3073 "gram.c"
break;
case 150:
#line 1118 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
#line 3083 "gram.c"
break;
case 151:
#line 1125 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
#line 3092 "gram.c"
break;
case 152:
#line 1129 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
#line 3101 "gram.c"
break;
case 153:
#line 1135 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3115 "gram.c"
break;
case 154:
#line 1144 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3128 "gram.c"
break;
case 155:
#line 1152 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
#line 3142 "gram.c"
break;
#line 3146 "gram.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
YYPOPSTACK (yylen);
yylen = 0;
*++yyvsp = yyval;
{
const int yylhs = yyr1[yyn] - YYNTOKENS;
const int yyi = yypgoto[yylhs] + *yyssp;
yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
? yytable[yyi]
: yydefgoto[yylhs]);
}
goto yynewstate;
yyerrlab:
yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
if (!yyerrstatus)
{
++yynerrs;
yyerror (YY_("syntax error"));
}
if (yyerrstatus == 3)
{
if (yychar <= YYEOF)
{
if (yychar == YYEOF)
YYABORT;
}
else
{
yydestruct ("Error: discarding",
yytoken, &yylval);
yychar = YYEMPTY;
}
}
goto yyerrlab1;
yyerrorlab:
if (0)
YYERROR;
++yynerrs;
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
yyerrlab1:
yyerrstatus = 3;
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
yyn += YYSYMBOL_YYerror;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
if (yyssp == yyss)
YYABORT;
yydestruct ("Error: popping",
YY_ACCESSING_SYMBOL (yystate), yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
yystate = yyn;
goto yynewstate;
yyacceptlab:
yyresult = 0;
goto yyreturnlab;
yyabortlab:
yyresult = 1;
goto yyreturnlab;
yyexhaustedlab:
yyerror (YY_("memory exhausted"));
yyresult = 2;
goto yyreturnlab;
yyreturnlab:
if (yychar != YYEMPTY)
{
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
}
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
return yyresult;
}
#line 1162 "gram.y"
void
sudoerserrorf(const char * restrict fmt, ...)
{
const int column = (int)(sudolinebuf.toke_start + 1);
va_list ap;
debug_decl(sudoerserrorf, SUDOERS_DEBUG_PARSER);
if (sudoers_error_hook != NULL) {
va_start(ap, fmt);
sudoers_error_hook(parsed_policy.ctx, sudoers, this_lineno, column,
fmt, ap);
va_end(ap);
}
if (parser_conf.verbose > 0 && fmt != NULL) {
LEXTRACE("<*> ");
#ifndef TRACELEXER
if (trace_print == NULL || trace_print == sudoers_trace_print) {
char *tofree = NULL;
const char *s;
int oldlocale;
sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
va_start(ap, fmt);
if (strcmp(fmt, "%s") == 0) {
s = _(va_arg(ap, char *));
} else {
if (vasprintf(&tofree, _(fmt), ap) != -1) {
s = tofree;
} else {
s = _("syntax error");
tofree = NULL;
}
}
sudo_printf(SUDO_CONV_ERROR_MSG, _("%s:%d:%zu: %s\n"), sudoers,
this_lineno, sudolinebuf.toke_start + 1, s);
free(tofree);
va_end(ap);
sudoers_setlocale(oldlocale, NULL);
if (sudolinebuf.len != 0) {
char tildes[128];
size_t tlen = 0;
sudo_printf(SUDO_CONV_ERROR_MSG, "%s%s", sudolinebuf.buf,
sudolinebuf.buf[sudolinebuf.len - 1] == '\n' ? "" : "\n");
if (sudolinebuf.toke_end > sudolinebuf.toke_start) {
tlen = sudolinebuf.toke_end - sudolinebuf.toke_start - 1;
if (tlen >= sizeof(tildes))
tlen = sizeof(tildes) - 1;
memset(tildes, '~', tlen);
}
tildes[tlen] = '\0';
sudo_printf(SUDO_CONV_ERROR_MSG, "%*s^%s\n",
(int)sudolinebuf.toke_start, "", tildes);
}
}
#endif
}
parse_error = true;
debug_return;
}
void
sudoerserror(const char *s)
{
if (sudoerschar == ERROR) {
s = sudoers_errstr;
sudoers_errstr = NULL;
}
#pragma pvs(push)
#pragma pvs(disable: 575, 618)
if (s == NULL)
sudoerserrorf(NULL);
else
sudoerserrorf("%s", s);
#pragma pvs(pop)
}
static void
alias_error(const char *name, short type, int errnum)
{
if (errnum == EEXIST) {
struct alias *a = alias_get(&parsed_policy, name, type);
if (a != NULL) {
sudoerserrorf(
U_("duplicate %s \"%s\", previously defined at %s:%d:%d"),
alias_type_to_string(type), name, a->file, a->line, a->column);
alias_put(a);
} else {
if (errno == ELOOP) {
sudoerserrorf(U_("cycle in %s \"%s\""),
alias_type_to_string(type), name);
} else {
sudoerserrorf(U_("duplicate %s \"%s\""),
alias_type_to_string(type), name);
}
}
} else {
sudoerserror(N_("unable to allocate memory"));
}
}
static struct defaults *
new_default(char *var, char *val, short op)
{
struct defaults *d;
debug_decl(new_default, SUDOERS_DEBUG_PARSER);
if ((d = calloc(1, sizeof(struct defaults))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
d->var = var;
d->val = val;
d->op = op;
d->line = this_lineno;
d->column = (int)(sudolinebuf.toke_start + 1);
d->file = sudo_rcstr_addref(sudoers);
HLTQ_INIT(d, entries);
debug_return_ptr(d);
}
static struct member *
new_member(char *name, short type)
{
struct member *m;
debug_decl(new_member, SUDOERS_DEBUG_PARSER);
if ((m = calloc(1, sizeof(struct member))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
m->name = name;
m->type = type;
HLTQ_INIT(m, entries);
debug_return_ptr(m);
}
static struct sudo_command *
new_command(char *cmnd, char *args)
{
struct sudo_command *c;
debug_decl(new_command, SUDOERS_DEBUG_PARSER);
if ((c = calloc(1, sizeof(*c))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
c->cmnd = cmnd;
c->args = args;
TAILQ_INIT(&c->digests);
debug_return_ptr(c);
}
static struct command_digest *
new_digest(unsigned int digest_type, char *digest_str)
{
struct command_digest *digest;
debug_decl(new_digest, SUDOERS_DEBUG_PARSER);
if ((digest = malloc(sizeof(*digest))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
HLTQ_INIT(digest, entries);
digest->digest_type = digest_type;
digest->digest_str = digest_str;
if (digest->digest_str == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
free(digest);
digest = NULL;
}
debug_return_ptr(digest);
}
static void
free_defaults_binding(struct defaults_binding *binding)
{
debug_decl(free_defaults_binding, SUDOERS_DEBUG_PARSER);
if (binding != NULL) {
if (--binding->refcnt == 0) {
free_members(&binding->members);
free(binding);
}
}
debug_return;
}
static bool
add_defaults(short type, struct member *bmem, struct defaults *defs)
{
struct defaults *d, *next;
struct defaults_binding *binding;
bool ret = true;
debug_decl(add_defaults, SUDOERS_DEBUG_PARSER);
if (defs == NULL)
debug_return_bool(false);
if ((binding = malloc(sizeof(*binding))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
sudoerserror(N_("unable to allocate memory"));
debug_return_bool(false);
}
if (bmem != NULL) {
parser_leak_remove(LEAK_MEMBER, bmem);
HLTQ_TO_TAILQ(&binding->members, bmem, entries);
} else {
TAILQ_INIT(&binding->members);
}
binding->refcnt = 0;
parser_leak_remove(LEAK_DEFAULTS, defs);
HLTQ_FOREACH_SAFE(d, defs, entries, next) {
d->type = type;
d->binding = binding;
binding->refcnt++;
TAILQ_INSERT_TAIL(&parsed_policy.defaults, d, entries);
}
debug_return_bool(ret);
}
static bool
add_userspec(struct member *members, struct privilege *privs)
{
struct userspec *u;
debug_decl(add_userspec, SUDOERS_DEBUG_PARSER);
if ((u = calloc(1, sizeof(*u))) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_bool(false);
}
u->line = sudolineno - 1;
u->column = (int)(sudolinebuf.toke_start + 1);
u->file = sudo_rcstr_addref(sudoers);
parser_leak_remove(LEAK_MEMBER, members);
HLTQ_TO_TAILQ(&u->users, members, entries);
parser_leak_remove(LEAK_PRIVILEGE, privs);
HLTQ_TO_TAILQ(&u->privileges, privs, entries);
STAILQ_INIT(&u->comments);
TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries);
debug_return_bool(true);
}
void
free_member(struct member *m)
{
debug_decl(free_member, SUDOERS_DEBUG_PARSER);
if (m->type == COMMAND || (m->type == ALL && m->name != NULL)) {
struct command_digest *digest;
struct sudo_command *c = (struct sudo_command *)m->name;
free(c->cmnd);
free(c->args);
while ((digest = TAILQ_FIRST(&c->digests)) != NULL) {
TAILQ_REMOVE(&c->digests, digest, entries);
free(digest->digest_str);
free(digest);
}
}
free(m->name);
free(m);
debug_return;
}
void
free_members(struct member_list *members)
{
struct member *m;
debug_decl(free_members, SUDOERS_DEBUG_PARSER);
while ((m = TAILQ_FIRST(members)) != NULL) {
TAILQ_REMOVE(members, m, entries);
free_member(m);
}
debug_return;
}
void
free_defaults(struct defaults_list *defs)
{
struct defaults *def;
debug_decl(free_defaults, SUDOERS_DEBUG_PARSER);
while ((def = TAILQ_FIRST(defs)) != NULL) {
TAILQ_REMOVE(defs, def, entries);
free_default(def);
}
debug_return;
}
void
free_default(struct defaults *def)
{
debug_decl(free_default, SUDOERS_DEBUG_PARSER);
free_defaults_binding(def->binding);
sudo_rcstr_delref(def->file);
free(def->var);
free(def->val);
free(def);
debug_return;
}
void
free_cmndspec(struct cmndspec *cs, struct cmndspec_list *csl)
{
struct cmndspec *prev, *next;
debug_decl(free_cmndspec, SUDOERS_DEBUG_PARSER);
prev = TAILQ_PREV(cs, cmndspec_list, entries);
next = TAILQ_NEXT(cs, entries);
TAILQ_REMOVE(csl, cs, entries);
if ((prev == NULL || cs->runcwd != prev->runcwd) &&
(next == NULL || cs->runcwd != next->runcwd)) {
free(cs->runcwd);
}
if ((prev == NULL || cs->runchroot != prev->runchroot) &&
(next == NULL || cs->runchroot != next->runchroot)) {
free(cs->runchroot);
}
if ((prev == NULL || cs->role != prev->role) &&
(next == NULL || cs->role != next->role)) {
free(cs->role);
}
if ((prev == NULL || cs->type != prev->type) &&
(next == NULL || cs->type != next->type)) {
free(cs->type);
}
if ((prev == NULL || cs->apparmor_profile != prev->apparmor_profile) &&
(next == NULL || cs->apparmor_profile != next->apparmor_profile)) {
free(cs->apparmor_profile);
}
if ((prev == NULL || cs->privs != prev->privs) &&
(next == NULL || cs->privs != next->privs)) {
free(cs->privs);
}
if ((prev == NULL || cs->limitprivs != prev->limitprivs) &&
(next == NULL || cs->limitprivs != next->limitprivs)) {
free(cs->limitprivs);
}
if (cs->runasuserlist != NULL) {
if ((prev == NULL || cs->runasuserlist != prev->runasuserlist) &&
(next == NULL || cs->runasuserlist != next->runasuserlist)) {
free_members(cs->runasuserlist);
free(cs->runasuserlist);
}
}
if (cs->runasgrouplist != NULL) {
if ((prev == NULL || cs->runasgrouplist != prev->runasgrouplist) &&
(next == NULL || cs->runasgrouplist != next->runasgrouplist)) {
free_members(cs->runasgrouplist);
free(cs->runasgrouplist);
}
}
free_member(cs->cmnd);
free(cs);
debug_return;
}
void
free_cmndspecs(struct cmndspec_list *csl)
{
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
char *runcwd = NULL, *runchroot = NULL;
char *role = NULL, *type = NULL;
char *apparmor_profile = NULL;
char *privs = NULL, *limitprivs = NULL;
struct cmndspec *cs;
debug_decl(free_cmndspecs, SUDOERS_DEBUG_PARSER);
while ((cs = TAILQ_FIRST(csl)) != NULL) {
TAILQ_REMOVE(csl, cs, entries);
if (cs->runcwd != runcwd) {
runcwd = cs->runcwd;
free(cs->runcwd);
}
if (cs->runchroot != runchroot) {
runchroot = cs->runchroot;
free(cs->runchroot);
}
if (cs->role != role) {
role = cs->role;
free(cs->role);
}
if (cs->type != type) {
type = cs->type;
free(cs->type);
}
if (cs->apparmor_profile != apparmor_profile) {
apparmor_profile = cs->apparmor_profile;
free(cs->apparmor_profile);
}
if (cs->privs != privs) {
privs = cs->privs;
free(cs->privs);
}
if (cs->limitprivs != limitprivs) {
limitprivs = cs->limitprivs;
free(cs->limitprivs);
}
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
runasuserlist = cs->runasuserlist;
free_members(runasuserlist);
free(runasuserlist);
}
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
runasgrouplist = cs->runasgrouplist;
free_members(runasgrouplist);
free(runasgrouplist);
}
free_member(cs->cmnd);
free(cs);
}
debug_return;
}
void
free_privilege(struct privilege *priv)
{
struct defaults *def;
debug_decl(free_privilege, SUDOERS_DEBUG_PARSER);
free(priv->ldap_role);
free_members(&priv->hostlist);
free_cmndspecs(&priv->cmndlist);
while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
TAILQ_REMOVE(&priv->defaults, def, entries);
free_default(def);
}
free(priv);
debug_return;
}
void
free_userspecs(struct userspec_list *usl)
{
struct userspec *us;
debug_decl(free_userspecs, SUDOERS_DEBUG_PARSER);
while ((us = TAILQ_FIRST(usl)) != NULL) {
TAILQ_REMOVE(usl, us, entries);
free_userspec(us);
}
debug_return;
}
void
free_userspec(struct userspec *us)
{
struct privilege *priv;
struct sudoers_comment *comment;
debug_decl(free_userspec, SUDOERS_DEBUG_PARSER);
free_members(&us->users);
while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
TAILQ_REMOVE(&us->privileges, priv, entries);
free_privilege(priv);
}
while ((comment = STAILQ_FIRST(&us->comments)) != NULL) {
STAILQ_REMOVE_HEAD(&us->comments, entries);
free(comment->str);
free(comment);
}
sudo_rcstr_delref(us->file);
free(us);
debug_return;
}
void
init_parse_tree(struct sudoers_parse_tree *parse_tree, char *lhost, char *shost,
struct sudoers_context *ctx, struct sudo_nss *nss)
{
TAILQ_INIT(&parse_tree->userspecs);
TAILQ_INIT(&parse_tree->defaults);
parse_tree->aliases = NULL;
parse_tree->shost = shost;
parse_tree->lhost = lhost;
parse_tree->ctx = ctx;
parse_tree->nss = nss;
}
void
reparent_parse_tree(struct sudoers_parse_tree *new_tree)
{
TAILQ_CONCAT(&new_tree->userspecs, &parsed_policy.userspecs, entries);
TAILQ_CONCAT(&new_tree->defaults, &parsed_policy.defaults, entries);
new_tree->aliases = parsed_policy.aliases;
parsed_policy.aliases = NULL;
}
void
free_parse_tree(struct sudoers_parse_tree *parse_tree)
{
free_userspecs(&parse_tree->userspecs);
free_defaults(&parse_tree->defaults);
free_aliases(parse_tree->aliases);
parse_tree->aliases = NULL;
free(parse_tree->lhost);
if (parse_tree->shost != parse_tree->lhost)
free(parse_tree->shost);
parse_tree->lhost = parse_tree->shost = NULL;
parse_tree->nss = NULL;
parse_tree->ctx = NULL;
}
bool
init_parser(struct sudoers_context *ctx, const char *file)
{
bool ret = true;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER);
free_parse_tree(&parsed_policy);
parsed_policy.ctx = ctx;
parser_leak_init();
init_lexer();
parse_error = false;
if (ctx != NULL) {
parser_conf = ctx->parser_conf;
} else {
const struct sudoers_parser_config def_conf =
SUDOERS_PARSER_CONFIG_INITIALIZER;
parser_conf = def_conf;
}
sudo_rcstr_delref(sudoers);
if (file != NULL) {
if ((sudoers = sudo_rcstr_dup(file)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
ret = false;
}
} else {
sudoers = NULL;
}
sudo_rcstr_delref(sudoers_search_path);
if (parser_conf.sudoers_path != NULL) {
sudoers_search_path = sudo_rcstr_dup(parser_conf.sudoers_path);
if (sudoers_search_path == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
ret = false;
}
} else {
sudoers_search_path = NULL;
}
debug_return_bool(ret);
}
bool
reset_parser(void)
{
return init_parser(NULL, NULL);
}
static void
init_options(struct command_options *opts)
{
opts->notbefore = UNSPEC;
opts->notafter = UNSPEC;
opts->timeout = UNSPEC;
opts->runchroot = NULL;
opts->runcwd = NULL;
opts->role = NULL;
opts->type = NULL;
opts->apparmor_profile = NULL;
opts->privs = NULL;
opts->limitprivs = NULL;
}
static void
propagate_cmndspec(struct cmndspec *cs, const struct cmndspec *prev)
{
if (cs->runcwd == NULL)
cs->runcwd = prev->runcwd;
if (cs->runchroot == NULL)
cs->runchroot = prev->runchroot;
if (cs->role == NULL && cs->type == NULL) {
cs->role = prev->role;
cs->type = prev->type;
}
if (cs->apparmor_profile == NULL)
cs->apparmor_profile = prev->apparmor_profile;
if (cs->privs == NULL && cs->limitprivs == NULL) {
cs->privs = prev->privs;
cs->limitprivs = prev->limitprivs;
}
if (cs->notbefore == UNSPEC)
cs->notbefore = prev->notbefore;
if (cs->notafter == UNSPEC)
cs->notafter = prev->notafter;
if (cs->timeout == UNSPEC)
cs->timeout = prev->timeout;
if (cs->tags.nopasswd == UNSPEC)
cs->tags.nopasswd = prev->tags.nopasswd;
if (cs->tags.noexec == UNSPEC)
cs->tags.noexec = prev->tags.noexec;
if (cs->tags.intercept == UNSPEC)
cs->tags.intercept = prev->tags.intercept;
if (!TAG_SET(cs->tags.setenv) && TAG_SET(prev->tags.setenv))
cs->tags.setenv = prev->tags.setenv;
if (cs->tags.log_input == UNSPEC)
cs->tags.log_input = prev->tags.log_input;
if (cs->tags.log_output == UNSPEC)
cs->tags.log_output = prev->tags.log_output;
if (cs->tags.send_mail == UNSPEC)
cs->tags.send_mail = prev->tags.send_mail;
if (cs->tags.follow == UNSPEC)
cs->tags.follow = prev->tags.follow;
if ((cs->runasuserlist == NULL &&
cs->runasgrouplist == NULL) &&
(prev->runasuserlist != NULL ||
prev->runasgrouplist != NULL)) {
cs->runasuserlist = prev->runasuserlist;
cs->runasgrouplist = prev->runasgrouplist;
}
}
uid_t
sudoers_file_uid(void)
{
return parser_conf.sudoers_uid;
}
gid_t
sudoers_file_gid(void)
{
return parser_conf.sudoers_gid;
}
mode_t
sudoers_file_mode(void)
{
return parser_conf.sudoers_mode;
}
bool
sudoers_error_recovery(void)
{
return parser_conf.recovery;
}
bool
sudoers_strict(void)
{
return parser_conf.strict;
}
bool
parser_leak_add(enum parser_leak_types type, void *v)
{
#ifdef NO_LEAKS
struct parser_leak_entry *entry;
debug_decl(parser_leak_add, SUDOERS_DEBUG_PARSER);
if (v == NULL)
debug_return_bool(false);
entry = calloc(1, sizeof(*entry));
if (entry == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_bool(false);
}
switch (type) {
case LEAK_PRIVILEGE:
entry->u.p = v;
break;
case LEAK_CMNDSPEC:
entry->u.cs = v;
break;
case LEAK_DEFAULTS:
entry->u.d = v;
break;
case LEAK_MEMBER:
entry->u.m = v;
break;
case LEAK_DIGEST:
entry->u.dig = v;
break;
case LEAK_RUNAS:
entry->u.rc = v;
break;
case LEAK_PTR:
entry->u.ptr = v;
break;
default:
free(entry);
sudo_warnx("unexpected leak type %d", type);
debug_return_bool(false);
}
entry->type = type;
SLIST_INSERT_HEAD(&parser_leak_list, entry, entries);
debug_return_bool(true);
#else
return true;
#endif
}
bool
parser_leak_remove(enum parser_leak_types type, void *v)
{
#ifdef NO_LEAKS
struct parser_leak_entry *entry, *prev = NULL;
debug_decl(parser_leak_remove, SUDOERS_DEBUG_PARSER);
if (v == NULL)
debug_return_bool(false);
SLIST_FOREACH(entry, &parser_leak_list, entries) {
switch (entry->type) {
case LEAK_PRIVILEGE:
if (entry->u.p == v)
goto found;
break;
case LEAK_CMNDSPEC:
if (entry->u.cs == v)
goto found;
break;
case LEAK_DEFAULTS:
if (entry->u.d == v)
goto found;
break;
case LEAK_MEMBER:
if (entry->u.m == v)
goto found;
break;
case LEAK_DIGEST:
if (entry->u.dig == v)
goto found;
break;
case LEAK_RUNAS:
if (entry->u.rc == v)
goto found;
break;
case LEAK_PTR:
if (entry->u.ptr == v)
goto found;
break;
default:
sudo_warnx("unexpected leak type %d in %p", entry->type, entry);
}
prev = entry;
}
sudo_warnx("%s: unable to find %p, type %d", __func__, v, type);
debug_return_bool(false);
found:
if (prev == NULL)
SLIST_REMOVE_HEAD(&parser_leak_list, entries);
else
SLIST_REMOVE_AFTER(prev, entries);
free(entry);
debug_return_bool(true);
#else
return true;
#endif
}
#ifdef NO_LEAKS
static void
parser_leak_free(void)
{
struct parser_leak_entry *entry;
void *next;
debug_decl(parser_leak_run, SUDOERS_DEBUG_PARSER);
while ((entry = SLIST_FIRST(&parser_leak_list))) {
SLIST_REMOVE_HEAD(&parser_leak_list, entries);
switch (entry->type) {
case LEAK_PRIVILEGE:
{
struct privilege *priv;
HLTQ_FOREACH_SAFE(priv, entry->u.p, entries, next)
free_privilege(priv);
free(entry);
}
break;
case LEAK_CMNDSPEC:
{
struct cmndspec_list specs;
HLTQ_TO_TAILQ(&specs, entry->u.cs, entries);
free_cmndspecs(&specs);
free(entry);
}
break;
case LEAK_DEFAULTS:
{
struct defaults_list defs;
HLTQ_TO_TAILQ(&defs, entry->u.d, entries);
free_defaults(&defs);
free(entry);
}
break;
case LEAK_MEMBER:
{
struct member *m;
HLTQ_FOREACH_SAFE(m, entry->u.m, entries, next)
free_member(m);
free(entry);
}
break;
case LEAK_DIGEST:
{
struct command_digest *dig;
HLTQ_FOREACH_SAFE(dig, entry->u.dig, entries, next) {
free(dig->digest_str);
free(dig);
}
free(entry);
}
break;
case LEAK_RUNAS:
{
struct member *m;
if (entry->u.rc->runasusers != NULL) {
HLTQ_FOREACH_SAFE(m, entry->u.rc->runasusers, entries, next)
free_member(m);
}
if (entry->u.rc->runasgroups != NULL) {
HLTQ_FOREACH_SAFE(m, entry->u.rc->runasgroups, entries, next)
free_member(m);
}
free(entry->u.rc);
free(entry);
break;
}
case LEAK_PTR:
free(entry->u.ptr);
free(entry);
break;
default:
sudo_warnx("unexpected garbage type %d", entry->type);
}
}
debug_return;
}
#endif
void
parser_leak_init(void)
{
#ifdef NO_LEAKS
static bool initialized;
debug_decl(parser_leak_init, SUDOERS_DEBUG_PARSER);
if (!initialized) {
atexit(parser_leak_free);
initialized = true;
debug_return;
}
parser_leak_free();
debug_return;
#endif
}