Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/plugins/sudoers/gram.c
1532 views
1
#include <config.h>
2
/* A Bison parser, made by GNU Bison 3.8.2. */
3
4
/* Bison implementation for Yacc-like parsers in C
5
6
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
7
Inc.
8
9
This program is free software: you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation, either version 3 of the License, or
12
(at your option) any later version.
13
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
18
19
You should have received a copy of the GNU General Public License
20
along with this program. If not, see <https://www.gnu.org/licenses/>. */
21
22
/* As a special exception, you may create a larger work that contains
23
part or all of the Bison parser skeleton and distribute that work
24
under terms of your choice, so long as that work isn't itself a
25
parser generator using the skeleton or a modified version thereof
26
as a parser skeleton. Alternatively, if you modify or redistribute
27
the parser skeleton itself, you may (at your option) remove this
28
special exception, which will cause the skeleton and the resulting
29
Bison output files to be licensed under the GNU General Public
30
License without this special exception.
31
32
This special exception was added by the Free Software Foundation in
33
version 2.2 of Bison. */
34
35
/* C LALR(1) parser skeleton written by Richard Stallman, by
36
simplifying the original so-called "semantic" parser. */
37
38
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
39
especially those whose name start with YY_ or yy_. They are
40
private implementation details that can be changed or removed. */
41
42
/* All symbols defined below should begin with yy or YY, to avoid
43
infringing on user name space. This should be done even for local
44
variables, as they might otherwise be expanded by user macros.
45
There are some unavoidable exceptions within include files to
46
define necessary library symbols; they are noted "INFRINGES ON
47
USER NAME SPACE" below. */
48
49
/* Identify Bison output, and Bison version. */
50
#define YYBISON 30802
51
52
/* Bison version string. */
53
#define YYBISON_VERSION "3.8.2"
54
55
/* Skeleton name. */
56
#define YYSKELETON_NAME "yacc.c"
57
58
/* Pure parsers. */
59
#define YYPURE 0
60
61
/* Push parsers. */
62
#define YYPUSH 0
63
64
/* Pull parsers. */
65
#define YYPULL 1
66
67
68
/* Substitute the variable and function names. */
69
#define yyparse sudoersparse
70
#define yylex sudoerslex
71
#define yyerror sudoerserror
72
#define yydebug sudoersdebug
73
#define yynerrs sudoersnerrs
74
#define yylval sudoerslval
75
#define yychar sudoerschar
76
77
/* First part of user prologue. */
78
#line 1 "gram.y"
79
80
/*
81
* SPDX-License-Identifier: ISC
82
*
83
* Copyright (c) 1996, 1998-2005, 2007-2013, 2014-2024
84
* Todd C. Miller <[email protected]>
85
*
86
* Permission to use, copy, modify, and distribute this software for any
87
* purpose with or without fee is hereby granted, provided that the above
88
* copyright notice and this permission notice appear in all copies.
89
*
90
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
91
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
92
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
93
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
94
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
95
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
96
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
97
*
98
* Sponsored in part by the Defense Advanced Research Projects
99
* Agency (DARPA) and Air Force Research Laboratory, Air Force
100
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
101
*/
102
103
#include <config.h>
104
105
#include <stdio.h>
106
#include <stdlib.h>
107
#include <stddef.h>
108
#include <string.h>
109
#include <unistd.h>
110
#include <errno.h>
111
112
#include <sudoers.h>
113
#include <sudo_digest.h>
114
#include <toke.h>
115
116
#ifdef YYBISON
117
# define YYERROR_VERBOSE
118
#endif
119
120
/* If we last saw a newline the entry is on the preceding line. */
121
#define this_lineno (sudoerschar == '\n' ? sudolineno - 1 : sudolineno)
122
123
// PVS Studio suppression
124
// -V::560, 592, 1037, 1042
125
126
/*
127
* Globals
128
*/
129
bool parse_error = false;
130
131
static struct sudoers_parser_config parser_conf =
132
SUDOERS_PARSER_CONFIG_INITIALIZER;
133
134
/* Optional logging function for parse errors. */
135
sudoers_logger_t sudoers_error_hook;
136
137
static int alias_line, alias_column;
138
139
#ifdef NO_LEAKS
140
static struct parser_leak_list parser_leak_list =
141
SLIST_HEAD_INITIALIZER(parser_leak_list);
142
#endif
143
144
struct sudoers_parse_tree parsed_policy = {
145
{ NULL, NULL }, /* entries */
146
TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
147
TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
148
NULL, /* aliases */
149
NULL, /* lhost */
150
NULL, /* shost */
151
NULL, /* nss */
152
NULL /* ctx */
153
};
154
155
/*
156
* Local prototypes
157
*/
158
static bool add_defaults(short, struct member *, struct defaults *);
159
static bool add_userspec(struct member *, struct privilege *);
160
static struct command_digest *new_digest(unsigned int, char *);
161
static struct defaults *new_default(char *, char *, short);
162
static struct member *new_member(char *, short);
163
static struct sudo_command *new_command(char *, char *);
164
static void alias_error(const char *name, short type, int errnum);
165
static void init_options(struct command_options *opts);
166
static void propagate_cmndspec(struct cmndspec *cs, const struct cmndspec *prev);
167
168
#line 168 "gram.c"
169
170
# ifndef YY_CAST
171
# ifdef __cplusplus
172
# define YY_CAST(Type, Val) static_cast<Type> (Val)
173
# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
174
# else
175
# define YY_CAST(Type, Val) ((Type) (Val))
176
# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
177
# endif
178
# endif
179
# ifndef YY_NULLPTR
180
# if defined __cplusplus
181
# if 201103L <= __cplusplus
182
# define YY_NULLPTR nullptr
183
# else
184
# define YY_NULLPTR 0
185
# endif
186
# else
187
# define YY_NULLPTR ((void*)0)
188
# endif
189
# endif
190
191
/* Use api.header.include to #include this header
192
instead of duplicating it here. */
193
#ifndef YY_SUDOERS_Y_TAB_H_INCLUDED
194
# define YY_SUDOERS_Y_TAB_H_INCLUDED
195
/* Debug traces. */
196
#ifndef YYDEBUG
197
# define YYDEBUG 0
198
#endif
199
#if YYDEBUG
200
extern int sudoersdebug;
201
#endif
202
203
/* Token kinds. */
204
#ifndef YYTOKENTYPE
205
# define YYTOKENTYPE
206
enum yytokentype
207
{
208
YYEMPTY = -2,
209
YYEOF = 0, /* "end of file" */
210
YYerror = 256, /* error */
211
YYUNDEF = 257, /* "invalid token" */
212
COMMAND = 258, /* COMMAND */
213
ALIAS = 259, /* ALIAS */
214
DEFVAR = 260, /* DEFVAR */
215
NTWKADDR = 261, /* NTWKADDR */
216
NETGROUP = 262, /* NETGROUP */
217
USERGROUP = 263, /* USERGROUP */
218
WORD = 264, /* WORD */
219
DIGEST = 265, /* DIGEST */
220
INCLUDE = 266, /* INCLUDE */
221
INCLUDEDIR = 267, /* INCLUDEDIR */
222
DEFAULTS = 268, /* DEFAULTS */
223
DEFAULTS_HOST = 269, /* DEFAULTS_HOST */
224
DEFAULTS_USER = 270, /* DEFAULTS_USER */
225
DEFAULTS_RUNAS = 271, /* DEFAULTS_RUNAS */
226
DEFAULTS_CMND = 272, /* DEFAULTS_CMND */
227
NOPASSWD = 273, /* NOPASSWD */
228
PASSWD = 274, /* PASSWD */
229
NOEXEC = 275, /* NOEXEC */
230
EXEC = 276, /* EXEC */
231
SETENV = 277, /* SETENV */
232
NOSETENV = 278, /* NOSETENV */
233
LOG_INPUT = 279, /* LOG_INPUT */
234
NOLOG_INPUT = 280, /* NOLOG_INPUT */
235
LOG_OUTPUT = 281, /* LOG_OUTPUT */
236
NOLOG_OUTPUT = 282, /* NOLOG_OUTPUT */
237
MAIL = 283, /* MAIL */
238
NOMAIL = 284, /* NOMAIL */
239
FOLLOWLNK = 285, /* FOLLOWLNK */
240
NOFOLLOWLNK = 286, /* NOFOLLOWLNK */
241
INTERCEPT = 287, /* INTERCEPT */
242
NOINTERCEPT = 288, /* NOINTERCEPT */
243
ALL = 289, /* ALL */
244
HOSTALIAS = 290, /* HOSTALIAS */
245
CMNDALIAS = 291, /* CMNDALIAS */
246
USERALIAS = 292, /* USERALIAS */
247
RUNASALIAS = 293, /* RUNASALIAS */
248
ERROR = 294, /* ERROR */
249
NOMATCH = 295, /* NOMATCH */
250
CHROOT = 296, /* CHROOT */
251
CWD = 297, /* CWD */
252
TYPE = 298, /* TYPE */
253
ROLE = 299, /* ROLE */
254
APPARMOR_PROFILE = 300, /* APPARMOR_PROFILE */
255
PRIVS = 301, /* PRIVS */
256
LIMITPRIVS = 302, /* LIMITPRIVS */
257
CMND_TIMEOUT = 303, /* CMND_TIMEOUT */
258
NOTBEFORE = 304, /* NOTBEFORE */
259
NOTAFTER = 305, /* NOTAFTER */
260
MYSELF = 306, /* MYSELF */
261
SHA224_TOK = 307, /* SHA224_TOK */
262
SHA256_TOK = 308, /* SHA256_TOK */
263
SHA384_TOK = 309, /* SHA384_TOK */
264
SHA512_TOK = 310 /* SHA512_TOK */
265
};
266
typedef enum yytokentype yytoken_kind_t;
267
#endif
268
/* Token kinds. */
269
#define YYEMPTY -2
270
#define YYEOF 0
271
#define YYerror 256
272
#define YYUNDEF 257
273
#define COMMAND 258
274
#define ALIAS 259
275
#define DEFVAR 260
276
#define NTWKADDR 261
277
#define NETGROUP 262
278
#define USERGROUP 263
279
#define WORD 264
280
#define DIGEST 265
281
#define INCLUDE 266
282
#define INCLUDEDIR 267
283
#define DEFAULTS 268
284
#define DEFAULTS_HOST 269
285
#define DEFAULTS_USER 270
286
#define DEFAULTS_RUNAS 271
287
#define DEFAULTS_CMND 272
288
#define NOPASSWD 273
289
#define PASSWD 274
290
#define NOEXEC 275
291
#define EXEC 276
292
#define SETENV 277
293
#define NOSETENV 278
294
#define LOG_INPUT 279
295
#define NOLOG_INPUT 280
296
#define LOG_OUTPUT 281
297
#define NOLOG_OUTPUT 282
298
#define MAIL 283
299
#define NOMAIL 284
300
#define FOLLOWLNK 285
301
#define NOFOLLOWLNK 286
302
#define INTERCEPT 287
303
#define NOINTERCEPT 288
304
#define ALL 289
305
#define HOSTALIAS 290
306
#define CMNDALIAS 291
307
#define USERALIAS 292
308
#define RUNASALIAS 293
309
#define ERROR 294
310
#define NOMATCH 295
311
#define CHROOT 296
312
#define CWD 297
313
#define TYPE 298
314
#define ROLE 299
315
#define APPARMOR_PROFILE 300
316
#define PRIVS 301
317
#define LIMITPRIVS 302
318
#define CMND_TIMEOUT 303
319
#define NOTBEFORE 304
320
#define NOTAFTER 305
321
#define MYSELF 306
322
#define SHA224_TOK 307
323
#define SHA256_TOK 308
324
#define SHA384_TOK 309
325
#define SHA512_TOK 310
326
327
/* Value type. */
328
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
329
union YYSTYPE
330
{
331
#line 91 "gram.y"
332
333
struct cmndspec *cmndspec;
334
struct defaults *defaults;
335
struct member *member;
336
struct runascontainer *runas;
337
struct privilege *privilege;
338
struct command_digest *digest;
339
struct sudo_command command;
340
struct command_options options;
341
struct cmndtag tag;
342
char *string;
343
const char *cstring;
344
int tok;
345
346
#line 346 "gram.c"
347
348
};
349
typedef union YYSTYPE YYSTYPE;
350
# define YYSTYPE_IS_TRIVIAL 1
351
# define YYSTYPE_IS_DECLARED 1
352
#endif
353
354
355
extern YYSTYPE sudoerslval;
356
357
358
int sudoersparse (void);
359
360
361
#endif /* !YY_SUDOERS_Y_TAB_H_INCLUDED */
362
/* Symbol kind. */
363
enum yysymbol_kind_t
364
{
365
YYSYMBOL_YYEMPTY = -2,
366
YYSYMBOL_YYEOF = 0, /* "end of file" */
367
YYSYMBOL_YYerror = 1, /* error */
368
YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
369
YYSYMBOL_COMMAND = 3, /* COMMAND */
370
YYSYMBOL_ALIAS = 4, /* ALIAS */
371
YYSYMBOL_DEFVAR = 5, /* DEFVAR */
372
YYSYMBOL_NTWKADDR = 6, /* NTWKADDR */
373
YYSYMBOL_NETGROUP = 7, /* NETGROUP */
374
YYSYMBOL_USERGROUP = 8, /* USERGROUP */
375
YYSYMBOL_WORD = 9, /* WORD */
376
YYSYMBOL_DIGEST = 10, /* DIGEST */
377
YYSYMBOL_INCLUDE = 11, /* INCLUDE */
378
YYSYMBOL_INCLUDEDIR = 12, /* INCLUDEDIR */
379
YYSYMBOL_DEFAULTS = 13, /* DEFAULTS */
380
YYSYMBOL_DEFAULTS_HOST = 14, /* DEFAULTS_HOST */
381
YYSYMBOL_DEFAULTS_USER = 15, /* DEFAULTS_USER */
382
YYSYMBOL_DEFAULTS_RUNAS = 16, /* DEFAULTS_RUNAS */
383
YYSYMBOL_DEFAULTS_CMND = 17, /* DEFAULTS_CMND */
384
YYSYMBOL_NOPASSWD = 18, /* NOPASSWD */
385
YYSYMBOL_PASSWD = 19, /* PASSWD */
386
YYSYMBOL_NOEXEC = 20, /* NOEXEC */
387
YYSYMBOL_EXEC = 21, /* EXEC */
388
YYSYMBOL_SETENV = 22, /* SETENV */
389
YYSYMBOL_NOSETENV = 23, /* NOSETENV */
390
YYSYMBOL_LOG_INPUT = 24, /* LOG_INPUT */
391
YYSYMBOL_NOLOG_INPUT = 25, /* NOLOG_INPUT */
392
YYSYMBOL_LOG_OUTPUT = 26, /* LOG_OUTPUT */
393
YYSYMBOL_NOLOG_OUTPUT = 27, /* NOLOG_OUTPUT */
394
YYSYMBOL_MAIL = 28, /* MAIL */
395
YYSYMBOL_NOMAIL = 29, /* NOMAIL */
396
YYSYMBOL_FOLLOWLNK = 30, /* FOLLOWLNK */
397
YYSYMBOL_NOFOLLOWLNK = 31, /* NOFOLLOWLNK */
398
YYSYMBOL_INTERCEPT = 32, /* INTERCEPT */
399
YYSYMBOL_NOINTERCEPT = 33, /* NOINTERCEPT */
400
YYSYMBOL_ALL = 34, /* ALL */
401
YYSYMBOL_HOSTALIAS = 35, /* HOSTALIAS */
402
YYSYMBOL_CMNDALIAS = 36, /* CMNDALIAS */
403
YYSYMBOL_USERALIAS = 37, /* USERALIAS */
404
YYSYMBOL_RUNASALIAS = 38, /* RUNASALIAS */
405
YYSYMBOL_39_ = 39, /* ':' */
406
YYSYMBOL_40_ = 40, /* '=' */
407
YYSYMBOL_41_ = 41, /* ',' */
408
YYSYMBOL_42_ = 42, /* '!' */
409
YYSYMBOL_43_ = 43, /* '+' */
410
YYSYMBOL_44_ = 44, /* '-' */
411
YYSYMBOL_45_ = 45, /* '(' */
412
YYSYMBOL_46_ = 46, /* ')' */
413
YYSYMBOL_47_n_ = 47, /* '\n' */
414
YYSYMBOL_ERROR = 48, /* ERROR */
415
YYSYMBOL_NOMATCH = 49, /* NOMATCH */
416
YYSYMBOL_CHROOT = 50, /* CHROOT */
417
YYSYMBOL_CWD = 51, /* CWD */
418
YYSYMBOL_TYPE = 52, /* TYPE */
419
YYSYMBOL_ROLE = 53, /* ROLE */
420
YYSYMBOL_APPARMOR_PROFILE = 54, /* APPARMOR_PROFILE */
421
YYSYMBOL_PRIVS = 55, /* PRIVS */
422
YYSYMBOL_LIMITPRIVS = 56, /* LIMITPRIVS */
423
YYSYMBOL_CMND_TIMEOUT = 57, /* CMND_TIMEOUT */
424
YYSYMBOL_NOTBEFORE = 58, /* NOTBEFORE */
425
YYSYMBOL_NOTAFTER = 59, /* NOTAFTER */
426
YYSYMBOL_MYSELF = 60, /* MYSELF */
427
YYSYMBOL_SHA224_TOK = 61, /* SHA224_TOK */
428
YYSYMBOL_SHA256_TOK = 62, /* SHA256_TOK */
429
YYSYMBOL_SHA384_TOK = 63, /* SHA384_TOK */
430
YYSYMBOL_SHA512_TOK = 64, /* SHA512_TOK */
431
YYSYMBOL_YYACCEPT = 65, /* $accept */
432
YYSYMBOL_file = 66, /* file */
433
YYSYMBOL_line = 67, /* line */
434
YYSYMBOL_entry = 68, /* entry */
435
YYSYMBOL_include = 69, /* include */
436
YYSYMBOL_includedir = 70, /* includedir */
437
YYSYMBOL_defaults_list = 71, /* defaults_list */
438
YYSYMBOL_defaults_entry = 72, /* defaults_entry */
439
YYSYMBOL_privileges = 73, /* privileges */
440
YYSYMBOL_privilege = 74, /* privilege */
441
YYSYMBOL_ophost = 75, /* ophost */
442
YYSYMBOL_host = 76, /* host */
443
YYSYMBOL_cmndspeclist = 77, /* cmndspeclist */
444
YYSYMBOL_cmndspec = 78, /* cmndspec */
445
YYSYMBOL_digestspec = 79, /* digestspec */
446
YYSYMBOL_digestlist = 80, /* digestlist */
447
YYSYMBOL_digcmnd = 81, /* digcmnd */
448
YYSYMBOL_opcmnd = 82, /* opcmnd */
449
YYSYMBOL_chdirspec = 83, /* chdirspec */
450
YYSYMBOL_chrootspec = 84, /* chrootspec */
451
YYSYMBOL_timeoutspec = 85, /* timeoutspec */
452
YYSYMBOL_notbeforespec = 86, /* notbeforespec */
453
YYSYMBOL_notafterspec = 87, /* notafterspec */
454
YYSYMBOL_rolespec = 88, /* rolespec */
455
YYSYMBOL_typespec = 89, /* typespec */
456
YYSYMBOL_apparmor_profilespec = 90, /* apparmor_profilespec */
457
YYSYMBOL_privsspec = 91, /* privsspec */
458
YYSYMBOL_limitprivsspec = 92, /* limitprivsspec */
459
YYSYMBOL_runasspec = 93, /* runasspec */
460
YYSYMBOL_runaslist = 94, /* runaslist */
461
YYSYMBOL_reserved_word = 95, /* reserved_word */
462
YYSYMBOL_reserved_alias = 96, /* reserved_alias */
463
YYSYMBOL_options = 97, /* options */
464
YYSYMBOL_cmndtag = 98, /* cmndtag */
465
YYSYMBOL_cmnd = 99, /* cmnd */
466
YYSYMBOL_hostaliases = 100, /* hostaliases */
467
YYSYMBOL_hostalias = 101, /* hostalias */
468
YYSYMBOL_102_1 = 102, /* $@1 */
469
YYSYMBOL_hostlist = 103, /* hostlist */
470
YYSYMBOL_cmndaliases = 104, /* cmndaliases */
471
YYSYMBOL_cmndalias = 105, /* cmndalias */
472
YYSYMBOL_106_2 = 106, /* $@2 */
473
YYSYMBOL_cmndlist = 107, /* cmndlist */
474
YYSYMBOL_runasaliases = 108, /* runasaliases */
475
YYSYMBOL_runasalias = 109, /* runasalias */
476
YYSYMBOL_110_3 = 110, /* $@3 */
477
YYSYMBOL_useraliases = 111, /* useraliases */
478
YYSYMBOL_useralias = 112, /* useralias */
479
YYSYMBOL_113_4 = 113, /* $@4 */
480
YYSYMBOL_userlist = 114, /* userlist */
481
YYSYMBOL_opuser = 115, /* opuser */
482
YYSYMBOL_user = 116, /* user */
483
YYSYMBOL_grouplist = 117, /* grouplist */
484
YYSYMBOL_opgroup = 118, /* opgroup */
485
YYSYMBOL_group = 119 /* group */
486
};
487
typedef enum yysymbol_kind_t yysymbol_kind_t;
488
489
490
491
492
#ifdef short
493
# undef short
494
#endif
495
496
/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
497
<limits.h> and (if available) <stdint.h> are included
498
so that the code can choose integer types of a good width. */
499
500
#ifndef __PTRDIFF_MAX__
501
# include <limits.h> /* INFRINGES ON USER NAME SPACE */
502
# if defined HAVE_STDINT_H
503
# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
504
# define YY_STDINT_H
505
# endif
506
#endif
507
508
/* Narrow types that promote to a signed type and that can represent a
509
signed or unsigned integer of at least N bits. In tables they can
510
save space and decrease cache pressure. Promoting to a signed type
511
helps avoid bugs in integer arithmetic. */
512
513
#ifdef __INT_LEAST8_MAX__
514
typedef __INT_LEAST8_TYPE__ yytype_int8;
515
#elif defined YY_STDINT_H
516
typedef int_least8_t yytype_int8;
517
#else
518
typedef signed char yytype_int8;
519
#endif
520
521
#ifdef __INT_LEAST16_MAX__
522
typedef __INT_LEAST16_TYPE__ yytype_int16;
523
#elif defined YY_STDINT_H
524
typedef int_least16_t yytype_int16;
525
#else
526
typedef short yytype_int16;
527
#endif
528
529
/* Work around bug in HP-UX 11.23, which defines these macros
530
incorrectly for preprocessor constants. This workaround can likely
531
be removed in 2023, as HPE has promised support for HP-UX 11.23
532
(aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
533
<https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
534
#ifdef __hpux
535
# undef UINT_LEAST8_MAX
536
# undef UINT_LEAST16_MAX
537
# define UINT_LEAST8_MAX 255
538
# define UINT_LEAST16_MAX 65535
539
#endif
540
541
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
542
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
543
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
544
&& UINT_LEAST8_MAX <= INT_MAX)
545
typedef uint_least8_t yytype_uint8;
546
#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
547
typedef unsigned char yytype_uint8;
548
#else
549
typedef short yytype_uint8;
550
#endif
551
552
#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
553
typedef __UINT_LEAST16_TYPE__ yytype_uint16;
554
#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
555
&& UINT_LEAST16_MAX <= INT_MAX)
556
typedef uint_least16_t yytype_uint16;
557
#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
558
typedef unsigned short yytype_uint16;
559
#else
560
typedef int yytype_uint16;
561
#endif
562
563
#ifndef YYPTRDIFF_T
564
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
565
# define YYPTRDIFF_T __PTRDIFF_TYPE__
566
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
567
# elif defined PTRDIFF_MAX
568
# ifndef ptrdiff_t
569
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
570
# endif
571
# define YYPTRDIFF_T ptrdiff_t
572
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
573
# else
574
# define YYPTRDIFF_T long
575
# define YYPTRDIFF_MAXIMUM LONG_MAX
576
# endif
577
#endif
578
579
#ifndef YYSIZE_T
580
# ifdef __SIZE_TYPE__
581
# define YYSIZE_T __SIZE_TYPE__
582
# elif defined size_t
583
# define YYSIZE_T size_t
584
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
585
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
586
# define YYSIZE_T size_t
587
# else
588
# define YYSIZE_T unsigned
589
# endif
590
#endif
591
592
#define YYSIZE_MAXIMUM \
593
YY_CAST (YYPTRDIFF_T, \
594
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
595
? YYPTRDIFF_MAXIMUM \
596
: YY_CAST (YYSIZE_T, -1)))
597
598
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
599
600
601
/* Stored state numbers (used for stacks). */
602
typedef yytype_uint8 yy_state_t;
603
604
/* State numbers in computations. */
605
typedef int yy_state_fast_t;
606
607
#ifndef YY_
608
# if defined YYENABLE_NLS && YYENABLE_NLS
609
# if ENABLE_NLS
610
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
611
# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
612
# endif
613
# endif
614
# ifndef YY_
615
# define YY_(Msgid) Msgid
616
# endif
617
#endif
618
619
620
#ifndef YY_ATTRIBUTE_PURE
621
# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
622
# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
623
# else
624
# define YY_ATTRIBUTE_PURE
625
# endif
626
#endif
627
628
#ifndef YY_ATTRIBUTE_UNUSED
629
# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
630
# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
631
# else
632
# define YY_ATTRIBUTE_UNUSED
633
# endif
634
#endif
635
636
/* Suppress unused-variable warnings by "using" E. */
637
#if ! defined lint || defined __GNUC__
638
# define YY_USE(E) ((void) (E))
639
#else
640
# define YY_USE(E) /* empty */
641
#endif
642
643
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
644
#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
645
# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
646
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
647
_Pragma ("GCC diagnostic push") \
648
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
649
# else
650
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
651
_Pragma ("GCC diagnostic push") \
652
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
653
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
654
# endif
655
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
656
_Pragma ("GCC diagnostic pop")
657
#else
658
# define YY_INITIAL_VALUE(Value) Value
659
#endif
660
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
661
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
662
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
663
#endif
664
#ifndef YY_INITIAL_VALUE
665
# define YY_INITIAL_VALUE(Value) /* Nothing. */
666
#endif
667
668
#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
669
# define YY_IGNORE_USELESS_CAST_BEGIN \
670
_Pragma ("GCC diagnostic push") \
671
_Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
672
# define YY_IGNORE_USELESS_CAST_END \
673
_Pragma ("GCC diagnostic pop")
674
#endif
675
#ifndef YY_IGNORE_USELESS_CAST_BEGIN
676
# define YY_IGNORE_USELESS_CAST_BEGIN
677
# define YY_IGNORE_USELESS_CAST_END
678
#endif
679
680
681
#define YY_ASSERT(E) ((void) (0 && (E)))
682
683
#if !defined yyoverflow
684
685
/* The parser invokes alloca or malloc; define the necessary symbols. */
686
687
# ifdef YYSTACK_USE_ALLOCA
688
# if YYSTACK_USE_ALLOCA
689
# ifdef __GNUC__
690
# define YYSTACK_ALLOC __builtin_alloca
691
# elif defined __BUILTIN_VA_ARG_INCR
692
# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
693
# elif defined _AIX
694
# define YYSTACK_ALLOC __alloca
695
# elif defined _MSC_VER
696
# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
697
# define alloca _alloca
698
# else
699
# define YYSTACK_ALLOC alloca
700
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
701
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
702
/* Use EXIT_SUCCESS as a witness for stdlib.h. */
703
# ifndef EXIT_SUCCESS
704
# define EXIT_SUCCESS 0
705
# endif
706
# endif
707
# endif
708
# endif
709
# endif
710
711
# ifdef YYSTACK_ALLOC
712
/* Pacify GCC's 'empty if-body' warning. */
713
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
714
# ifndef YYSTACK_ALLOC_MAXIMUM
715
/* The OS might guarantee only one guard page at the bottom of the stack,
716
and a page size can be as small as 4096 bytes. So we cannot safely
717
invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
718
to allow for a few compiler-allocated temporary stack slots. */
719
# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
720
# endif
721
# else
722
# define YYSTACK_ALLOC YYMALLOC
723
# define YYSTACK_FREE YYFREE
724
# ifndef YYSTACK_ALLOC_MAXIMUM
725
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
726
# endif
727
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
728
&& ! ((defined YYMALLOC || defined malloc) \
729
&& (defined YYFREE || defined free)))
730
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
731
# ifndef EXIT_SUCCESS
732
# define EXIT_SUCCESS 0
733
# endif
734
# endif
735
# ifndef YYMALLOC
736
# define YYMALLOC malloc
737
# if ! defined malloc && ! defined EXIT_SUCCESS
738
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
739
# endif
740
# endif
741
# ifndef YYFREE
742
# define YYFREE free
743
# if ! defined free && ! defined EXIT_SUCCESS
744
void free (void *); /* INFRINGES ON USER NAME SPACE */
745
# endif
746
# endif
747
# endif
748
#endif /* !defined yyoverflow */
749
750
#if (! defined yyoverflow \
751
&& (! defined __cplusplus \
752
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
753
754
/* A type that is properly aligned for any stack member. */
755
union yyalloc
756
{
757
yy_state_t yyss_alloc;
758
YYSTYPE yyvs_alloc;
759
};
760
761
/* The size of the maximum gap between one aligned stack and the next. */
762
# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
763
764
/* The size of an array large to enough to hold all stacks, each with
765
N elements. */
766
# define YYSTACK_BYTES(N) \
767
((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
768
+ YYSTACK_GAP_MAXIMUM)
769
770
# define YYCOPY_NEEDED 1
771
772
/* Relocate STACK from its old location to the new one. The
773
local variables YYSIZE and YYSTACKSIZE give the old and new number of
774
elements in the stack, and YYPTR gives the new location of the
775
stack. Advance YYPTR to a properly aligned location for the next
776
stack. */
777
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
778
do \
779
{ \
780
YYPTRDIFF_T yynewbytes; \
781
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
782
Stack = &yyptr->Stack_alloc; \
783
yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
784
yyptr += yynewbytes / YYSIZEOF (*yyptr); \
785
} \
786
while (0)
787
788
#endif
789
790
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
791
/* Copy COUNT objects from SRC to DST. The source and destination do
792
not overlap. */
793
# ifndef YYCOPY
794
# if defined __GNUC__ && 1 < __GNUC__
795
# define YYCOPY(Dst, Src, Count) \
796
__builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
797
# else
798
# define YYCOPY(Dst, Src, Count) \
799
do \
800
{ \
801
YYPTRDIFF_T yyi; \
802
for (yyi = 0; yyi < (Count); yyi++) \
803
(Dst)[yyi] = (Src)[yyi]; \
804
} \
805
while (0)
806
# endif
807
# endif
808
#endif /* !YYCOPY_NEEDED */
809
810
/* YYFINAL -- State number of the termination state. */
811
#define YYFINAL 90
812
/* YYLAST -- Last index in YYTABLE. */
813
#define YYLAST 332
814
815
/* YYNTOKENS -- Number of terminals. */
816
#define YYNTOKENS 65
817
/* YYNNTS -- Number of nonterminals. */
818
#define YYNNTS 55
819
/* YYNRULES -- Number of rules. */
820
#define YYNRULES 155
821
/* YYNSTATES -- Number of states. */
822
#define YYNSTATES 256
823
824
/* YYMAXUTOK -- Last valid token kind. */
825
#define YYMAXUTOK 310
826
827
828
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
829
as returned by yylex, with out-of-bounds checking. */
830
#define YYTRANSLATE(YYX) \
831
(0 <= (YYX) && (YYX) <= YYMAXUTOK \
832
? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
833
: YYSYMBOL_YYUNDEF)
834
835
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
836
as returned by yylex. */
837
static const yytype_int8 yytranslate[] =
838
{
839
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
840
47, 2, 2, 2, 2, 2, 2, 2, 2, 2,
841
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
842
2, 2, 2, 42, 2, 2, 2, 2, 2, 2,
843
45, 46, 2, 43, 41, 44, 2, 2, 2, 2,
844
2, 2, 2, 2, 2, 2, 2, 2, 39, 2,
845
2, 40, 2, 2, 2, 2, 2, 2, 2, 2,
846
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
847
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
848
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
849
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
850
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
851
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
852
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
853
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
854
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
855
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
856
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
857
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
858
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
859
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
860
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
861
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
862
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
863
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
864
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
865
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
866
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
867
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
868
35, 36, 37, 38, 48, 49, 50, 51, 52, 53,
869
54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
870
64
871
};
872
873
#if YYDEBUG
874
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
875
static const yytype_int16 yyrline[] =
876
{
877
0, 205, 205, 208, 211, 212, 215, 218, 221, 229,
878
237, 243, 246, 249, 252, 255, 259, 263, 267, 271,
879
277, 280, 286, 289, 295, 296, 303, 312, 321, 331,
880
341, 353, 354, 359, 365, 382, 386, 392, 401, 409,
881
418, 427, 438, 439, 449, 513, 522, 531, 540, 551,
882
552, 559, 562, 576, 580, 586, 602, 624, 629, 633,
883
638, 643, 648, 653, 657, 662, 665, 670, 687, 699,
884
715, 733, 752, 753, 754, 755, 756, 757, 758, 759,
885
760, 761, 762, 765, 771, 774, 779, 784, 793, 802,
886
814, 819, 824, 829, 834, 841, 844, 847, 850, 853,
887
856, 859, 862, 865, 868, 871, 874, 877, 880, 883,
888
886, 889, 894, 908, 917, 938, 961, 962, 965, 965,
889
977, 980, 981, 988, 989, 992, 992, 1004, 1007, 1008,
890
1015, 1016, 1019, 1019, 1031, 1034, 1035, 1038, 1038, 1050,
891
1053, 1054, 1061, 1065, 1071, 1080, 1088, 1097, 1106, 1117,
892
1118, 1125, 1129, 1135, 1144, 1152
893
};
894
#endif
895
896
/** Accessing symbol of state STATE. */
897
#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
898
899
#if YYDEBUG || 0
900
/* The user-facing name of the symbol whose (internal) number is
901
YYSYMBOL. No bounds checking. */
902
static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
903
904
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
905
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
906
static const char *const yytname[] =
907
{
908
"\"end of file\"", "error", "\"invalid token\"", "COMMAND", "ALIAS",
909
"DEFVAR", "NTWKADDR", "NETGROUP", "USERGROUP", "WORD", "DIGEST",
910
"INCLUDE", "INCLUDEDIR", "DEFAULTS", "DEFAULTS_HOST", "DEFAULTS_USER",
911
"DEFAULTS_RUNAS", "DEFAULTS_CMND", "NOPASSWD", "PASSWD", "NOEXEC",
912
"EXEC", "SETENV", "NOSETENV", "LOG_INPUT", "NOLOG_INPUT", "LOG_OUTPUT",
913
"NOLOG_OUTPUT", "MAIL", "NOMAIL", "FOLLOWLNK", "NOFOLLOWLNK",
914
"INTERCEPT", "NOINTERCEPT", "ALL", "HOSTALIAS", "CMNDALIAS", "USERALIAS",
915
"RUNASALIAS", "':'", "'='", "','", "'!'", "'+'", "'-'", "'('", "')'",
916
"'\\n'", "ERROR", "NOMATCH", "CHROOT", "CWD", "TYPE", "ROLE",
917
"APPARMOR_PROFILE", "PRIVS", "LIMITPRIVS", "CMND_TIMEOUT", "NOTBEFORE",
918
"NOTAFTER", "MYSELF", "SHA224_TOK", "SHA256_TOK", "SHA384_TOK",
919
"SHA512_TOK", "$accept", "file", "line", "entry", "include",
920
"includedir", "defaults_list", "defaults_entry", "privileges",
921
"privilege", "ophost", "host", "cmndspeclist", "cmndspec", "digestspec",
922
"digestlist", "digcmnd", "opcmnd", "chdirspec", "chrootspec",
923
"timeoutspec", "notbeforespec", "notafterspec", "rolespec", "typespec",
924
"apparmor_profilespec", "privsspec", "limitprivsspec", "runasspec",
925
"runaslist", "reserved_word", "reserved_alias", "options", "cmndtag",
926
"cmnd", "hostaliases", "hostalias", "$@1", "hostlist", "cmndaliases",
927
"cmndalias", "$@2", "cmndlist", "runasaliases", "runasalias", "$@3",
928
"useraliases", "useralias", "$@4", "userlist", "opuser", "user",
929
"grouplist", "opgroup", "group", YY_NULLPTR
930
};
931
932
static const char *
933
yysymbol_name (yysymbol_kind_t yysymbol)
934
{
935
return yytname[yysymbol];
936
}
937
#endif
938
939
#define YYPACT_NINF (-116)
940
941
#define yypact_value_is_default(Yyn) \
942
((Yyn) == YYPACT_NINF)
943
944
#define YYTABLE_NINF (-4)
945
946
#define yytable_value_is_error(Yyn) \
947
0
948
949
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
950
STATE-NUM. */
951
static const yytype_int16 yypact[] =
952
{
953
174, -29, -116, -116, -116, -116, 35, 38, 11, 239,
954
150, 150, 8, -116, 32, 76, 88, 114, 254, -116,
955
58, 218, -116, -116, -116, 70, -116, -116, -116, 12,
956
13, 136, 73, 14, -116, -116, -116, -116, -116, -116,
957
276, -116, -116, 4, 10, 10, -116, -116, -116, -116,
958
190, 42, 81, 85, 97, -116, 64, -116, -116, -116,
959
52, -116, -116, -116, -116, -116, -116, -116, -116, -116,
960
-116, -116, -116, -116, 57, 2, -116, -116, 111, 9,
961
-116, -116, 112, 56, -116, -116, 123, 61, -116, -116,
962
-116, -116, 150, 62, -116, 75, 90, -116, 130, -116,
963
188, 204, 205, -116, 11, -116, -116, 239, 55, 66,
964
108, -116, 207, 210, 213, 228, 143, -116, 8, 155,
965
175, 239, 32, -116, 209, 8, 76, -116, 211, 150,
966
88, -116, 217, 150, 114, -116, -116, 194, -116, 202,
967
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
968
-116, -116, -116, -116, -116, -116, -116, 239, 225, -116,
969
8, 227, -116, 150, 229, -116, 150, 229, -116, -116,
970
-116, 233, 230, -116, -116, 225, 227, 229, 229, 235,
971
232, 121, 202, 240, -116, -116, -116, 255, 238, -116,
972
-116, -116, 235, -116, 234, 236, 244, 246, 247, 260,
973
261, 262, 263, 264, -116, -116, -116, -116, -116, -116,
974
-116, -116, -116, -116, 1, -116, 235, 238, 241, 296,
975
297, 298, 299, 300, 302, 303, 304, 305, -116, -116,
976
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
977
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
978
-116, -116, -116, -116, -116, -116
979
};
980
981
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
982
Performed when YYTABLE does not specify something else to do. Zero
983
means the default is an error. */
984
static const yytype_uint8 yydefact[] =
985
{
986
0, 0, 144, 146, 147, 148, 0, 0, 0, 0,
987
0, 0, 0, 145, 0, 0, 0, 0, 0, 6,
988
0, 0, 4, 8, 9, 0, 140, 142, 7, 0,
989
0, 26, 0, 0, 24, 37, 40, 39, 41, 38,
990
0, 121, 35, 0, 0, 0, 114, 113, 115, 112,
991
0, 0, 0, 0, 0, 49, 0, 128, 51, 53,
992
0, 118, 72, 73, 74, 79, 78, 82, 80, 81,
993
75, 76, 77, 83, 0, 0, 116, 125, 0, 0,
994
123, 137, 0, 0, 135, 132, 0, 0, 130, 143,
995
1, 5, 0, 0, 31, 0, 0, 20, 0, 22,
996
0, 0, 0, 27, 0, 15, 36, 0, 0, 0,
997
0, 54, 0, 0, 0, 0, 0, 52, 0, 0,
998
0, 0, 0, 12, 0, 0, 0, 13, 0, 0,
999
0, 11, 0, 0, 0, 14, 141, 0, 10, 65,
1000
21, 23, 28, 29, 30, 25, 122, 18, 16, 17,
1001
45, 46, 47, 48, 50, 129, 19, 0, 120, 117,
1002
0, 127, 124, 0, 139, 136, 0, 134, 131, 33,
1003
32, 67, 34, 42, 84, 119, 126, 138, 133, 71,
1004
0, 68, 65, 95, 153, 155, 154, 0, 70, 149,
1005
151, 66, 0, 43, 0, 0, 0, 0, 0, 0,
1006
0, 0, 0, 0, 85, 86, 89, 87, 88, 90,
1007
91, 92, 93, 94, 0, 152, 0, 69, 0, 0,
1008
0, 0, 0, 0, 0, 0, 0, 0, 96, 97,
1009
98, 99, 102, 103, 104, 105, 106, 107, 110, 111,
1010
108, 109, 100, 101, 44, 150, 56, 55, 61, 60,
1011
62, 63, 64, 57, 58, 59
1012
};
1013
1014
/* YYPGOTO[NTERM-NUM]. */
1015
static const yytype_int16 yypgoto[] =
1016
{
1017
-116, -116, -116, 294, -116, -116, -6, 212, -116, 180,
1018
214, 278, -116, 137, 206, -116, -115, 267, -116, -116,
1019
-116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
1020
-116, -9, -116, -116, 270, -116, 203, -116, -7, -116,
1021
198, -116, -85, -116, 192, -116, -116, 197, -116, -10,
1022
237, 310, 138, 115, 145
1023
};
1024
1025
/* YYDEFGOTO[NTERM-NUM]. */
1026
static const yytype_uint8 yydefgoto[] =
1027
{
1028
0, 20, 21, 22, 23, 24, 33, 34, 93, 94,
1029
41, 42, 172, 173, 55, 56, 57, 58, 204, 205,
1030
206, 207, 208, 209, 210, 211, 212, 213, 174, 180,
1031
73, 74, 183, 214, 59, 75, 76, 120, 95, 79,
1032
80, 124, 60, 87, 88, 132, 83, 84, 128, 25,
1033
26, 27, 188, 189, 190
1034
};
1035
1036
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
1037
positive, shift that token. If negative, reduce the rule whose
1038
number is the opposite. If YYTABLE_NINF, syntax error. */
1039
static const yytype_int16 yytable[] =
1040
{
1041
44, 45, 43, 155, 46, 47, 78, 82, 86, 31,
1042
48, 46, 47, 96, 98, 31, 31, 48, 28, 228,
1043
229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
1044
239, 240, 241, 242, 243, 49, 61, 108, 109, 110,
1045
161, 122, 49, 50, 29, 107, 32, 30, 126, 123,
1046
50, 92, 32, 32, 119, 104, 127, 31, 90, 97,
1047
99, 105, 51, 52, 53, 54, 62, 46, 47, 51,
1048
52, 53, 54, 48, 35, 176, 36, 37, 103, 38,
1049
77, 112, 63, 64, 65, 66, 67, 68, 69, 70,
1050
71, 72, 81, 118, 32, 130, 104, 121, 49, 244,
1051
134, 137, 147, 131, 39, 116, 50, 104, 135, 138,
1052
62, 92, 40, 148, 158, 139, 107, 78, 85, 164,
1053
113, 82, 62, 167, 114, 86, 63, 64, 65, 66,
1054
67, 68, 69, 70, 71, 72, 115, 140, 63, 64,
1055
65, 66, 67, 68, 69, 70, 71, 72, 62, 104,
1056
175, 125, 129, 177, 2, 149, 178, 3, 4, 5,
1057
192, 181, 92, 133, 63, 64, 65, 66, 67, 68,
1058
69, 70, 71, 72, -2, 1, 100, 141, 2, 101,
1059
102, 3, 4, 5, 13, 6, 7, 8, 9, 10,
1060
11, 12, 18, 46, 47, 169, 104, 142, 35, 48,
1061
36, 37, 156, 38, 51, 52, 53, 54, 13, 14,
1062
15, 16, 17, 143, 144, 157, 18, 150, -3, 1,
1063
151, 19, 2, 152, 49, 3, 4, 5, 39, 6,
1064
7, 8, 9, 10, 11, 12, 40, 2, 153, 184,
1065
3, 4, 5, 35, 185, 36, 37, 171, 38, 160,
1066
246, 163, 13, 14, 15, 16, 17, 166, 2, 184,
1067
18, 3, 4, 5, 185, 19, 107, 13, 118, 186,
1068
92, 182, 179, 39, 218, 18, 219, 187, 191, 216,
1069
35, 40, 36, 37, 220, 38, 221, 222, 13, 186,
1070
194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
1071
223, 224, 225, 226, 227, 247, 248, 249, 250, 251,
1072
39, 252, 253, 254, 255, 91, 145, 170, 106, 193,
1073
111, 146, 154, 117, 162, 159, 168, 165, 89, 136,
1074
217, 245, 215
1075
};
1076
1077
static const yytype_uint8 yycheck[] =
1078
{
1079
10, 11, 9, 118, 3, 4, 15, 16, 17, 5,
1080
9, 3, 4, 1, 1, 5, 5, 9, 47, 18,
1081
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
1082
29, 30, 31, 32, 33, 34, 4, 43, 44, 45,
1083
125, 39, 34, 42, 9, 41, 42, 9, 39, 47,
1084
42, 41, 42, 42, 60, 41, 47, 5, 0, 47,
1085
47, 47, 61, 62, 63, 64, 34, 3, 4, 61,
1086
62, 63, 64, 9, 4, 160, 6, 7, 5, 9,
1087
4, 39, 50, 51, 52, 53, 54, 55, 56, 57,
1088
58, 59, 4, 41, 42, 39, 41, 40, 34, 214,
1089
39, 39, 47, 47, 34, 41, 42, 41, 47, 47,
1090
34, 41, 42, 47, 121, 40, 41, 126, 4, 129,
1091
39, 130, 34, 133, 39, 134, 50, 51, 52, 53,
1092
54, 55, 56, 57, 58, 59, 39, 47, 50, 51,
1093
52, 53, 54, 55, 56, 57, 58, 59, 34, 41,
1094
157, 40, 40, 163, 4, 47, 166, 7, 8, 9,
1095
39, 171, 41, 40, 50, 51, 52, 53, 54, 55,
1096
56, 57, 58, 59, 0, 1, 40, 47, 4, 43,
1097
44, 7, 8, 9, 34, 11, 12, 13, 14, 15,
1098
16, 17, 42, 3, 4, 1, 41, 9, 4, 9,
1099
6, 7, 47, 9, 61, 62, 63, 64, 34, 35,
1100
36, 37, 38, 9, 9, 40, 42, 10, 0, 1,
1101
10, 47, 4, 10, 34, 7, 8, 9, 34, 11,
1102
12, 13, 14, 15, 16, 17, 42, 4, 10, 4,
1103
7, 8, 9, 4, 9, 6, 7, 45, 9, 40,
1104
9, 40, 34, 35, 36, 37, 38, 40, 4, 4,
1105
42, 7, 8, 9, 9, 47, 41, 34, 41, 34,
1106
41, 41, 39, 34, 40, 42, 40, 42, 46, 41,
1107
4, 42, 6, 7, 40, 9, 40, 40, 34, 34,
1108
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
1109
40, 40, 40, 40, 40, 9, 9, 9, 9, 9,
1110
34, 9, 9, 9, 9, 21, 104, 137, 40, 182,
1111
50, 107, 116, 56, 126, 122, 134, 130, 18, 92,
1112
192, 216, 187
1113
};
1114
1115
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
1116
state STATE-NUM. */
1117
static const yytype_int8 yystos[] =
1118
{
1119
0, 1, 4, 7, 8, 9, 11, 12, 13, 14,
1120
15, 16, 17, 34, 35, 36, 37, 38, 42, 47,
1121
66, 67, 68, 69, 70, 114, 115, 116, 47, 9,
1122
9, 5, 42, 71, 72, 4, 6, 7, 9, 34,
1123
42, 75, 76, 103, 114, 114, 3, 4, 9, 34,
1124
42, 61, 62, 63, 64, 79, 80, 81, 82, 99,
1125
107, 4, 34, 50, 51, 52, 53, 54, 55, 56,
1126
57, 58, 59, 95, 96, 100, 101, 4, 96, 104,
1127
105, 4, 96, 111, 112, 4, 96, 108, 109, 116,
1128
0, 68, 41, 73, 74, 103, 1, 47, 1, 47,
1129
40, 43, 44, 5, 41, 47, 76, 41, 71, 71,
1130
71, 99, 39, 39, 39, 39, 41, 82, 41, 71,
1131
102, 40, 39, 47, 106, 40, 39, 47, 113, 40,
1132
39, 47, 110, 40, 39, 47, 115, 39, 47, 40,
1133
47, 47, 9, 9, 9, 72, 75, 47, 47, 47,
1134
10, 10, 10, 10, 79, 81, 47, 40, 103, 101,
1135
40, 107, 105, 40, 114, 112, 40, 114, 109, 1,
1136
74, 45, 77, 78, 93, 103, 107, 114, 114, 39,
1137
94, 114, 41, 97, 4, 9, 34, 42, 117, 118,
1138
119, 46, 39, 78, 50, 51, 52, 53, 54, 55,
1139
56, 57, 58, 59, 83, 84, 85, 86, 87, 88,
1140
89, 90, 91, 92, 98, 119, 41, 117, 40, 40,
1141
40, 40, 40, 40, 40, 40, 40, 40, 18, 19,
1142
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1143
30, 31, 32, 33, 81, 118, 9, 9, 9, 9,
1144
9, 9, 9, 9, 9, 9
1145
};
1146
1147
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
1148
static const yytype_int8 yyr1[] =
1149
{
1150
0, 65, 66, 66, 67, 67, 68, 68, 68, 68,
1151
68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
1152
69, 69, 70, 70, 71, 71, 72, 72, 72, 72,
1153
72, 73, 73, 73, 74, 75, 75, 76, 76, 76,
1154
76, 76, 77, 77, 78, 79, 79, 79, 79, 80,
1155
80, 81, 81, 82, 82, 83, 84, 85, 86, 87,
1156
88, 89, 90, 91, 92, 93, 93, 94, 94, 94,
1157
94, 94, 95, 95, 95, 95, 95, 95, 95, 95,
1158
95, 95, 95, 96, 97, 97, 97, 97, 97, 97,
1159
97, 97, 97, 97, 97, 98, 98, 98, 98, 98,
1160
98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
1161
98, 98, 99, 99, 99, 99, 100, 100, 102, 101,
1162
101, 103, 103, 104, 104, 106, 105, 105, 107, 107,
1163
108, 108, 110, 109, 109, 111, 111, 113, 112, 112,
1164
114, 114, 115, 115, 116, 116, 116, 116, 116, 117,
1165
117, 118, 118, 119, 119, 119
1166
};
1167
1168
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
1169
static const yytype_int8 yyr2[] =
1170
{
1171
0, 2, 0, 1, 1, 2, 1, 2, 1, 1,
1172
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
1173
3, 4, 3, 4, 1, 3, 1, 2, 3, 3,
1174
3, 1, 3, 3, 3, 1, 2, 1, 1, 1,
1175
1, 1, 1, 3, 4, 3, 3, 3, 3, 1,
1176
3, 1, 2, 1, 2, 3, 3, 3, 3, 3,
1177
3, 3, 3, 3, 3, 0, 3, 0, 1, 3,
1178
2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1179
1, 1, 1, 1, 0, 2, 2, 2, 2, 2,
1180
2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
1181
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1182
2, 2, 1, 1, 1, 1, 1, 3, 0, 4,
1183
3, 1, 3, 1, 3, 0, 4, 3, 1, 3,
1184
1, 3, 0, 4, 3, 1, 3, 0, 4, 3,
1185
1, 3, 1, 2, 1, 1, 1, 1, 1, 1,
1186
3, 1, 2, 1, 1, 1
1187
};
1188
1189
1190
enum { YYENOMEM = -2 };
1191
1192
#define yyerrok (yyerrstatus = 0)
1193
#define yyclearin (yychar = YYEMPTY)
1194
1195
#define YYACCEPT goto yyacceptlab
1196
#define YYABORT goto yyabortlab
1197
#define YYERROR goto yyerrorlab
1198
#define YYNOMEM goto yyexhaustedlab
1199
1200
1201
#define YYRECOVERING() (!!yyerrstatus)
1202
1203
#define YYBACKUP(Token, Value) \
1204
do \
1205
if (yychar == YYEMPTY) \
1206
{ \
1207
yychar = (Token); \
1208
yylval = (Value); \
1209
YYPOPSTACK (yylen); \
1210
yystate = *yyssp; \
1211
goto yybackup; \
1212
} \
1213
else \
1214
{ \
1215
yyerror (YY_("syntax error: cannot back up")); \
1216
YYERROR; \
1217
} \
1218
while (0)
1219
1220
/* Backward compatibility with an undocumented macro.
1221
Use YYerror or YYUNDEF. */
1222
#define YYERRCODE YYUNDEF
1223
1224
1225
/* Enable debugging if requested. */
1226
#if YYDEBUG
1227
1228
# ifndef YYFPRINTF
1229
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1230
# define YYFPRINTF fprintf
1231
# endif
1232
1233
# define YYDPRINTF(Args) \
1234
do { \
1235
if (yydebug) \
1236
YYFPRINTF Args; \
1237
} while (0)
1238
1239
1240
1241
1242
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
1243
do { \
1244
if (yydebug) \
1245
{ \
1246
YYFPRINTF (stderr, "%s ", Title); \
1247
yy_symbol_print (stderr, \
1248
Kind, Value); \
1249
YYFPRINTF (stderr, "\n"); \
1250
} \
1251
} while (0)
1252
1253
1254
/*-----------------------------------.
1255
| Print this symbol's value on YYO. |
1256
`-----------------------------------*/
1257
1258
static void
1259
yy_symbol_value_print (FILE *yyo,
1260
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
1261
{
1262
FILE *yyoutput = yyo;
1263
YY_USE (yyoutput);
1264
if (!yyvaluep)
1265
return;
1266
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1267
YY_USE (yykind);
1268
YY_IGNORE_MAYBE_UNINITIALIZED_END
1269
}
1270
1271
1272
/*---------------------------.
1273
| Print this symbol on YYO. |
1274
`---------------------------*/
1275
1276
static void
1277
yy_symbol_print (FILE *yyo,
1278
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
1279
{
1280
YYFPRINTF (yyo, "%s %s (",
1281
yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
1282
1283
yy_symbol_value_print (yyo, yykind, yyvaluep);
1284
YYFPRINTF (yyo, ")");
1285
}
1286
1287
/*------------------------------------------------------------------.
1288
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1289
| TOP (included). |
1290
`------------------------------------------------------------------*/
1291
1292
static void
1293
yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
1294
{
1295
YYFPRINTF (stderr, "Stack now");
1296
for (; yybottom <= yytop; yybottom++)
1297
{
1298
int yybot = *yybottom;
1299
YYFPRINTF (stderr, " %d", yybot);
1300
}
1301
YYFPRINTF (stderr, "\n");
1302
}
1303
1304
# define YY_STACK_PRINT(Bottom, Top) \
1305
do { \
1306
if (yydebug) \
1307
yy_stack_print ((Bottom), (Top)); \
1308
} while (0)
1309
1310
1311
/*------------------------------------------------.
1312
| Report that the YYRULE is going to be reduced. |
1313
`------------------------------------------------*/
1314
1315
static void
1316
yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
1317
int yyrule)
1318
{
1319
int yylno = yyrline[yyrule];
1320
int yynrhs = yyr2[yyrule];
1321
int yyi;
1322
YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
1323
yyrule - 1, yylno);
1324
/* The symbols being reduced. */
1325
for (yyi = 0; yyi < yynrhs; yyi++)
1326
{
1327
YYFPRINTF (stderr, " $%d = ", yyi + 1);
1328
yy_symbol_print (stderr,
1329
YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
1330
&yyvsp[(yyi + 1) - (yynrhs)]);
1331
YYFPRINTF (stderr, "\n");
1332
}
1333
}
1334
1335
# define YY_REDUCE_PRINT(Rule) \
1336
do { \
1337
if (yydebug) \
1338
yy_reduce_print (yyssp, yyvsp, Rule); \
1339
} while (0)
1340
1341
/* Nonzero means print parse trace. It is left uninitialized so that
1342
multiple parsers can coexist. */
1343
int yydebug;
1344
#else /* !YYDEBUG */
1345
# define YYDPRINTF(Args) ((void) 0)
1346
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
1347
# define YY_STACK_PRINT(Bottom, Top)
1348
# define YY_REDUCE_PRINT(Rule)
1349
#endif /* !YYDEBUG */
1350
1351
1352
/* YYINITDEPTH -- initial size of the parser's stacks. */
1353
#ifndef YYINITDEPTH
1354
# define YYINITDEPTH 200
1355
#endif
1356
1357
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1358
if the built-in stack extension method is used).
1359
1360
Do not make this value too large; the results are undefined if
1361
YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1362
evaluated with infinite-precision integer arithmetic. */
1363
1364
#ifndef YYMAXDEPTH
1365
# define YYMAXDEPTH 10000
1366
#endif
1367
1368
1369
1370
1371
1372
1373
/*-----------------------------------------------.
1374
| Release the memory associated to this symbol. |
1375
`-----------------------------------------------*/
1376
1377
static void
1378
yydestruct (const char *yymsg,
1379
yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
1380
{
1381
YY_USE (yyvaluep);
1382
if (!yymsg)
1383
yymsg = "Deleting";
1384
YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
1385
1386
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1387
YY_USE (yykind);
1388
YY_IGNORE_MAYBE_UNINITIALIZED_END
1389
}
1390
1391
1392
/* Lookahead token kind. */
1393
int yychar;
1394
1395
/* The semantic value of the lookahead symbol. */
1396
YYSTYPE yylval;
1397
/* Number of syntax errors so far. */
1398
int yynerrs;
1399
1400
1401
1402
1403
/*----------.
1404
| yyparse. |
1405
`----------*/
1406
1407
int
1408
yyparse (void)
1409
{
1410
yy_state_fast_t yystate = 0;
1411
/* Number of tokens to shift before error messages enabled. */
1412
int yyerrstatus = 0;
1413
1414
/* Refer to the stacks through separate pointers, to allow yyoverflow
1415
to reallocate them elsewhere. */
1416
1417
/* Their size. */
1418
YYPTRDIFF_T yystacksize = YYINITDEPTH;
1419
1420
/* The state stack: array, bottom, top. */
1421
yy_state_t yyssa[YYINITDEPTH];
1422
yy_state_t *yyss = yyssa;
1423
yy_state_t *yyssp = yyss;
1424
1425
/* The semantic value stack: array, bottom, top. */
1426
YYSTYPE yyvsa[YYINITDEPTH];
1427
YYSTYPE *yyvs = yyvsa;
1428
YYSTYPE *yyvsp = yyvs;
1429
1430
int yyn;
1431
/* The return value of yyparse. */
1432
int yyresult;
1433
/* Lookahead symbol kind. */
1434
yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
1435
/* The variables used to return semantic value and location from the
1436
action routines. */
1437
YYSTYPE yyval;
1438
1439
1440
1441
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1442
1443
/* The number of symbols on the RHS of the reduced rule.
1444
Keep to zero when no symbol should be popped. */
1445
int yylen = 0;
1446
1447
YYDPRINTF ((stderr, "Starting parse\n"));
1448
1449
yychar = YYEMPTY; /* Cause a token to be read. */
1450
1451
goto yysetstate;
1452
1453
1454
/*------------------------------------------------------------.
1455
| yynewstate -- push a new state, which is found in yystate. |
1456
`------------------------------------------------------------*/
1457
yynewstate:
1458
/* In all cases, when you get here, the value and location stacks
1459
have just been pushed. So pushing a state here evens the stacks. */
1460
yyssp++;
1461
1462
1463
/*--------------------------------------------------------------------.
1464
| yysetstate -- set current state (the top of the stack) to yystate. |
1465
`--------------------------------------------------------------------*/
1466
yysetstate:
1467
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1468
YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
1469
YY_IGNORE_USELESS_CAST_BEGIN
1470
*yyssp = YY_CAST (yy_state_t, yystate);
1471
YY_IGNORE_USELESS_CAST_END
1472
YY_STACK_PRINT (yyss, yyssp);
1473
1474
if (yyss + yystacksize - 1 <= yyssp)
1475
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
1476
YYNOMEM;
1477
#else
1478
{
1479
/* Get the current used size of the three stacks, in elements. */
1480
YYPTRDIFF_T yysize = yyssp - yyss + 1;
1481
1482
# if defined yyoverflow
1483
{
1484
/* Give user a chance to reallocate the stack. Use copies of
1485
these so that the &'s don't force the real ones into
1486
memory. */
1487
yy_state_t *yyss1 = yyss;
1488
YYSTYPE *yyvs1 = yyvs;
1489
1490
/* Each stack pointer address is followed by the size of the
1491
data in use in that stack, in bytes. This used to be a
1492
conditional around just the two extra args, but that might
1493
be undefined if yyoverflow is a macro. */
1494
yyoverflow (YY_("memory exhausted"),
1495
&yyss1, yysize * YYSIZEOF (*yyssp),
1496
&yyvs1, yysize * YYSIZEOF (*yyvsp),
1497
&yystacksize);
1498
yyss = yyss1;
1499
yyvs = yyvs1;
1500
}
1501
# else /* defined YYSTACK_RELOCATE */
1502
/* Extend the stack our own way. */
1503
if (YYMAXDEPTH <= yystacksize)
1504
YYNOMEM;
1505
yystacksize *= 2;
1506
if (YYMAXDEPTH < yystacksize)
1507
yystacksize = YYMAXDEPTH;
1508
1509
{
1510
yy_state_t *yyss1 = yyss;
1511
union yyalloc *yyptr =
1512
YY_CAST (union yyalloc *,
1513
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
1514
if (! yyptr)
1515
YYNOMEM;
1516
YYSTACK_RELOCATE (yyss_alloc, yyss);
1517
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1518
# undef YYSTACK_RELOCATE
1519
if (yyss1 != yyssa)
1520
YYSTACK_FREE (yyss1);
1521
}
1522
# endif
1523
1524
yyssp = yyss + yysize - 1;
1525
yyvsp = yyvs + yysize - 1;
1526
1527
YY_IGNORE_USELESS_CAST_BEGIN
1528
YYDPRINTF ((stderr, "Stack size increased to %ld\n",
1529
YY_CAST (long, yystacksize)));
1530
YY_IGNORE_USELESS_CAST_END
1531
1532
if (yyss + yystacksize - 1 <= yyssp)
1533
YYABORT;
1534
}
1535
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
1536
1537
1538
if (yystate == YYFINAL)
1539
YYACCEPT;
1540
1541
goto yybackup;
1542
1543
1544
/*-----------.
1545
| yybackup. |
1546
`-----------*/
1547
yybackup:
1548
/* Do appropriate processing given the current state. Read a
1549
lookahead token if we need one and don't already have one. */
1550
1551
/* First try to decide what to do without reference to lookahead token. */
1552
yyn = yypact[yystate];
1553
if (yypact_value_is_default (yyn))
1554
goto yydefault;
1555
1556
/* Not known => get a lookahead token if don't already have one. */
1557
1558
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
1559
if (yychar == YYEMPTY)
1560
{
1561
YYDPRINTF ((stderr, "Reading a token\n"));
1562
yychar = yylex ();
1563
}
1564
1565
if (yychar <= YYEOF)
1566
{
1567
yychar = YYEOF;
1568
yytoken = YYSYMBOL_YYEOF;
1569
YYDPRINTF ((stderr, "Now at end of input.\n"));
1570
}
1571
else if (yychar == YYerror)
1572
{
1573
/* The scanner already issued an error message, process directly
1574
to error recovery. But do not keep the error token as
1575
lookahead, it is too special and may lead us to an endless
1576
loop in error recovery. */
1577
yychar = YYUNDEF;
1578
yytoken = YYSYMBOL_YYerror;
1579
goto yyerrlab1;
1580
}
1581
else
1582
{
1583
yytoken = YYTRANSLATE (yychar);
1584
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1585
}
1586
1587
/* If the proper action on seeing token YYTOKEN is to reduce or to
1588
detect an error, take that action. */
1589
yyn += yytoken;
1590
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1591
goto yydefault;
1592
yyn = yytable[yyn];
1593
if (yyn <= 0)
1594
{
1595
if (yytable_value_is_error (yyn))
1596
goto yyerrlab;
1597
yyn = -yyn;
1598
goto yyreduce;
1599
}
1600
1601
/* Count tokens shifted since error; after three, turn off error
1602
status. */
1603
if (yyerrstatus)
1604
yyerrstatus--;
1605
1606
/* Shift the lookahead token. */
1607
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1608
yystate = yyn;
1609
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1610
*++yyvsp = yylval;
1611
YY_IGNORE_MAYBE_UNINITIALIZED_END
1612
1613
/* Discard the shifted token. */
1614
yychar = YYEMPTY;
1615
goto yynewstate;
1616
1617
1618
/*-----------------------------------------------------------.
1619
| yydefault -- do the default action for the current state. |
1620
`-----------------------------------------------------------*/
1621
yydefault:
1622
yyn = yydefact[yystate];
1623
if (yyn == 0)
1624
goto yyerrlab;
1625
goto yyreduce;
1626
1627
1628
/*-----------------------------.
1629
| yyreduce -- do a reduction. |
1630
`-----------------------------*/
1631
yyreduce:
1632
/* yyn is the number of a rule to reduce with. */
1633
yylen = yyr2[yyn];
1634
1635
/* If YYLEN is nonzero, implement the default value of the action:
1636
'$$ = $1'.
1637
1638
Otherwise, the following line sets YYVAL to garbage.
1639
This behavior is undocumented and Bison
1640
users should not rely upon it. Assigning to YYVAL
1641
unconditionally makes the parser a bit smaller, and it avoids a
1642
GCC warning that YYVAL may be used uninitialized. */
1643
yyval = yyvsp[1-yylen];
1644
1645
1646
YY_REDUCE_PRINT (yyn);
1647
switch (yyn)
1648
{
1649
case 2: /* file: %empty */
1650
#line 205 "gram.y"
1651
{
1652
; /* empty file */
1653
}
1654
#line 1654 "gram.c"
1655
break;
1656
1657
case 6: /* entry: '\n' */
1658
#line 215 "gram.y"
1659
{
1660
; /* blank line */
1661
}
1662
#line 1662 "gram.c"
1663
break;
1664
1665
case 7: /* entry: error '\n' */
1666
#line 218 "gram.y"
1667
{
1668
yyerrok;
1669
}
1670
#line 1670 "gram.c"
1671
break;
1672
1673
case 8: /* entry: include */
1674
#line 221 "gram.y"
1675
{
1676
const bool success = push_include((yyvsp[0].string),
1677
parsed_policy.ctx->user.shost, &parser_conf);
1678
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1679
free((yyvsp[0].string));
1680
if (!success && !parser_conf.recovery)
1681
YYERROR;
1682
}
1683
#line 1683 "gram.c"
1684
break;
1685
1686
case 9: /* entry: includedir */
1687
#line 229 "gram.y"
1688
{
1689
const bool success = push_includedir((yyvsp[0].string),
1690
parsed_policy.ctx->user.shost, &parser_conf);
1691
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1692
free((yyvsp[0].string));
1693
if (!success && !parser_conf.recovery)
1694
YYERROR;
1695
}
1696
#line 1696 "gram.c"
1697
break;
1698
1699
case 10: /* entry: userlist privileges '\n' */
1700
#line 237 "gram.y"
1701
{
1702
if (!add_userspec((yyvsp[-2].member), (yyvsp[-1].privilege))) {
1703
sudoerserror(N_("unable to allocate memory"));
1704
YYERROR;
1705
}
1706
}
1707
#line 1707 "gram.c"
1708
break;
1709
1710
case 11: /* entry: USERALIAS useraliases '\n' */
1711
#line 243 "gram.y"
1712
{
1713
;
1714
}
1715
#line 1715 "gram.c"
1716
break;
1717
1718
case 12: /* entry: HOSTALIAS hostaliases '\n' */
1719
#line 246 "gram.y"
1720
{
1721
;
1722
}
1723
#line 1723 "gram.c"
1724
break;
1725
1726
case 13: /* entry: CMNDALIAS cmndaliases '\n' */
1727
#line 249 "gram.y"
1728
{
1729
;
1730
}
1731
#line 1731 "gram.c"
1732
break;
1733
1734
case 14: /* entry: RUNASALIAS runasaliases '\n' */
1735
#line 252 "gram.y"
1736
{
1737
;
1738
}
1739
#line 1739 "gram.c"
1740
break;
1741
1742
case 15: /* entry: DEFAULTS defaults_list '\n' */
1743
#line 255 "gram.y"
1744
{
1745
if (!add_defaults(DEFAULTS, NULL, (yyvsp[-1].defaults)))
1746
YYERROR;
1747
}
1748
#line 1748 "gram.c"
1749
break;
1750
1751
case 16: /* entry: DEFAULTS_USER userlist defaults_list '\n' */
1752
#line 259 "gram.y"
1753
{
1754
if (!add_defaults(DEFAULTS_USER, (yyvsp[-2].member), (yyvsp[-1].defaults)))
1755
YYERROR;
1756
}
1757
#line 1757 "gram.c"
1758
break;
1759
1760
case 17: /* entry: DEFAULTS_RUNAS userlist defaults_list '\n' */
1761
#line 263 "gram.y"
1762
{
1763
if (!add_defaults(DEFAULTS_RUNAS, (yyvsp[-2].member), (yyvsp[-1].defaults)))
1764
YYERROR;
1765
}
1766
#line 1766 "gram.c"
1767
break;
1768
1769
case 18: /* entry: DEFAULTS_HOST hostlist defaults_list '\n' */
1770
#line 267 "gram.y"
1771
{
1772
if (!add_defaults(DEFAULTS_HOST, (yyvsp[-2].member), (yyvsp[-1].defaults)))
1773
YYERROR;
1774
}
1775
#line 1775 "gram.c"
1776
break;
1777
1778
case 19: /* entry: DEFAULTS_CMND cmndlist defaults_list '\n' */
1779
#line 271 "gram.y"
1780
{
1781
if (!add_defaults(DEFAULTS_CMND, (yyvsp[-2].member), (yyvsp[-1].defaults)))
1782
YYERROR;
1783
}
1784
#line 1784 "gram.c"
1785
break;
1786
1787
case 20: /* include: INCLUDE WORD '\n' */
1788
#line 277 "gram.y"
1789
{
1790
(yyval.string) = (yyvsp[-1].string);
1791
}
1792
#line 1792 "gram.c"
1793
break;
1794
1795
case 21: /* include: INCLUDE WORD error '\n' */
1796
#line 280 "gram.y"
1797
{
1798
yyerrok;
1799
(yyval.string) = (yyvsp[-2].string);
1800
}
1801
#line 1801 "gram.c"
1802
break;
1803
1804
case 22: /* includedir: INCLUDEDIR WORD '\n' */
1805
#line 286 "gram.y"
1806
{
1807
(yyval.string) = (yyvsp[-1].string);
1808
}
1809
#line 1809 "gram.c"
1810
break;
1811
1812
case 23: /* includedir: INCLUDEDIR WORD error '\n' */
1813
#line 289 "gram.y"
1814
{
1815
yyerrok;
1816
(yyval.string) = (yyvsp[-2].string);
1817
}
1818
#line 1818 "gram.c"
1819
break;
1820
1821
case 25: /* defaults_list: defaults_list ',' defaults_entry */
1822
#line 296 "gram.y"
1823
{
1824
parser_leak_remove(LEAK_DEFAULTS, (yyvsp[0].defaults));
1825
HLTQ_CONCAT((yyvsp[-2].defaults), (yyvsp[0].defaults), entries);
1826
(yyval.defaults) = (yyvsp[-2].defaults);
1827
}
1828
#line 1828 "gram.c"
1829
break;
1830
1831
case 26: /* defaults_entry: DEFVAR */
1832
#line 303 "gram.y"
1833
{
1834
(yyval.defaults) = new_default((yyvsp[0].string), NULL, true);
1835
if ((yyval.defaults) == NULL) {
1836
sudoerserror(N_("unable to allocate memory"));
1837
YYERROR;
1838
}
1839
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1840
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
1841
}
1842
#line 1842 "gram.c"
1843
break;
1844
1845
case 27: /* defaults_entry: '!' DEFVAR */
1846
#line 312 "gram.y"
1847
{
1848
(yyval.defaults) = new_default((yyvsp[0].string), NULL, false);
1849
if ((yyval.defaults) == NULL) {
1850
sudoerserror(N_("unable to allocate memory"));
1851
YYERROR;
1852
}
1853
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1854
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
1855
}
1856
#line 1856 "gram.c"
1857
break;
1858
1859
case 28: /* defaults_entry: DEFVAR '=' WORD */
1860
#line 321 "gram.y"
1861
{
1862
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), true);
1863
if ((yyval.defaults) == NULL) {
1864
sudoerserror(N_("unable to allocate memory"));
1865
YYERROR;
1866
}
1867
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
1868
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1869
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
1870
}
1871
#line 1871 "gram.c"
1872
break;
1873
1874
case 29: /* defaults_entry: DEFVAR '+' WORD */
1875
#line 331 "gram.y"
1876
{
1877
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '+');
1878
if ((yyval.defaults) == NULL) {
1879
sudoerserror(N_("unable to allocate memory"));
1880
YYERROR;
1881
}
1882
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
1883
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1884
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
1885
}
1886
#line 1886 "gram.c"
1887
break;
1888
1889
case 30: /* defaults_entry: DEFVAR '-' WORD */
1890
#line 341 "gram.y"
1891
{
1892
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '-');
1893
if ((yyval.defaults) == NULL) {
1894
sudoerserror(N_("unable to allocate memory"));
1895
YYERROR;
1896
}
1897
parser_leak_remove(LEAK_PTR, (yyvsp[-2].string));
1898
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1899
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
1900
}
1901
#line 1901 "gram.c"
1902
break;
1903
1904
case 32: /* privileges: privileges ':' privilege */
1905
#line 354 "gram.y"
1906
{
1907
parser_leak_remove(LEAK_PRIVILEGE, (yyvsp[0].privilege));
1908
HLTQ_CONCAT((yyvsp[-2].privilege), (yyvsp[0].privilege), entries);
1909
(yyval.privilege) = (yyvsp[-2].privilege);
1910
}
1911
#line 1911 "gram.c"
1912
break;
1913
1914
case 33: /* privileges: privileges ':' error */
1915
#line 359 "gram.y"
1916
{
1917
yyerrok;
1918
(yyval.privilege) = (yyvsp[-2].privilege);
1919
}
1920
#line 1920 "gram.c"
1921
break;
1922
1923
case 34: /* privilege: hostlist '=' cmndspeclist */
1924
#line 365 "gram.y"
1925
{
1926
struct privilege *p = calloc(1, sizeof(*p));
1927
if (p == NULL) {
1928
sudoerserror(N_("unable to allocate memory"));
1929
YYERROR;
1930
}
1931
parser_leak_add(LEAK_PRIVILEGE, p);
1932
TAILQ_INIT(&p->defaults);
1933
parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member));
1934
HLTQ_TO_TAILQ(&p->hostlist, (yyvsp[-2].member), entries);
1935
parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec));
1936
HLTQ_TO_TAILQ(&p->cmndlist, (yyvsp[0].cmndspec), entries);
1937
HLTQ_INIT(p, entries);
1938
(yyval.privilege) = p;
1939
}
1940
#line 1940 "gram.c"
1941
break;
1942
1943
case 35: /* ophost: host */
1944
#line 382 "gram.y"
1945
{
1946
(yyval.member) = (yyvsp[0].member);
1947
(yyval.member)->negated = false;
1948
}
1949
#line 1949 "gram.c"
1950
break;
1951
1952
case 36: /* ophost: '!' host */
1953
#line 386 "gram.y"
1954
{
1955
(yyval.member) = (yyvsp[0].member);
1956
(yyval.member)->negated = true;
1957
}
1958
#line 1958 "gram.c"
1959
break;
1960
1961
case 37: /* host: ALIAS */
1962
#line 392 "gram.y"
1963
{
1964
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
1965
if ((yyval.member) == NULL) {
1966
sudoerserror(N_("unable to allocate memory"));
1967
YYERROR;
1968
}
1969
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1970
parser_leak_add(LEAK_MEMBER, (yyval.member));
1971
}
1972
#line 1972 "gram.c"
1973
break;
1974
1975
case 38: /* host: ALL */
1976
#line 401 "gram.y"
1977
{
1978
(yyval.member) = new_member(NULL, ALL);
1979
if ((yyval.member) == NULL) {
1980
sudoerserror(N_("unable to allocate memory"));
1981
YYERROR;
1982
}
1983
parser_leak_add(LEAK_MEMBER, (yyval.member));
1984
}
1985
#line 1985 "gram.c"
1986
break;
1987
1988
case 39: /* host: NETGROUP */
1989
#line 409 "gram.y"
1990
{
1991
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
1992
if ((yyval.member) == NULL) {
1993
sudoerserror(N_("unable to allocate memory"));
1994
YYERROR;
1995
}
1996
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
1997
parser_leak_add(LEAK_MEMBER, (yyval.member));
1998
}
1999
#line 1999 "gram.c"
2000
break;
2001
2002
case 40: /* host: NTWKADDR */
2003
#line 418 "gram.y"
2004
{
2005
(yyval.member) = new_member((yyvsp[0].string), NTWKADDR);
2006
if ((yyval.member) == NULL) {
2007
sudoerserror(N_("unable to allocate memory"));
2008
YYERROR;
2009
}
2010
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2011
parser_leak_add(LEAK_MEMBER, (yyval.member));
2012
}
2013
#line 2013 "gram.c"
2014
break;
2015
2016
case 41: /* host: WORD */
2017
#line 427 "gram.y"
2018
{
2019
(yyval.member) = new_member((yyvsp[0].string), WORD);
2020
if ((yyval.member) == NULL) {
2021
sudoerserror(N_("unable to allocate memory"));
2022
YYERROR;
2023
}
2024
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2025
parser_leak_add(LEAK_MEMBER, (yyval.member));
2026
}
2027
#line 2027 "gram.c"
2028
break;
2029
2030
case 43: /* cmndspeclist: cmndspeclist ',' cmndspec */
2031
#line 439 "gram.y"
2032
{
2033
const struct cmndspec *prev =
2034
HLTQ_LAST((yyvsp[-2].cmndspec), cmndspec, entries);
2035
propagate_cmndspec((yyvsp[0].cmndspec), prev);
2036
parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec));
2037
HLTQ_CONCAT((yyvsp[-2].cmndspec), (yyvsp[0].cmndspec), entries);
2038
(yyval.cmndspec) = (yyvsp[-2].cmndspec);
2039
}
2040
#line 2040 "gram.c"
2041
break;
2042
2043
case 44: /* cmndspec: runasspec options cmndtag digcmnd */
2044
#line 449 "gram.y"
2045
{
2046
struct cmndspec *cs = calloc(1, sizeof(*cs));
2047
if (cs == NULL) {
2048
sudoerserror(N_("unable to allocate memory"));
2049
YYERROR;
2050
}
2051
parser_leak_add(LEAK_CMNDSPEC, cs);
2052
if ((yyvsp[-3].runas) != NULL) {
2053
if ((yyvsp[-3].runas)->runasusers != NULL) {
2054
cs->runasuserlist =
2055
malloc(sizeof(*cs->runasuserlist));
2056
if (cs->runasuserlist == NULL) {
2057
free(cs);
2058
sudoerserror(N_("unable to allocate memory"));
2059
YYERROR;
2060
}
2061
/* g/c done via runas container */
2062
HLTQ_TO_TAILQ(cs->runasuserlist,
2063
(yyvsp[-3].runas)->runasusers, entries);
2064
}
2065
if ((yyvsp[-3].runas)->runasgroups != NULL) {
2066
cs->runasgrouplist =
2067
malloc(sizeof(*cs->runasgrouplist));
2068
if (cs->runasgrouplist == NULL) {
2069
free(cs);
2070
sudoerserror(N_("unable to allocate memory"));
2071
YYERROR;
2072
}
2073
/* g/c done via runas container */
2074
HLTQ_TO_TAILQ(cs->runasgrouplist,
2075
(yyvsp[-3].runas)->runasgroups, entries);
2076
}
2077
parser_leak_remove(LEAK_RUNAS, (yyvsp[-3].runas));
2078
free((yyvsp[-3].runas));
2079
}
2080
cs->role = (yyvsp[-2].options).role;
2081
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).role);
2082
cs->type = (yyvsp[-2].options).type;
2083
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).type);
2084
cs->apparmor_profile = (yyvsp[-2].options).apparmor_profile;
2085
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).apparmor_profile);
2086
cs->privs = (yyvsp[-2].options).privs;
2087
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).privs);
2088
cs->limitprivs = (yyvsp[-2].options).limitprivs;
2089
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).limitprivs);
2090
cs->notbefore = (yyvsp[-2].options).notbefore;
2091
cs->notafter = (yyvsp[-2].options).notafter;
2092
cs->timeout = (yyvsp[-2].options).timeout;
2093
cs->runcwd = (yyvsp[-2].options).runcwd;
2094
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runcwd);
2095
cs->runchroot = (yyvsp[-2].options).runchroot;
2096
parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runchroot);
2097
cs->tags = (yyvsp[-1].tag);
2098
cs->cmnd = (yyvsp[0].member);
2099
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2100
HLTQ_INIT(cs, entries);
2101
/* sudo "ALL" implies the SETENV tag */
2102
if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
2103
cs->tags.setenv == UNSPEC)
2104
cs->tags.setenv = IMPLIED;
2105
(yyval.cmndspec) = cs;
2106
}
2107
#line 2107 "gram.c"
2108
break;
2109
2110
case 45: /* digestspec: SHA224_TOK ':' DIGEST */
2111
#line 513 "gram.y"
2112
{
2113
(yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string));
2114
if ((yyval.digest) == NULL) {
2115
sudoerserror(N_("unable to allocate memory"));
2116
YYERROR;
2117
}
2118
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2119
parser_leak_add(LEAK_DIGEST, (yyval.digest));
2120
}
2121
#line 2121 "gram.c"
2122
break;
2123
2124
case 46: /* digestspec: SHA256_TOK ':' DIGEST */
2125
#line 522 "gram.y"
2126
{
2127
(yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string));
2128
if ((yyval.digest) == NULL) {
2129
sudoerserror(N_("unable to allocate memory"));
2130
YYERROR;
2131
}
2132
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2133
parser_leak_add(LEAK_DIGEST, (yyval.digest));
2134
}
2135
#line 2135 "gram.c"
2136
break;
2137
2138
case 47: /* digestspec: SHA384_TOK ':' DIGEST */
2139
#line 531 "gram.y"
2140
{
2141
(yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string));
2142
if ((yyval.digest) == NULL) {
2143
sudoerserror(N_("unable to allocate memory"));
2144
YYERROR;
2145
}
2146
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2147
parser_leak_add(LEAK_DIGEST, (yyval.digest));
2148
}
2149
#line 2149 "gram.c"
2150
break;
2151
2152
case 48: /* digestspec: SHA512_TOK ':' DIGEST */
2153
#line 540 "gram.y"
2154
{
2155
(yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string));
2156
if ((yyval.digest) == NULL) {
2157
sudoerserror(N_("unable to allocate memory"));
2158
YYERROR;
2159
}
2160
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2161
parser_leak_add(LEAK_DIGEST, (yyval.digest));
2162
}
2163
#line 2163 "gram.c"
2164
break;
2165
2166
case 50: /* digestlist: digestlist ',' digestspec */
2167
#line 552 "gram.y"
2168
{
2169
parser_leak_remove(LEAK_DIGEST, (yyvsp[0].digest));
2170
HLTQ_CONCAT((yyvsp[-2].digest), (yyvsp[0].digest), entries);
2171
(yyval.digest) = (yyvsp[-2].digest);
2172
}
2173
#line 2173 "gram.c"
2174
break;
2175
2176
case 51: /* digcmnd: opcmnd */
2177
#line 559 "gram.y"
2178
{
2179
(yyval.member) = (yyvsp[0].member);
2180
}
2181
#line 2181 "gram.c"
2182
break;
2183
2184
case 52: /* digcmnd: digestlist opcmnd */
2185
#line 562 "gram.y"
2186
{
2187
struct sudo_command *c =
2188
(struct sudo_command *) (yyvsp[0].member)->name;
2189
2190
if ((yyvsp[0].member)->type != COMMAND && (yyvsp[0].member)->type != ALL) {
2191
sudoerserror(N_("a digest requires a path name"));
2192
YYERROR;
2193
}
2194
parser_leak_remove(LEAK_DIGEST, (yyvsp[-1].digest));
2195
HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries);
2196
(yyval.member) = (yyvsp[0].member);
2197
}
2198
#line 2198 "gram.c"
2199
break;
2200
2201
case 53: /* opcmnd: cmnd */
2202
#line 576 "gram.y"
2203
{
2204
(yyval.member) = (yyvsp[0].member);
2205
(yyval.member)->negated = false;
2206
}
2207
#line 2207 "gram.c"
2208
break;
2209
2210
case 54: /* opcmnd: '!' cmnd */
2211
#line 580 "gram.y"
2212
{
2213
(yyval.member) = (yyvsp[0].member);
2214
(yyval.member)->negated = true;
2215
}
2216
#line 2216 "gram.c"
2217
break;
2218
2219
case 55: /* chdirspec: CWD '=' WORD */
2220
#line 586 "gram.y"
2221
{
2222
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
2223
if (strcmp((yyvsp[0].string), "*") != 0) {
2224
sudoerserror(N_("values for \"CWD\" must"
2225
" start with a '/', '~', or '*'"));
2226
YYERROR;
2227
}
2228
}
2229
if (strlen((yyvsp[0].string)) >= PATH_MAX) {
2230
sudoerserror(N_("\"CWD\" path too long"));
2231
YYERROR;
2232
}
2233
(yyval.string) = (yyvsp[0].string);
2234
}
2235
#line 2235 "gram.c"
2236
break;
2237
2238
case 56: /* chrootspec: CHROOT '=' WORD */
2239
#line 602 "gram.y"
2240
{
2241
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
2242
if (strcmp((yyvsp[0].string), "*") != 0) {
2243
sudoerserror(N_("values for \"CHROOT\" must"
2244
" start with a '/', '~', or '*'"));
2245
YYERROR;
2246
}
2247
}
2248
if (strlen((yyvsp[0].string)) >= PATH_MAX) {
2249
sudoerserror(N_("\"CHROOT\" path too long"));
2250
YYERROR;
2251
}
2252
if (parser_conf.strict > 2) {
2253
sudoerserror(N_("\"CHROOT\" is deprecated"));
2254
YYERROR;
2255
} else if (parser_conf.verbose > 0) {
2256
parser_warnx(parsed_policy.ctx, sudoers, this_lineno, sudolinebuf.toke_start + 1, false, false, N_("\"CHROOT\" is deprecated"));
2257
}
2258
(yyval.string) = (yyvsp[0].string);
2259
}
2260
#line 2260 "gram.c"
2261
break;
2262
2263
case 57: /* timeoutspec: CMND_TIMEOUT '=' WORD */
2264
#line 624 "gram.y"
2265
{
2266
(yyval.string) = (yyvsp[0].string);
2267
}
2268
#line 2268 "gram.c"
2269
break;
2270
2271
case 58: /* notbeforespec: NOTBEFORE '=' WORD */
2272
#line 629 "gram.y"
2273
{
2274
(yyval.string) = (yyvsp[0].string);
2275
}
2276
#line 2276 "gram.c"
2277
break;
2278
2279
case 59: /* notafterspec: NOTAFTER '=' WORD */
2280
#line 633 "gram.y"
2281
{
2282
(yyval.string) = (yyvsp[0].string);
2283
}
2284
#line 2284 "gram.c"
2285
break;
2286
2287
case 60: /* rolespec: ROLE '=' WORD */
2288
#line 638 "gram.y"
2289
{
2290
(yyval.string) = (yyvsp[0].string);
2291
}
2292
#line 2292 "gram.c"
2293
break;
2294
2295
case 61: /* typespec: TYPE '=' WORD */
2296
#line 643 "gram.y"
2297
{
2298
(yyval.string) = (yyvsp[0].string);
2299
}
2300
#line 2300 "gram.c"
2301
break;
2302
2303
case 62: /* apparmor_profilespec: APPARMOR_PROFILE '=' WORD */
2304
#line 648 "gram.y"
2305
{
2306
(yyval.string) = (yyvsp[0].string);
2307
}
2308
#line 2308 "gram.c"
2309
break;
2310
2311
case 63: /* privsspec: PRIVS '=' WORD */
2312
#line 653 "gram.y"
2313
{
2314
(yyval.string) = (yyvsp[0].string);
2315
}
2316
#line 2316 "gram.c"
2317
break;
2318
2319
case 64: /* limitprivsspec: LIMITPRIVS '=' WORD */
2320
#line 657 "gram.y"
2321
{
2322
(yyval.string) = (yyvsp[0].string);
2323
}
2324
#line 2324 "gram.c"
2325
break;
2326
2327
case 65: /* runasspec: %empty */
2328
#line 662 "gram.y"
2329
{
2330
(yyval.runas) = NULL;
2331
}
2332
#line 2332 "gram.c"
2333
break;
2334
2335
case 66: /* runasspec: '(' runaslist ')' */
2336
#line 665 "gram.y"
2337
{
2338
(yyval.runas) = (yyvsp[-1].runas);
2339
}
2340
#line 2340 "gram.c"
2341
break;
2342
2343
case 67: /* runaslist: %empty */
2344
#line 670 "gram.y"
2345
{
2346
/* User may run command as themselves. */
2347
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
2348
if ((yyval.runas) != NULL) {
2349
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
2350
/* $$->runasgroups = NULL; */
2351
if ((yyval.runas)->runasusers == NULL) {
2352
free((yyval.runas));
2353
(yyval.runas) = NULL;
2354
}
2355
}
2356
if ((yyval.runas) == NULL) {
2357
sudoerserror(N_("unable to allocate memory"));
2358
YYERROR;
2359
}
2360
parser_leak_add(LEAK_RUNAS, (yyval.runas));
2361
}
2362
#line 2362 "gram.c"
2363
break;
2364
2365
case 68: /* runaslist: userlist */
2366
#line 687 "gram.y"
2367
{
2368
/* User may run command as a user in userlist. */
2369
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
2370
if ((yyval.runas) == NULL) {
2371
sudoerserror(N_("unable to allocate memory"));
2372
YYERROR;
2373
}
2374
parser_leak_add(LEAK_RUNAS, (yyval.runas));
2375
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2376
(yyval.runas)->runasusers = (yyvsp[0].member);
2377
/* $$->runasgroups = NULL; */
2378
}
2379
#line 2379 "gram.c"
2380
break;
2381
2382
case 69: /* runaslist: userlist ':' grouplist */
2383
#line 699 "gram.y"
2384
{
2385
/*
2386
* User may run command as a user in userlist
2387
* and optionally as a group in grouplist.
2388
*/
2389
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
2390
if ((yyval.runas) == NULL) {
2391
sudoerserror(N_("unable to allocate memory"));
2392
YYERROR;
2393
}
2394
parser_leak_add(LEAK_RUNAS, (yyval.runas));
2395
parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member));
2396
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2397
(yyval.runas)->runasusers = (yyvsp[-2].member);
2398
(yyval.runas)->runasgroups = (yyvsp[0].member);
2399
}
2400
#line 2400 "gram.c"
2401
break;
2402
2403
case 70: /* runaslist: ':' grouplist */
2404
#line 715 "gram.y"
2405
{
2406
/* User may run command as a group in grouplist. */
2407
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
2408
if ((yyval.runas) != NULL) {
2409
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
2410
if ((yyval.runas)->runasusers == NULL) {
2411
free((yyval.runas));
2412
(yyval.runas) = NULL;
2413
}
2414
}
2415
if ((yyval.runas) == NULL) {
2416
sudoerserror(N_("unable to allocate memory"));
2417
YYERROR;
2418
}
2419
parser_leak_add(LEAK_RUNAS, (yyval.runas));
2420
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2421
(yyval.runas)->runasgroups = (yyvsp[0].member);
2422
}
2423
#line 2423 "gram.c"
2424
break;
2425
2426
case 71: /* runaslist: ':' */
2427
#line 733 "gram.y"
2428
{
2429
/* User may run command as themselves. */
2430
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
2431
if ((yyval.runas) != NULL) {
2432
(yyval.runas)->runasusers = new_member(NULL, MYSELF);
2433
/* $$->runasgroups = NULL; */
2434
if ((yyval.runas)->runasusers == NULL) {
2435
free((yyval.runas));
2436
(yyval.runas) = NULL;
2437
}
2438
}
2439
if ((yyval.runas) == NULL) {
2440
sudoerserror(N_("unable to allocate memory"));
2441
YYERROR;
2442
}
2443
parser_leak_add(LEAK_RUNAS, (yyval.runas));
2444
}
2445
#line 2445 "gram.c"
2446
break;
2447
2448
case 72: /* reserved_word: ALL */
2449
#line 752 "gram.y"
2450
{ (yyval.cstring) = "ALL"; }
2451
#line 2451 "gram.c"
2452
break;
2453
2454
case 73: /* reserved_word: CHROOT */
2455
#line 753 "gram.y"
2456
{ (yyval.cstring) = "CHROOT"; }
2457
#line 2457 "gram.c"
2458
break;
2459
2460
case 74: /* reserved_word: CWD */
2461
#line 754 "gram.y"
2462
{ (yyval.cstring) = "CWD"; }
2463
#line 2463 "gram.c"
2464
break;
2465
2466
case 75: /* reserved_word: CMND_TIMEOUT */
2467
#line 755 "gram.y"
2468
{ (yyval.cstring) = "CMND_TIMEOUT"; }
2469
#line 2469 "gram.c"
2470
break;
2471
2472
case 76: /* reserved_word: NOTBEFORE */
2473
#line 756 "gram.y"
2474
{ (yyval.cstring) = "NOTBEFORE"; }
2475
#line 2475 "gram.c"
2476
break;
2477
2478
case 77: /* reserved_word: NOTAFTER */
2479
#line 757 "gram.y"
2480
{ (yyval.cstring) = "NOTAFTER"; }
2481
#line 2481 "gram.c"
2482
break;
2483
2484
case 78: /* reserved_word: ROLE */
2485
#line 758 "gram.y"
2486
{ (yyval.cstring) = "ROLE"; }
2487
#line 2487 "gram.c"
2488
break;
2489
2490
case 79: /* reserved_word: TYPE */
2491
#line 759 "gram.y"
2492
{ (yyval.cstring) = "TYPE"; }
2493
#line 2493 "gram.c"
2494
break;
2495
2496
case 80: /* reserved_word: PRIVS */
2497
#line 760 "gram.y"
2498
{ (yyval.cstring) = "PRIVS"; }
2499
#line 2499 "gram.c"
2500
break;
2501
2502
case 81: /* reserved_word: LIMITPRIVS */
2503
#line 761 "gram.y"
2504
{ (yyval.cstring) = "LIMITPRIVS"; }
2505
#line 2505 "gram.c"
2506
break;
2507
2508
case 82: /* reserved_word: APPARMOR_PROFILE */
2509
#line 762 "gram.y"
2510
{ (yyval.cstring) = "APPARMOR_PROFILE"; }
2511
#line 2511 "gram.c"
2512
break;
2513
2514
case 83: /* reserved_alias: reserved_word */
2515
#line 765 "gram.y"
2516
{
2517
sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].cstring));
2518
YYERROR;
2519
}
2520
#line 2520 "gram.c"
2521
break;
2522
2523
case 84: /* options: %empty */
2524
#line 771 "gram.y"
2525
{
2526
init_options(&(yyval.options));
2527
}
2528
#line 2528 "gram.c"
2529
break;
2530
2531
case 85: /* options: options chdirspec */
2532
#line 774 "gram.y"
2533
{
2534
parser_leak_remove(LEAK_PTR, (yyval.options).runcwd);
2535
free((yyval.options).runcwd);
2536
(yyval.options).runcwd = (yyvsp[0].string);
2537
}
2538
#line 2538 "gram.c"
2539
break;
2540
2541
case 86: /* options: options chrootspec */
2542
#line 779 "gram.y"
2543
{
2544
parser_leak_remove(LEAK_PTR, (yyval.options).runchroot);
2545
free((yyval.options).runchroot);
2546
(yyval.options).runchroot = (yyvsp[0].string);
2547
}
2548
#line 2548 "gram.c"
2549
break;
2550
2551
case 87: /* options: options notbeforespec */
2552
#line 784 "gram.y"
2553
{
2554
(yyval.options).notbefore = parse_gentime((yyvsp[0].string));
2555
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2556
free((yyvsp[0].string));
2557
if ((yyval.options).notbefore == -1) {
2558
sudoerserror(N_("invalid notbefore value"));
2559
YYERROR;
2560
}
2561
}
2562
#line 2562 "gram.c"
2563
break;
2564
2565
case 88: /* options: options notafterspec */
2566
#line 793 "gram.y"
2567
{
2568
(yyval.options).notafter = parse_gentime((yyvsp[0].string));
2569
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2570
free((yyvsp[0].string));
2571
if ((yyval.options).notafter == -1) {
2572
sudoerserror(N_("invalid notafter value"));
2573
YYERROR;
2574
}
2575
}
2576
#line 2576 "gram.c"
2577
break;
2578
2579
case 89: /* options: options timeoutspec */
2580
#line 802 "gram.y"
2581
{
2582
(yyval.options).timeout = parse_timeout((yyvsp[0].string));
2583
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2584
free((yyvsp[0].string));
2585
if ((yyval.options).timeout == -1) {
2586
if (errno == ERANGE)
2587
sudoerserror(N_("timeout value too large"));
2588
else
2589
sudoerserror(N_("invalid timeout value"));
2590
YYERROR;
2591
}
2592
}
2593
#line 2593 "gram.c"
2594
break;
2595
2596
case 90: /* options: options rolespec */
2597
#line 814 "gram.y"
2598
{
2599
parser_leak_remove(LEAK_PTR, (yyval.options).role);
2600
free((yyval.options).role);
2601
(yyval.options).role = (yyvsp[0].string);
2602
}
2603
#line 2603 "gram.c"
2604
break;
2605
2606
case 91: /* options: options typespec */
2607
#line 819 "gram.y"
2608
{
2609
parser_leak_remove(LEAK_PTR, (yyval.options).type);
2610
free((yyval.options).type);
2611
(yyval.options).type = (yyvsp[0].string);
2612
}
2613
#line 2613 "gram.c"
2614
break;
2615
2616
case 92: /* options: options apparmor_profilespec */
2617
#line 824 "gram.y"
2618
{
2619
parser_leak_remove(LEAK_PTR, (yyval.options).apparmor_profile);
2620
free((yyval.options).apparmor_profile);
2621
(yyval.options).apparmor_profile = (yyvsp[0].string);
2622
}
2623
#line 2623 "gram.c"
2624
break;
2625
2626
case 93: /* options: options privsspec */
2627
#line 829 "gram.y"
2628
{
2629
parser_leak_remove(LEAK_PTR, (yyval.options).privs);
2630
free((yyval.options).privs);
2631
(yyval.options).privs = (yyvsp[0].string);
2632
}
2633
#line 2633 "gram.c"
2634
break;
2635
2636
case 94: /* options: options limitprivsspec */
2637
#line 834 "gram.y"
2638
{
2639
parser_leak_remove(LEAK_PTR, (yyval.options).limitprivs);
2640
free((yyval.options).limitprivs);
2641
(yyval.options).limitprivs = (yyvsp[0].string);
2642
}
2643
#line 2643 "gram.c"
2644
break;
2645
2646
case 95: /* cmndtag: %empty */
2647
#line 841 "gram.y"
2648
{
2649
TAGS_INIT(&(yyval.tag));
2650
}
2651
#line 2651 "gram.c"
2652
break;
2653
2654
case 96: /* cmndtag: cmndtag NOPASSWD */
2655
#line 844 "gram.y"
2656
{
2657
(yyval.tag).nopasswd = true;
2658
}
2659
#line 2659 "gram.c"
2660
break;
2661
2662
case 97: /* cmndtag: cmndtag PASSWD */
2663
#line 847 "gram.y"
2664
{
2665
(yyval.tag).nopasswd = false;
2666
}
2667
#line 2667 "gram.c"
2668
break;
2669
2670
case 98: /* cmndtag: cmndtag NOEXEC */
2671
#line 850 "gram.y"
2672
{
2673
(yyval.tag).noexec = true;
2674
}
2675
#line 2675 "gram.c"
2676
break;
2677
2678
case 99: /* cmndtag: cmndtag EXEC */
2679
#line 853 "gram.y"
2680
{
2681
(yyval.tag).noexec = false;
2682
}
2683
#line 2683 "gram.c"
2684
break;
2685
2686
case 100: /* cmndtag: cmndtag INTERCEPT */
2687
#line 856 "gram.y"
2688
{
2689
(yyval.tag).intercept = true;
2690
}
2691
#line 2691 "gram.c"
2692
break;
2693
2694
case 101: /* cmndtag: cmndtag NOINTERCEPT */
2695
#line 859 "gram.y"
2696
{
2697
(yyval.tag).intercept = false;
2698
}
2699
#line 2699 "gram.c"
2700
break;
2701
2702
case 102: /* cmndtag: cmndtag SETENV */
2703
#line 862 "gram.y"
2704
{
2705
(yyval.tag).setenv = true;
2706
}
2707
#line 2707 "gram.c"
2708
break;
2709
2710
case 103: /* cmndtag: cmndtag NOSETENV */
2711
#line 865 "gram.y"
2712
{
2713
(yyval.tag).setenv = false;
2714
}
2715
#line 2715 "gram.c"
2716
break;
2717
2718
case 104: /* cmndtag: cmndtag LOG_INPUT */
2719
#line 868 "gram.y"
2720
{
2721
(yyval.tag).log_input = true;
2722
}
2723
#line 2723 "gram.c"
2724
break;
2725
2726
case 105: /* cmndtag: cmndtag NOLOG_INPUT */
2727
#line 871 "gram.y"
2728
{
2729
(yyval.tag).log_input = false;
2730
}
2731
#line 2731 "gram.c"
2732
break;
2733
2734
case 106: /* cmndtag: cmndtag LOG_OUTPUT */
2735
#line 874 "gram.y"
2736
{
2737
(yyval.tag).log_output = true;
2738
}
2739
#line 2739 "gram.c"
2740
break;
2741
2742
case 107: /* cmndtag: cmndtag NOLOG_OUTPUT */
2743
#line 877 "gram.y"
2744
{
2745
(yyval.tag).log_output = false;
2746
}
2747
#line 2747 "gram.c"
2748
break;
2749
2750
case 108: /* cmndtag: cmndtag FOLLOWLNK */
2751
#line 880 "gram.y"
2752
{
2753
(yyval.tag).follow = true;
2754
}
2755
#line 2755 "gram.c"
2756
break;
2757
2758
case 109: /* cmndtag: cmndtag NOFOLLOWLNK */
2759
#line 883 "gram.y"
2760
{
2761
(yyval.tag).follow = false;
2762
}
2763
#line 2763 "gram.c"
2764
break;
2765
2766
case 110: /* cmndtag: cmndtag MAIL */
2767
#line 886 "gram.y"
2768
{
2769
(yyval.tag).send_mail = true;
2770
}
2771
#line 2771 "gram.c"
2772
break;
2773
2774
case 111: /* cmndtag: cmndtag NOMAIL */
2775
#line 889 "gram.y"
2776
{
2777
(yyval.tag).send_mail = false;
2778
}
2779
#line 2779 "gram.c"
2780
break;
2781
2782
case 112: /* cmnd: ALL */
2783
#line 894 "gram.y"
2784
{
2785
struct sudo_command *c;
2786
2787
if ((c = new_command(NULL, NULL)) == NULL) {
2788
sudoerserror(N_("unable to allocate memory"));
2789
YYERROR;
2790
}
2791
(yyval.member) = new_member((char *)c, ALL);
2792
if ((yyval.member) == NULL) {
2793
sudoerserror(N_("unable to allocate memory"));
2794
YYERROR;
2795
}
2796
parser_leak_add(LEAK_MEMBER, (yyval.member));
2797
}
2798
#line 2798 "gram.c"
2799
break;
2800
2801
case 113: /* cmnd: ALIAS */
2802
#line 908 "gram.y"
2803
{
2804
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
2805
if ((yyval.member) == NULL) {
2806
sudoerserror(N_("unable to allocate memory"));
2807
YYERROR;
2808
}
2809
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2810
parser_leak_add(LEAK_MEMBER, (yyval.member));
2811
}
2812
#line 2812 "gram.c"
2813
break;
2814
2815
case 114: /* cmnd: COMMAND */
2816
#line 917 "gram.y"
2817
{
2818
struct sudo_command *c;
2819
2820
if (strlen((yyvsp[0].command).cmnd) >= PATH_MAX) {
2821
sudoerserror(N_("command too long"));
2822
YYERROR;
2823
}
2824
if ((c = new_command((yyvsp[0].command).cmnd, (yyvsp[0].command).args)) == NULL) {
2825
sudoerserror(N_("unable to allocate memory"));
2826
YYERROR;
2827
}
2828
(yyval.member) = new_member((char *)c, COMMAND);
2829
if ((yyval.member) == NULL) {
2830
free(c);
2831
sudoerserror(N_("unable to allocate memory"));
2832
YYERROR;
2833
}
2834
parser_leak_remove(LEAK_PTR, (yyvsp[0].command).cmnd);
2835
parser_leak_remove(LEAK_PTR, (yyvsp[0].command).args);
2836
parser_leak_add(LEAK_MEMBER, (yyval.member));
2837
}
2838
#line 2838 "gram.c"
2839
break;
2840
2841
case 115: /* cmnd: WORD */
2842
#line 938 "gram.y"
2843
{
2844
if (strcmp((yyvsp[0].string), "list") == 0) {
2845
struct sudo_command *c;
2846
2847
if ((c = new_command((yyvsp[0].string), NULL)) == NULL) {
2848
sudoerserror(N_("unable to allocate memory"));
2849
YYERROR;
2850
}
2851
(yyval.member) = new_member((char *)c, COMMAND);
2852
if ((yyval.member) == NULL) {
2853
free(c);
2854
sudoerserror(N_("unable to allocate memory"));
2855
YYERROR;
2856
}
2857
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
2858
parser_leak_add(LEAK_MEMBER, (yyval.member));
2859
} else {
2860
sudoerserror(N_("expected a fully-qualified path name"));
2861
YYERROR;
2862
}
2863
}
2864
#line 2864 "gram.c"
2865
break;
2866
2867
case 118: /* $@1: %empty */
2868
#line 965 "gram.y"
2869
{
2870
alias_line = this_lineno;
2871
alias_column = (int)sudolinebuf.toke_start + 1;
2872
}
2873
#line 2873 "gram.c"
2874
break;
2875
2876
case 119: /* hostalias: ALIAS $@1 '=' hostlist */
2877
#line 968 "gram.y"
2878
{
2879
if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS,
2880
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
2881
alias_error((yyvsp[-3].string), HOSTALIAS, errno);
2882
YYERROR;
2883
}
2884
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
2885
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2886
}
2887
#line 2887 "gram.c"
2888
break;
2889
2890
case 122: /* hostlist: hostlist ',' ophost */
2891
#line 981 "gram.y"
2892
{
2893
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2894
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
2895
(yyval.member) = (yyvsp[-2].member);
2896
}
2897
#line 2897 "gram.c"
2898
break;
2899
2900
case 125: /* $@2: %empty */
2901
#line 992 "gram.y"
2902
{
2903
alias_line = this_lineno;
2904
alias_column = (int)sudolinebuf.toke_start + 1;
2905
}
2906
#line 2906 "gram.c"
2907
break;
2908
2909
case 126: /* cmndalias: ALIAS $@2 '=' cmndlist */
2910
#line 995 "gram.y"
2911
{
2912
if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS,
2913
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
2914
alias_error((yyvsp[-3].string), CMNDALIAS, errno);
2915
YYERROR;
2916
}
2917
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
2918
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2919
}
2920
#line 2920 "gram.c"
2921
break;
2922
2923
case 129: /* cmndlist: cmndlist ',' digcmnd */
2924
#line 1008 "gram.y"
2925
{
2926
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2927
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
2928
(yyval.member) = (yyvsp[-2].member);
2929
}
2930
#line 2930 "gram.c"
2931
break;
2932
2933
case 132: /* $@3: %empty */
2934
#line 1019 "gram.y"
2935
{
2936
alias_line = this_lineno;
2937
alias_column = (int)sudolinebuf.toke_start + 1;
2938
}
2939
#line 2939 "gram.c"
2940
break;
2941
2942
case 133: /* runasalias: ALIAS $@3 '=' userlist */
2943
#line 1022 "gram.y"
2944
{
2945
if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS,
2946
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
2947
alias_error((yyvsp[-3].string), RUNASALIAS, errno);
2948
YYERROR;
2949
}
2950
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
2951
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2952
}
2953
#line 2953 "gram.c"
2954
break;
2955
2956
case 137: /* $@4: %empty */
2957
#line 1038 "gram.y"
2958
{
2959
alias_line = this_lineno;
2960
alias_column = (int)sudolinebuf.toke_start + 1;
2961
}
2962
#line 2962 "gram.c"
2963
break;
2964
2965
case 138: /* useralias: ALIAS $@4 '=' userlist */
2966
#line 1041 "gram.y"
2967
{
2968
if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS,
2969
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
2970
alias_error((yyvsp[-3].string), USERALIAS, errno);
2971
YYERROR;
2972
}
2973
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
2974
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2975
}
2976
#line 2976 "gram.c"
2977
break;
2978
2979
case 141: /* userlist: userlist ',' opuser */
2980
#line 1054 "gram.y"
2981
{
2982
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
2983
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
2984
(yyval.member) = (yyvsp[-2].member);
2985
}
2986
#line 2986 "gram.c"
2987
break;
2988
2989
case 142: /* opuser: user */
2990
#line 1061 "gram.y"
2991
{
2992
(yyval.member) = (yyvsp[0].member);
2993
(yyval.member)->negated = false;
2994
}
2995
#line 2995 "gram.c"
2996
break;
2997
2998
case 143: /* opuser: '!' user */
2999
#line 1065 "gram.y"
3000
{
3001
(yyval.member) = (yyvsp[0].member);
3002
(yyval.member)->negated = true;
3003
}
3004
#line 3004 "gram.c"
3005
break;
3006
3007
case 144: /* user: ALIAS */
3008
#line 1071 "gram.y"
3009
{
3010
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
3011
if ((yyval.member) == NULL) {
3012
sudoerserror(N_("unable to allocate memory"));
3013
YYERROR;
3014
}
3015
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3016
parser_leak_add(LEAK_MEMBER, (yyval.member));
3017
}
3018
#line 3018 "gram.c"
3019
break;
3020
3021
case 145: /* user: ALL */
3022
#line 1080 "gram.y"
3023
{
3024
(yyval.member) = new_member(NULL, ALL);
3025
if ((yyval.member) == NULL) {
3026
sudoerserror(N_("unable to allocate memory"));
3027
YYERROR;
3028
}
3029
parser_leak_add(LEAK_MEMBER, (yyval.member));
3030
}
3031
#line 3031 "gram.c"
3032
break;
3033
3034
case 146: /* user: NETGROUP */
3035
#line 1088 "gram.y"
3036
{
3037
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
3038
if ((yyval.member) == NULL) {
3039
sudoerserror(N_("unable to allocate memory"));
3040
YYERROR;
3041
}
3042
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3043
parser_leak_add(LEAK_MEMBER, (yyval.member));
3044
}
3045
#line 3045 "gram.c"
3046
break;
3047
3048
case 147: /* user: USERGROUP */
3049
#line 1097 "gram.y"
3050
{
3051
(yyval.member) = new_member((yyvsp[0].string), USERGROUP);
3052
if ((yyval.member) == NULL) {
3053
sudoerserror(N_("unable to allocate memory"));
3054
YYERROR;
3055
}
3056
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3057
parser_leak_add(LEAK_MEMBER, (yyval.member));
3058
}
3059
#line 3059 "gram.c"
3060
break;
3061
3062
case 148: /* user: WORD */
3063
#line 1106 "gram.y"
3064
{
3065
(yyval.member) = new_member((yyvsp[0].string), WORD);
3066
if ((yyval.member) == NULL) {
3067
sudoerserror(N_("unable to allocate memory"));
3068
YYERROR;
3069
}
3070
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3071
parser_leak_add(LEAK_MEMBER, (yyval.member));
3072
}
3073
#line 3073 "gram.c"
3074
break;
3075
3076
case 150: /* grouplist: grouplist ',' opgroup */
3077
#line 1118 "gram.y"
3078
{
3079
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
3080
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
3081
(yyval.member) = (yyvsp[-2].member);
3082
}
3083
#line 3083 "gram.c"
3084
break;
3085
3086
case 151: /* opgroup: group */
3087
#line 1125 "gram.y"
3088
{
3089
(yyval.member) = (yyvsp[0].member);
3090
(yyval.member)->negated = false;
3091
}
3092
#line 3092 "gram.c"
3093
break;
3094
3095
case 152: /* opgroup: '!' group */
3096
#line 1129 "gram.y"
3097
{
3098
(yyval.member) = (yyvsp[0].member);
3099
(yyval.member)->negated = true;
3100
}
3101
#line 3101 "gram.c"
3102
break;
3103
3104
case 153: /* group: ALIAS */
3105
#line 1135 "gram.y"
3106
{
3107
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
3108
if ((yyval.member) == NULL) {
3109
sudoerserror(N_("unable to allocate memory"));
3110
YYERROR;
3111
}
3112
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3113
parser_leak_add(LEAK_MEMBER, (yyval.member));
3114
}
3115
#line 3115 "gram.c"
3116
break;
3117
3118
case 154: /* group: ALL */
3119
#line 1144 "gram.y"
3120
{
3121
(yyval.member) = new_member(NULL, ALL);
3122
if ((yyval.member) == NULL) {
3123
sudoerserror(N_("unable to allocate memory"));
3124
YYERROR;
3125
}
3126
parser_leak_add(LEAK_MEMBER, (yyval.member));
3127
}
3128
#line 3128 "gram.c"
3129
break;
3130
3131
case 155: /* group: WORD */
3132
#line 1152 "gram.y"
3133
{
3134
(yyval.member) = new_member((yyvsp[0].string), WORD);
3135
if ((yyval.member) == NULL) {
3136
sudoerserror(N_("unable to allocate memory"));
3137
YYERROR;
3138
}
3139
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
3140
parser_leak_add(LEAK_MEMBER, (yyval.member));
3141
}
3142
#line 3142 "gram.c"
3143
break;
3144
3145
3146
#line 3146 "gram.c"
3147
3148
default: break;
3149
}
3150
/* User semantic actions sometimes alter yychar, and that requires
3151
that yytoken be updated with the new translation. We take the
3152
approach of translating immediately before every use of yytoken.
3153
One alternative is translating here after every semantic action,
3154
but that translation would be missed if the semantic action invokes
3155
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
3156
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
3157
incorrect destructor might then be invoked immediately. In the
3158
case of YYERROR or YYBACKUP, subsequent parser actions might lead
3159
to an incorrect destructor call or verbose syntax error message
3160
before the lookahead is translated. */
3161
YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
3162
3163
YYPOPSTACK (yylen);
3164
yylen = 0;
3165
3166
*++yyvsp = yyval;
3167
3168
/* Now 'shift' the result of the reduction. Determine what state
3169
that goes to, based on the state we popped back to and the rule
3170
number reduced by. */
3171
{
3172
const int yylhs = yyr1[yyn] - YYNTOKENS;
3173
const int yyi = yypgoto[yylhs] + *yyssp;
3174
yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
3175
? yytable[yyi]
3176
: yydefgoto[yylhs]);
3177
}
3178
3179
goto yynewstate;
3180
3181
3182
/*--------------------------------------.
3183
| yyerrlab -- here on detecting error. |
3184
`--------------------------------------*/
3185
yyerrlab:
3186
/* Make sure we have latest lookahead translation. See comments at
3187
user semantic actions for why this is necessary. */
3188
yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
3189
/* If not already recovering from an error, report this error. */
3190
if (!yyerrstatus)
3191
{
3192
++yynerrs;
3193
yyerror (YY_("syntax error"));
3194
}
3195
3196
if (yyerrstatus == 3)
3197
{
3198
/* If just tried and failed to reuse lookahead token after an
3199
error, discard it. */
3200
3201
if (yychar <= YYEOF)
3202
{
3203
/* Return failure if at end of input. */
3204
if (yychar == YYEOF)
3205
YYABORT;
3206
}
3207
else
3208
{
3209
yydestruct ("Error: discarding",
3210
yytoken, &yylval);
3211
yychar = YYEMPTY;
3212
}
3213
}
3214
3215
/* Else will try to reuse lookahead token after shifting the error
3216
token. */
3217
goto yyerrlab1;
3218
3219
3220
/*---------------------------------------------------.
3221
| yyerrorlab -- error raised explicitly by YYERROR. |
3222
`---------------------------------------------------*/
3223
yyerrorlab:
3224
/* Pacify compilers when the user code never invokes YYERROR and the
3225
label yyerrorlab therefore never appears in user code. */
3226
if (0)
3227
YYERROR;
3228
++yynerrs;
3229
3230
/* Do not reclaim the symbols of the rule whose action triggered
3231
this YYERROR. */
3232
YYPOPSTACK (yylen);
3233
yylen = 0;
3234
YY_STACK_PRINT (yyss, yyssp);
3235
yystate = *yyssp;
3236
goto yyerrlab1;
3237
3238
3239
/*-------------------------------------------------------------.
3240
| yyerrlab1 -- common code for both syntax error and YYERROR. |
3241
`-------------------------------------------------------------*/
3242
yyerrlab1:
3243
yyerrstatus = 3; /* Each real token shifted decrements this. */
3244
3245
/* Pop stack until we find a state that shifts the error token. */
3246
for (;;)
3247
{
3248
yyn = yypact[yystate];
3249
if (!yypact_value_is_default (yyn))
3250
{
3251
yyn += YYSYMBOL_YYerror;
3252
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
3253
{
3254
yyn = yytable[yyn];
3255
if (0 < yyn)
3256
break;
3257
}
3258
}
3259
3260
/* Pop the current state because it cannot handle the error token. */
3261
if (yyssp == yyss)
3262
YYABORT;
3263
3264
3265
yydestruct ("Error: popping",
3266
YY_ACCESSING_SYMBOL (yystate), yyvsp);
3267
YYPOPSTACK (1);
3268
yystate = *yyssp;
3269
YY_STACK_PRINT (yyss, yyssp);
3270
}
3271
3272
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
3273
*++yyvsp = yylval;
3274
YY_IGNORE_MAYBE_UNINITIALIZED_END
3275
3276
3277
/* Shift the error token. */
3278
YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
3279
3280
yystate = yyn;
3281
goto yynewstate;
3282
3283
3284
/*-------------------------------------.
3285
| yyacceptlab -- YYACCEPT comes here. |
3286
`-------------------------------------*/
3287
yyacceptlab:
3288
yyresult = 0;
3289
goto yyreturnlab;
3290
3291
3292
/*-----------------------------------.
3293
| yyabortlab -- YYABORT comes here. |
3294
`-----------------------------------*/
3295
yyabortlab:
3296
yyresult = 1;
3297
goto yyreturnlab;
3298
3299
3300
/*-----------------------------------------------------------.
3301
| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
3302
`-----------------------------------------------------------*/
3303
yyexhaustedlab:
3304
yyerror (YY_("memory exhausted"));
3305
yyresult = 2;
3306
goto yyreturnlab;
3307
3308
3309
/*----------------------------------------------------------.
3310
| yyreturnlab -- parsing is finished, clean up and return. |
3311
`----------------------------------------------------------*/
3312
yyreturnlab:
3313
if (yychar != YYEMPTY)
3314
{
3315
/* Make sure we have latest lookahead translation. See comments at
3316
user semantic actions for why this is necessary. */
3317
yytoken = YYTRANSLATE (yychar);
3318
yydestruct ("Cleanup: discarding lookahead",
3319
yytoken, &yylval);
3320
}
3321
/* Do not reclaim the symbols of the rule whose action triggered
3322
this YYABORT or YYACCEPT. */
3323
YYPOPSTACK (yylen);
3324
YY_STACK_PRINT (yyss, yyssp);
3325
while (yyssp != yyss)
3326
{
3327
yydestruct ("Cleanup: popping",
3328
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
3329
YYPOPSTACK (1);
3330
}
3331
#ifndef yyoverflow
3332
if (yyss != yyssa)
3333
YYSTACK_FREE (yyss);
3334
#endif
3335
3336
return yyresult;
3337
}
3338
3339
#line 1162 "gram.y"
3340
3341
/* Like yyerror() but takes a printf-style format string. */
3342
void
3343
sudoerserrorf(const char * restrict fmt, ...)
3344
{
3345
const int column = (int)(sudolinebuf.toke_start + 1);
3346
va_list ap;
3347
debug_decl(sudoerserrorf, SUDOERS_DEBUG_PARSER);
3348
3349
if (sudoers_error_hook != NULL) {
3350
va_start(ap, fmt);
3351
sudoers_error_hook(parsed_policy.ctx, sudoers, this_lineno, column,
3352
fmt, ap);
3353
va_end(ap);
3354
}
3355
if (parser_conf.verbose > 0 && fmt != NULL) {
3356
LEXTRACE("<*> ");
3357
#ifndef TRACELEXER
3358
if (trace_print == NULL || trace_print == sudoers_trace_print) {
3359
char *tofree = NULL;
3360
const char *s;
3361
int oldlocale;
3362
3363
/* Warnings are displayed in the user's locale. */
3364
sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
3365
3366
va_start(ap, fmt);
3367
if (strcmp(fmt, "%s") == 0) {
3368
/* Optimize common case, a single string. */
3369
s = _(va_arg(ap, char *));
3370
} else {
3371
if (vasprintf(&tofree, _(fmt), ap) != -1) {
3372
s = tofree;
3373
} else {
3374
s = _("syntax error");
3375
tofree = NULL;
3376
}
3377
}
3378
sudo_printf(SUDO_CONV_ERROR_MSG, _("%s:%d:%zu: %s\n"), sudoers,
3379
this_lineno, sudolinebuf.toke_start + 1, s);
3380
free(tofree);
3381
va_end(ap);
3382
sudoers_setlocale(oldlocale, NULL);
3383
3384
/* Display the offending line and token if possible. */
3385
if (sudolinebuf.len != 0) {
3386
char tildes[128];
3387
size_t tlen = 0;
3388
3389
sudo_printf(SUDO_CONV_ERROR_MSG, "%s%s", sudolinebuf.buf,
3390
sudolinebuf.buf[sudolinebuf.len - 1] == '\n' ? "" : "\n");
3391
if (sudolinebuf.toke_end > sudolinebuf.toke_start) {
3392
tlen = sudolinebuf.toke_end - sudolinebuf.toke_start - 1;
3393
if (tlen >= sizeof(tildes))
3394
tlen = sizeof(tildes) - 1;
3395
memset(tildes, '~', tlen);
3396
}
3397
tildes[tlen] = '\0';
3398
sudo_printf(SUDO_CONV_ERROR_MSG, "%*s^%s\n",
3399
(int)sudolinebuf.toke_start, "", tildes);
3400
}
3401
}
3402
#endif
3403
}
3404
parse_error = true;
3405
debug_return;
3406
}
3407
3408
void
3409
sudoerserror(const char *s)
3410
{
3411
if (sudoerschar == ERROR) {
3412
/* Use error string from lexer. */
3413
s = sudoers_errstr;
3414
sudoers_errstr = NULL;
3415
}
3416
3417
#pragma pvs(push)
3418
#pragma pvs(disable: 575, 618)
3419
3420
if (s == NULL)
3421
sudoerserrorf(NULL);
3422
else
3423
sudoerserrorf("%s", s);
3424
3425
#pragma pvs(pop)
3426
}
3427
3428
static void
3429
alias_error(const char *name, short type, int errnum)
3430
{
3431
if (errnum == EEXIST) {
3432
struct alias *a = alias_get(&parsed_policy, name, type);
3433
if (a != NULL) {
3434
sudoerserrorf(
3435
U_("duplicate %s \"%s\", previously defined at %s:%d:%d"),
3436
alias_type_to_string(type), name, a->file, a->line, a->column);
3437
alias_put(a);
3438
} else {
3439
if (errno == ELOOP) {
3440
sudoerserrorf(U_("cycle in %s \"%s\""),
3441
alias_type_to_string(type), name);
3442
} else {
3443
sudoerserrorf(U_("duplicate %s \"%s\""),
3444
alias_type_to_string(type), name);
3445
}
3446
}
3447
} else {
3448
sudoerserror(N_("unable to allocate memory"));
3449
}
3450
}
3451
3452
static struct defaults *
3453
new_default(char *var, char *val, short op)
3454
{
3455
struct defaults *d;
3456
debug_decl(new_default, SUDOERS_DEBUG_PARSER);
3457
3458
if ((d = calloc(1, sizeof(struct defaults))) == NULL) {
3459
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3460
"unable to allocate memory");
3461
debug_return_ptr(NULL);
3462
}
3463
3464
d->var = var;
3465
d->val = val;
3466
/* d->type = 0; */
3467
d->op = op;
3468
/* d->binding = NULL; */
3469
d->line = this_lineno;
3470
d->column = (int)(sudolinebuf.toke_start + 1);
3471
d->file = sudo_rcstr_addref(sudoers);
3472
HLTQ_INIT(d, entries);
3473
3474
debug_return_ptr(d);
3475
}
3476
3477
static struct member *
3478
new_member(char *name, short type)
3479
{
3480
struct member *m;
3481
debug_decl(new_member, SUDOERS_DEBUG_PARSER);
3482
3483
if ((m = calloc(1, sizeof(struct member))) == NULL) {
3484
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3485
"unable to allocate memory");
3486
debug_return_ptr(NULL);
3487
}
3488
3489
m->name = name;
3490
m->type = type;
3491
HLTQ_INIT(m, entries);
3492
3493
debug_return_ptr(m);
3494
}
3495
3496
static struct sudo_command *
3497
new_command(char *cmnd, char *args)
3498
{
3499
struct sudo_command *c;
3500
debug_decl(new_command, SUDOERS_DEBUG_PARSER);
3501
3502
if ((c = calloc(1, sizeof(*c))) == NULL) {
3503
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3504
"unable to allocate memory");
3505
debug_return_ptr(NULL);
3506
}
3507
/* garbage collected as part of struct member */
3508
3509
c->cmnd = cmnd;
3510
c->args = args;
3511
TAILQ_INIT(&c->digests);
3512
3513
debug_return_ptr(c);
3514
}
3515
3516
static struct command_digest *
3517
new_digest(unsigned int digest_type, char *digest_str)
3518
{
3519
struct command_digest *digest;
3520
debug_decl(new_digest, SUDOERS_DEBUG_PARSER);
3521
3522
if ((digest = malloc(sizeof(*digest))) == NULL) {
3523
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3524
"unable to allocate memory");
3525
debug_return_ptr(NULL);
3526
}
3527
3528
HLTQ_INIT(digest, entries);
3529
digest->digest_type = digest_type;
3530
digest->digest_str = digest_str;
3531
if (digest->digest_str == NULL) {
3532
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3533
"unable to allocate memory");
3534
free(digest);
3535
digest = NULL;
3536
}
3537
3538
debug_return_ptr(digest);
3539
}
3540
3541
static void
3542
free_defaults_binding(struct defaults_binding *binding)
3543
{
3544
debug_decl(free_defaults_binding, SUDOERS_DEBUG_PARSER);
3545
3546
/* Bindings may be shared among multiple Defaults entries. */
3547
if (binding != NULL) {
3548
if (--binding->refcnt == 0) {
3549
free_members(&binding->members);
3550
free(binding);
3551
}
3552
}
3553
3554
debug_return;
3555
}
3556
3557
/*
3558
* Add a list of defaults structures to the defaults list.
3559
* The bmem argument, if non-NULL, specifies a list of hosts, users,
3560
* or runas users the entries apply to (determined by the type).
3561
*/
3562
static bool
3563
add_defaults(short type, struct member *bmem, struct defaults *defs)
3564
{
3565
struct defaults *d, *next;
3566
struct defaults_binding *binding;
3567
bool ret = true;
3568
debug_decl(add_defaults, SUDOERS_DEBUG_PARSER);
3569
3570
if (defs == NULL)
3571
debug_return_bool(false);
3572
3573
/*
3574
* We use a single binding for each entry in defs.
3575
*/
3576
if ((binding = malloc(sizeof(*binding))) == NULL) {
3577
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3578
"unable to allocate memory");
3579
sudoerserror(N_("unable to allocate memory"));
3580
debug_return_bool(false);
3581
}
3582
if (bmem != NULL) {
3583
parser_leak_remove(LEAK_MEMBER, bmem);
3584
HLTQ_TO_TAILQ(&binding->members, bmem, entries);
3585
} else {
3586
TAILQ_INIT(&binding->members);
3587
}
3588
binding->refcnt = 0;
3589
3590
/*
3591
* Set type and binding (who it applies to) for new entries.
3592
* Then add to the global defaults list.
3593
*/
3594
parser_leak_remove(LEAK_DEFAULTS, defs);
3595
HLTQ_FOREACH_SAFE(d, defs, entries, next) {
3596
d->type = type;
3597
d->binding = binding;
3598
binding->refcnt++;
3599
TAILQ_INSERT_TAIL(&parsed_policy.defaults, d, entries);
3600
}
3601
3602
debug_return_bool(ret);
3603
}
3604
3605
/*
3606
* Allocate a new struct userspec, populate it, and insert it at the
3607
* end of the userspecs list.
3608
*/
3609
static bool
3610
add_userspec(struct member *members, struct privilege *privs)
3611
{
3612
struct userspec *u;
3613
debug_decl(add_userspec, SUDOERS_DEBUG_PARSER);
3614
3615
if ((u = calloc(1, sizeof(*u))) == NULL) {
3616
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
3617
"unable to allocate memory");
3618
debug_return_bool(false);
3619
}
3620
/* We already parsed the newline so sudolineno is off by one. */
3621
u->line = sudolineno - 1;
3622
u->column = (int)(sudolinebuf.toke_start + 1);
3623
u->file = sudo_rcstr_addref(sudoers);
3624
parser_leak_remove(LEAK_MEMBER, members);
3625
HLTQ_TO_TAILQ(&u->users, members, entries);
3626
parser_leak_remove(LEAK_PRIVILEGE, privs);
3627
HLTQ_TO_TAILQ(&u->privileges, privs, entries);
3628
STAILQ_INIT(&u->comments);
3629
TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries);
3630
3631
debug_return_bool(true);
3632
}
3633
3634
/*
3635
* Free a member struct and its contents.
3636
*/
3637
void
3638
free_member(struct member *m)
3639
{
3640
debug_decl(free_member, SUDOERS_DEBUG_PARSER);
3641
3642
if (m->type == COMMAND || (m->type == ALL && m->name != NULL)) {
3643
struct command_digest *digest;
3644
struct sudo_command *c = (struct sudo_command *)m->name;
3645
free(c->cmnd);
3646
free(c->args);
3647
while ((digest = TAILQ_FIRST(&c->digests)) != NULL) {
3648
TAILQ_REMOVE(&c->digests, digest, entries);
3649
free(digest->digest_str);
3650
free(digest);
3651
}
3652
}
3653
free(m->name);
3654
free(m);
3655
3656
debug_return;
3657
}
3658
3659
/*
3660
* Free a tailq of members but not the struct member_list container itself.
3661
*/
3662
void
3663
free_members(struct member_list *members)
3664
{
3665
struct member *m;
3666
debug_decl(free_members, SUDOERS_DEBUG_PARSER);
3667
3668
while ((m = TAILQ_FIRST(members)) != NULL) {
3669
TAILQ_REMOVE(members, m, entries);
3670
free_member(m);
3671
}
3672
3673
debug_return;
3674
}
3675
3676
void
3677
free_defaults(struct defaults_list *defs)
3678
{
3679
struct defaults *def;
3680
debug_decl(free_defaults, SUDOERS_DEBUG_PARSER);
3681
3682
while ((def = TAILQ_FIRST(defs)) != NULL) {
3683
TAILQ_REMOVE(defs, def, entries);
3684
free_default(def);
3685
}
3686
3687
debug_return;
3688
}
3689
3690
void
3691
free_default(struct defaults *def)
3692
{
3693
debug_decl(free_default, SUDOERS_DEBUG_PARSER);
3694
3695
free_defaults_binding(def->binding);
3696
sudo_rcstr_delref(def->file);
3697
free(def->var);
3698
free(def->val);
3699
free(def);
3700
3701
debug_return;
3702
}
3703
3704
void
3705
free_cmndspec(struct cmndspec *cs, struct cmndspec_list *csl)
3706
{
3707
struct cmndspec *prev, *next;
3708
debug_decl(free_cmndspec, SUDOERS_DEBUG_PARSER);
3709
3710
prev = TAILQ_PREV(cs, cmndspec_list, entries);
3711
next = TAILQ_NEXT(cs, entries);
3712
TAILQ_REMOVE(csl, cs, entries);
3713
3714
/* Don't free runcwd/runchroot that are in use by other entries. */
3715
if ((prev == NULL || cs->runcwd != prev->runcwd) &&
3716
(next == NULL || cs->runcwd != next->runcwd)) {
3717
free(cs->runcwd);
3718
}
3719
if ((prev == NULL || cs->runchroot != prev->runchroot) &&
3720
(next == NULL || cs->runchroot != next->runchroot)) {
3721
free(cs->runchroot);
3722
}
3723
/* Don't free root/type that are in use by other entries. */
3724
if ((prev == NULL || cs->role != prev->role) &&
3725
(next == NULL || cs->role != next->role)) {
3726
free(cs->role);
3727
}
3728
if ((prev == NULL || cs->type != prev->type) &&
3729
(next == NULL || cs->type != next->type)) {
3730
free(cs->type);
3731
}
3732
/* Don't free apparmor_profile that is in use by other entries. */
3733
if ((prev == NULL || cs->apparmor_profile != prev->apparmor_profile) &&
3734
(next == NULL || cs->apparmor_profile != next->apparmor_profile)) {
3735
free(cs->apparmor_profile);
3736
}
3737
/* Don't free privs/limitprivs that are in use by other entries. */
3738
if ((prev == NULL || cs->privs != prev->privs) &&
3739
(next == NULL || cs->privs != next->privs)) {
3740
free(cs->privs);
3741
}
3742
if ((prev == NULL || cs->limitprivs != prev->limitprivs) &&
3743
(next == NULL || cs->limitprivs != next->limitprivs)) {
3744
free(cs->limitprivs);
3745
}
3746
/* Don't free user/group lists that are in use by other entries. */
3747
if (cs->runasuserlist != NULL) {
3748
if ((prev == NULL || cs->runasuserlist != prev->runasuserlist) &&
3749
(next == NULL || cs->runasuserlist != next->runasuserlist)) {
3750
free_members(cs->runasuserlist);
3751
free(cs->runasuserlist);
3752
}
3753
}
3754
if (cs->runasgrouplist != NULL) {
3755
if ((prev == NULL || cs->runasgrouplist != prev->runasgrouplist) &&
3756
(next == NULL || cs->runasgrouplist != next->runasgrouplist)) {
3757
free_members(cs->runasgrouplist);
3758
free(cs->runasgrouplist);
3759
}
3760
}
3761
free_member(cs->cmnd);
3762
free(cs);
3763
3764
debug_return;
3765
}
3766
3767
void
3768
free_cmndspecs(struct cmndspec_list *csl)
3769
{
3770
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
3771
char *runcwd = NULL, *runchroot = NULL;
3772
char *role = NULL, *type = NULL;
3773
char *apparmor_profile = NULL;
3774
char *privs = NULL, *limitprivs = NULL;
3775
struct cmndspec *cs;
3776
debug_decl(free_cmndspecs, SUDOERS_DEBUG_PARSER);
3777
3778
while ((cs = TAILQ_FIRST(csl)) != NULL) {
3779
TAILQ_REMOVE(csl, cs, entries);
3780
3781
/* Only free the first instance of runcwd/runchroot. */
3782
if (cs->runcwd != runcwd) {
3783
runcwd = cs->runcwd;
3784
free(cs->runcwd);
3785
}
3786
if (cs->runchroot != runchroot) {
3787
runchroot = cs->runchroot;
3788
free(cs->runchroot);
3789
}
3790
/* Only free the first instance of a role/type. */
3791
if (cs->role != role) {
3792
role = cs->role;
3793
free(cs->role);
3794
}
3795
if (cs->type != type) {
3796
type = cs->type;
3797
free(cs->type);
3798
}
3799
/* Only free the first instance of apparmor_profile. */
3800
if (cs->apparmor_profile != apparmor_profile) {
3801
apparmor_profile = cs->apparmor_profile;
3802
free(cs->apparmor_profile);
3803
}
3804
/* Only free the first instance of privs/limitprivs. */
3805
if (cs->privs != privs) {
3806
privs = cs->privs;
3807
free(cs->privs);
3808
}
3809
if (cs->limitprivs != limitprivs) {
3810
limitprivs = cs->limitprivs;
3811
free(cs->limitprivs);
3812
}
3813
/* Only free the first instance of runas user/group lists. */
3814
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
3815
runasuserlist = cs->runasuserlist;
3816
free_members(runasuserlist);
3817
free(runasuserlist);
3818
}
3819
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
3820
runasgrouplist = cs->runasgrouplist;
3821
free_members(runasgrouplist);
3822
free(runasgrouplist);
3823
}
3824
free_member(cs->cmnd);
3825
free(cs);
3826
}
3827
3828
debug_return;
3829
}
3830
3831
void
3832
free_privilege(struct privilege *priv)
3833
{
3834
struct defaults *def;
3835
debug_decl(free_privilege, SUDOERS_DEBUG_PARSER);
3836
3837
free(priv->ldap_role);
3838
free_members(&priv->hostlist);
3839
free_cmndspecs(&priv->cmndlist);
3840
while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
3841
TAILQ_REMOVE(&priv->defaults, def, entries);
3842
free_default(def);
3843
}
3844
free(priv);
3845
3846
debug_return;
3847
}
3848
3849
void
3850
free_userspecs(struct userspec_list *usl)
3851
{
3852
struct userspec *us;
3853
debug_decl(free_userspecs, SUDOERS_DEBUG_PARSER);
3854
3855
while ((us = TAILQ_FIRST(usl)) != NULL) {
3856
TAILQ_REMOVE(usl, us, entries);
3857
free_userspec(us);
3858
}
3859
3860
debug_return;
3861
}
3862
3863
void
3864
free_userspec(struct userspec *us)
3865
{
3866
struct privilege *priv;
3867
struct sudoers_comment *comment;
3868
debug_decl(free_userspec, SUDOERS_DEBUG_PARSER);
3869
3870
free_members(&us->users);
3871
while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
3872
TAILQ_REMOVE(&us->privileges, priv, entries);
3873
free_privilege(priv);
3874
}
3875
while ((comment = STAILQ_FIRST(&us->comments)) != NULL) {
3876
STAILQ_REMOVE_HEAD(&us->comments, entries);
3877
free(comment->str);
3878
free(comment);
3879
}
3880
sudo_rcstr_delref(us->file);
3881
free(us);
3882
3883
debug_return;
3884
}
3885
3886
/*
3887
* Initialized a sudoers parse tree.
3888
* Takes ownership of lhost and shost.
3889
*/
3890
void
3891
init_parse_tree(struct sudoers_parse_tree *parse_tree, char *lhost, char *shost,
3892
struct sudoers_context *ctx, struct sudo_nss *nss)
3893
{
3894
TAILQ_INIT(&parse_tree->userspecs);
3895
TAILQ_INIT(&parse_tree->defaults);
3896
parse_tree->aliases = NULL;
3897
parse_tree->shost = shost;
3898
parse_tree->lhost = lhost;
3899
parse_tree->ctx = ctx;
3900
parse_tree->nss = nss;
3901
}
3902
3903
/*
3904
* Move the contents of parsed_policy to new_tree.
3905
*/
3906
void
3907
reparent_parse_tree(struct sudoers_parse_tree *new_tree)
3908
{
3909
TAILQ_CONCAT(&new_tree->userspecs, &parsed_policy.userspecs, entries);
3910
TAILQ_CONCAT(&new_tree->defaults, &parsed_policy.defaults, entries);
3911
new_tree->aliases = parsed_policy.aliases;
3912
parsed_policy.aliases = NULL;
3913
}
3914
3915
/*
3916
* Free the contents of a sudoers parse tree and initialize it.
3917
*/
3918
void
3919
free_parse_tree(struct sudoers_parse_tree *parse_tree)
3920
{
3921
free_userspecs(&parse_tree->userspecs);
3922
free_defaults(&parse_tree->defaults);
3923
free_aliases(parse_tree->aliases);
3924
parse_tree->aliases = NULL;
3925
free(parse_tree->lhost);
3926
if (parse_tree->shost != parse_tree->lhost)
3927
free(parse_tree->shost);
3928
parse_tree->lhost = parse_tree->shost = NULL;
3929
parse_tree->nss = NULL;
3930
parse_tree->ctx = NULL;
3931
}
3932
3933
/*
3934
* Free up space used by data structures from a previous parser run and sets
3935
* the current sudoers file to path.
3936
*/
3937
bool
3938
init_parser(struct sudoers_context *ctx, const char *file)
3939
{
3940
bool ret = true;
3941
debug_decl(init_parser, SUDOERS_DEBUG_PARSER);
3942
3943
free_parse_tree(&parsed_policy);
3944
parsed_policy.ctx = ctx;
3945
parser_leak_init();
3946
init_lexer();
3947
parse_error = false;
3948
3949
if (ctx != NULL) {
3950
parser_conf = ctx->parser_conf;
3951
} else {
3952
const struct sudoers_parser_config def_conf =
3953
SUDOERS_PARSER_CONFIG_INITIALIZER;
3954
parser_conf = def_conf;
3955
}
3956
3957
sudo_rcstr_delref(sudoers);
3958
if (file != NULL) {
3959
if ((sudoers = sudo_rcstr_dup(file)) == NULL) {
3960
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
3961
ret = false;
3962
}
3963
} else {
3964
sudoers = NULL;
3965
}
3966
3967
sudo_rcstr_delref(sudoers_search_path);
3968
if (parser_conf.sudoers_path != NULL) {
3969
sudoers_search_path = sudo_rcstr_dup(parser_conf.sudoers_path);
3970
if (sudoers_search_path == NULL) {
3971
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
3972
ret = false;
3973
}
3974
} else {
3975
sudoers_search_path = NULL;
3976
}
3977
3978
debug_return_bool(ret);
3979
}
3980
3981
bool
3982
reset_parser(void)
3983
{
3984
return init_parser(NULL, NULL);
3985
}
3986
3987
/*
3988
* Initialize all options in a cmndspec.
3989
*/
3990
static void
3991
init_options(struct command_options *opts)
3992
{
3993
opts->notbefore = UNSPEC;
3994
opts->notafter = UNSPEC;
3995
opts->timeout = UNSPEC;
3996
opts->runchroot = NULL;
3997
opts->runcwd = NULL;
3998
opts->role = NULL;
3999
opts->type = NULL;
4000
opts->apparmor_profile = NULL;
4001
opts->privs = NULL;
4002
opts->limitprivs = NULL;
4003
}
4004
4005
/*
4006
* Propagate inheritable settings and tags from prev to cs.
4007
*/
4008
static void
4009
propagate_cmndspec(struct cmndspec *cs, const struct cmndspec *prev)
4010
{
4011
/* propagate runcwd and runchroot */
4012
if (cs->runcwd == NULL)
4013
cs->runcwd = prev->runcwd;
4014
if (cs->runchroot == NULL)
4015
cs->runchroot = prev->runchroot;
4016
/* propagate role and type */
4017
if (cs->role == NULL && cs->type == NULL) {
4018
cs->role = prev->role;
4019
cs->type = prev->type;
4020
}
4021
/* propagate apparmor_profile */
4022
if (cs->apparmor_profile == NULL)
4023
cs->apparmor_profile = prev->apparmor_profile;
4024
/* propagate privs & limitprivs */
4025
if (cs->privs == NULL && cs->limitprivs == NULL) {
4026
cs->privs = prev->privs;
4027
cs->limitprivs = prev->limitprivs;
4028
}
4029
/* propagate command time restrictions */
4030
if (cs->notbefore == UNSPEC)
4031
cs->notbefore = prev->notbefore;
4032
if (cs->notafter == UNSPEC)
4033
cs->notafter = prev->notafter;
4034
/* propagate command timeout */
4035
if (cs->timeout == UNSPEC)
4036
cs->timeout = prev->timeout;
4037
/* propagate tags and runas list */
4038
if (cs->tags.nopasswd == UNSPEC)
4039
cs->tags.nopasswd = prev->tags.nopasswd;
4040
if (cs->tags.noexec == UNSPEC)
4041
cs->tags.noexec = prev->tags.noexec;
4042
if (cs->tags.intercept == UNSPEC)
4043
cs->tags.intercept = prev->tags.intercept;
4044
/* Need to handle IMPLIED setting for SETENV tag specially. */
4045
if (!TAG_SET(cs->tags.setenv) && TAG_SET(prev->tags.setenv))
4046
cs->tags.setenv = prev->tags.setenv;
4047
if (cs->tags.log_input == UNSPEC)
4048
cs->tags.log_input = prev->tags.log_input;
4049
if (cs->tags.log_output == UNSPEC)
4050
cs->tags.log_output = prev->tags.log_output;
4051
if (cs->tags.send_mail == UNSPEC)
4052
cs->tags.send_mail = prev->tags.send_mail;
4053
if (cs->tags.follow == UNSPEC)
4054
cs->tags.follow = prev->tags.follow;
4055
if ((cs->runasuserlist == NULL &&
4056
cs->runasgrouplist == NULL) &&
4057
(prev->runasuserlist != NULL ||
4058
prev->runasgrouplist != NULL)) {
4059
cs->runasuserlist = prev->runasuserlist;
4060
cs->runasgrouplist = prev->runasgrouplist;
4061
}
4062
}
4063
4064
uid_t
4065
sudoers_file_uid(void)
4066
{
4067
return parser_conf.sudoers_uid;
4068
}
4069
4070
gid_t
4071
sudoers_file_gid(void)
4072
{
4073
return parser_conf.sudoers_gid;
4074
}
4075
4076
mode_t
4077
sudoers_file_mode(void)
4078
{
4079
return parser_conf.sudoers_mode;
4080
}
4081
4082
bool
4083
sudoers_error_recovery(void)
4084
{
4085
return parser_conf.recovery;
4086
}
4087
4088
bool
4089
sudoers_strict(void)
4090
{
4091
return parser_conf.strict;
4092
}
4093
4094
bool
4095
parser_leak_add(enum parser_leak_types type, void *v)
4096
{
4097
#ifdef NO_LEAKS
4098
struct parser_leak_entry *entry;
4099
debug_decl(parser_leak_add, SUDOERS_DEBUG_PARSER);
4100
4101
if (v == NULL)
4102
debug_return_bool(false);
4103
4104
entry = calloc(1, sizeof(*entry));
4105
if (entry == NULL) {
4106
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
4107
debug_return_bool(false);
4108
}
4109
switch (type) {
4110
case LEAK_PRIVILEGE:
4111
entry->u.p = v;
4112
break;
4113
case LEAK_CMNDSPEC:
4114
entry->u.cs = v;
4115
break;
4116
case LEAK_DEFAULTS:
4117
entry->u.d = v;
4118
break;
4119
case LEAK_MEMBER:
4120
entry->u.m = v;
4121
break;
4122
case LEAK_DIGEST:
4123
entry->u.dig = v;
4124
break;
4125
case LEAK_RUNAS:
4126
entry->u.rc = v;
4127
break;
4128
case LEAK_PTR:
4129
entry->u.ptr = v;
4130
break;
4131
default:
4132
free(entry);
4133
sudo_warnx("unexpected leak type %d", type);
4134
debug_return_bool(false);
4135
}
4136
entry->type = type;
4137
SLIST_INSERT_HEAD(&parser_leak_list, entry, entries);
4138
debug_return_bool(true);
4139
#else
4140
return true;
4141
#endif /* NO_LEAKS */
4142
}
4143
4144
bool
4145
parser_leak_remove(enum parser_leak_types type, void *v)
4146
{
4147
#ifdef NO_LEAKS
4148
struct parser_leak_entry *entry, *prev = NULL;
4149
debug_decl(parser_leak_remove, SUDOERS_DEBUG_PARSER);
4150
4151
if (v == NULL)
4152
debug_return_bool(false);
4153
4154
SLIST_FOREACH(entry, &parser_leak_list, entries) {
4155
switch (entry->type) {
4156
case LEAK_PRIVILEGE:
4157
if (entry->u.p == v)
4158
goto found;
4159
break;
4160
case LEAK_CMNDSPEC:
4161
if (entry->u.cs == v)
4162
goto found;
4163
break;
4164
case LEAK_DEFAULTS:
4165
if (entry->u.d == v)
4166
goto found;
4167
break;
4168
case LEAK_MEMBER:
4169
if (entry->u.m == v)
4170
goto found;
4171
break;
4172
case LEAK_DIGEST:
4173
if (entry->u.dig == v)
4174
goto found;
4175
break;
4176
case LEAK_RUNAS:
4177
if (entry->u.rc == v)
4178
goto found;
4179
break;
4180
case LEAK_PTR:
4181
if (entry->u.ptr == v)
4182
goto found;
4183
break;
4184
default:
4185
sudo_warnx("unexpected leak type %d in %p", entry->type, entry);
4186
}
4187
prev = entry;
4188
}
4189
/* If this happens, there is a bug in the leak tracking code. */
4190
sudo_warnx("%s: unable to find %p, type %d", __func__, v, type);
4191
debug_return_bool(false);
4192
found:
4193
if (prev == NULL)
4194
SLIST_REMOVE_HEAD(&parser_leak_list, entries);
4195
else
4196
SLIST_REMOVE_AFTER(prev, entries);
4197
free(entry);
4198
debug_return_bool(true);
4199
#else
4200
return true;
4201
#endif /* NO_LEAKS */
4202
}
4203
4204
#ifdef NO_LEAKS
4205
static void
4206
parser_leak_free(void)
4207
{
4208
struct parser_leak_entry *entry;
4209
void *next;
4210
debug_decl(parser_leak_run, SUDOERS_DEBUG_PARSER);
4211
4212
/* Free the leaks. */
4213
while ((entry = SLIST_FIRST(&parser_leak_list))) {
4214
SLIST_REMOVE_HEAD(&parser_leak_list, entries);
4215
switch (entry->type) {
4216
case LEAK_PRIVILEGE:
4217
{
4218
struct privilege *priv;
4219
4220
HLTQ_FOREACH_SAFE(priv, entry->u.p, entries, next)
4221
free_privilege(priv);
4222
free(entry);
4223
}
4224
break;
4225
case LEAK_CMNDSPEC:
4226
{
4227
struct cmndspec_list specs;
4228
4229
HLTQ_TO_TAILQ(&specs, entry->u.cs, entries);
4230
free_cmndspecs(&specs);
4231
free(entry);
4232
}
4233
break;
4234
case LEAK_DEFAULTS:
4235
{
4236
struct defaults_list defs;
4237
4238
HLTQ_TO_TAILQ(&defs, entry->u.d, entries);
4239
free_defaults(&defs);
4240
free(entry);
4241
}
4242
break;
4243
case LEAK_MEMBER:
4244
{
4245
struct member *m;
4246
4247
HLTQ_FOREACH_SAFE(m, entry->u.m, entries, next)
4248
free_member(m);
4249
free(entry);
4250
}
4251
break;
4252
case LEAK_DIGEST:
4253
{
4254
struct command_digest *dig;
4255
4256
HLTQ_FOREACH_SAFE(dig, entry->u.dig, entries, next) {
4257
free(dig->digest_str);
4258
free(dig);
4259
}
4260
free(entry);
4261
}
4262
break;
4263
case LEAK_RUNAS:
4264
{
4265
struct member *m;
4266
4267
if (entry->u.rc->runasusers != NULL) {
4268
HLTQ_FOREACH_SAFE(m, entry->u.rc->runasusers, entries, next)
4269
free_member(m);
4270
}
4271
if (entry->u.rc->runasgroups != NULL) {
4272
HLTQ_FOREACH_SAFE(m, entry->u.rc->runasgroups, entries, next)
4273
free_member(m);
4274
}
4275
free(entry->u.rc);
4276
free(entry);
4277
break;
4278
}
4279
case LEAK_PTR:
4280
free(entry->u.ptr);
4281
free(entry);
4282
break;
4283
default:
4284
sudo_warnx("unexpected garbage type %d", entry->type);
4285
}
4286
}
4287
4288
debug_return;
4289
}
4290
#endif /* NO_LEAKS */
4291
4292
void
4293
parser_leak_init(void)
4294
{
4295
#ifdef NO_LEAKS
4296
static bool initialized;
4297
debug_decl(parser_leak_init, SUDOERS_DEBUG_PARSER);
4298
4299
if (!initialized) {
4300
atexit(parser_leak_free);
4301
initialized = true;
4302
debug_return;
4303
}
4304
4305
/* Already initialized, free existing leaks. */
4306
parser_leak_free();
4307
debug_return;
4308
#endif /* NO_LEAKS */
4309
}
4310
4311