Diff for /embedaddon/sudo/plugins/sudoers/toke.l between versions 1.1 and 1.1.1.5

version 1.1, 2012/02/21 16:23:02 version 1.1.1.5, 2014/06/15 16:12:54
Line 1 Line 1
 %{  %{
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2011 * Copyright (c) 1996, 1998-2005, 2007-2013
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 26 Line 26
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
Line 43 Line 42
 #ifdef HAVE_STRINGS_H  #ifdef HAVE_STRINGS_H
 # include <strings.h>  # include <strings.h>
 #endif /* HAVE_STRINGS_H */  #endif /* HAVE_STRINGS_H */
   #if defined(HAVE_STDINT_H)
   # include <stdint.h>
   #elif defined(HAVE_INTTYPES_H)
   # include <inttypes.h>
   #endif
 #ifdef HAVE_UNISTD_H  #ifdef HAVE_UNISTD_H
 # include <unistd.h>  # include <unistd.h>
 #endif /* HAVE_UNISTD_H */  #endif /* HAVE_UNISTD_H */
Line 71 Line 75
 #include "parse.h"  #include "parse.h"
 #include "toke.h"  #include "toke.h"
 #include <gram.h>  #include <gram.h>
   #include "lbuf.h"
   #include "sha2.h"
   #include "secure_path.h"
   
extern YYSTYPE yylval;int sudolineno;                 /* current sudoers line number. */
extern int parse_error;int last_token;                 /* last token that was parsed. */
int sudolineno;char *sudoers;                  /* sudoers file being parsed. */
char *sudoers; 
   
static int continued, prev_state, sawspace;/* Default sudoers path, mode and owner (may be set via sudo.conf) */
 const char *sudoers_file = _PATH_SUDOERS;
 mode_t sudoers_mode = SUDOERS_MODE;
 uid_t sudoers_uid = SUDOERS_UID;
 gid_t sudoers_gid = SUDOERS_GID;
   
static int _push_include(char *, int);static bool continued, sawspace;
static int pop_include(void);static int prev_state;
 static int digest_len;
 
 static bool _push_include(char *, bool);
 static bool pop_include(void);
 static char *parse_include(char *);  static char *parse_include(char *);
   
 #ifdef TRACELEXER  
 static int sudoers_trace_print(const char *msg);  
 #else  
 # define sudoers_trace_print NULL  
 #endif  
 int (*trace_print)(const char *msg) = sudoers_trace_print;  int (*trace_print)(const char *msg) = sudoers_trace_print;
   
#define push_include(_p)        (_push_include((_p), FALSE))#define LEXRETURN(n)    do {    \
#define push_includedir(_p)     (_push_include((_p), TRUE))        last_token = (n);       \
         return (n);             \
 } while (0)
 
 #define ECHO    ignore_result(fwrite(sudoerstext, sudoersleng, 1, sudoersout))
 
 #define push_include(_p)        (_push_include((_p), false))
 #define push_includedir(_p)     (_push_include((_p), true))
 %}  %}
   
 HEX16                   [0-9A-Fa-f]{1,4}  HEX16                   [0-9A-Fa-f]{1,4}
Line 109  DEFVAR   [a-z_]+ Line 125  DEFVAR   [a-z_]+
 %option noinput  %option noinput
 %option nounput  %option nounput
 %option noyywrap  %option noyywrap
   %option prefix="sudoers"
   
 %s      GOTDEFS  %s      GOTDEFS
 %x      GOTCMND  %x      GOTCMND
 %x      STARTDEFS  %x      STARTDEFS
 %x      INDEFS  %x      INDEFS
 %x      INSTR  %x      INSTR
   %s      WANTDIGEST
   
 %%  %%
 <GOTDEFS>[[:blank:]]*,[[:blank:]]* {  <GOTDEFS>[[:blank:]]*,[[:blank:]]* {
                             LEXTRACE(", ");                              LEXTRACE(", ");
                            return ',';                            LEXRETURN(',');
                         }                       /* return ',' */                          }                       /* return ',' */
   
 <GOTDEFS>[[:blank:]]+   BEGIN STARTDEFS;  <GOTDEFS>[[:blank:]]+   BEGIN STARTDEFS;
Line 127  DEFVAR   [a-z_]+ Line 145  DEFVAR   [a-z_]+
 <STARTDEFS>{DEFVAR}     {  <STARTDEFS>{DEFVAR}     {
                             BEGIN INDEFS;                              BEGIN INDEFS;
                             LEXTRACE("DEFVAR ");                              LEXTRACE("DEFVAR ");
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                            return DEFVAR;                            LEXRETURN(DEFVAR);
                         }                          }
   
 <INDEFS>{  <INDEFS>{
     ,                   {      ,                   {
                             BEGIN STARTDEFS;                              BEGIN STARTDEFS;
                             LEXTRACE(", ");                              LEXTRACE(", ");
                            return ',';                            LEXRETURN(',');
                         }                       /* return ',' */                          }                       /* return ',' */
   
     =                   {      =                   {
                             LEXTRACE("= ");                              LEXTRACE("= ");
                            return '=';                            LEXRETURN('=');
                         }                       /* return '=' */                          }                       /* return '=' */
   
     \+=                 {      \+=                 {
                             LEXTRACE("+= ");                              LEXTRACE("+= ");
                            return '+';                            LEXRETURN('+');
                         }                       /* return '+' */                          }                       /* return '+' */
   
     -=                  {      -=                  {
                             LEXTRACE("-= ");                              LEXTRACE("-= ");
                            return '-';                            LEXRETURN('-');
                         }                       /* return '-' */                          }                       /* return '-' */
   
     \"                  {      \"                  {
                             LEXTRACE("BEGINSTR ");                              LEXTRACE("BEGINSTR ");
                            yylval.string = NULL;                            sudoerslval.string = NULL;
                             prev_state = YY_START;                              prev_state = YY_START;
                             BEGIN INSTR;                              BEGIN INSTR;
                         }                          }
   
     {ENVAR}             {      {ENVAR}             {
                             LEXTRACE("WORD(2) ");                              LEXTRACE("WORD(2) ");
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                            return WORD;                            LEXRETURN(WORD);
                         }                          }
 }  }
   
 <INSTR>{  <INSTR>{
     \\[[:blank:]]*\n[[:blank:]]*        {      \\[[:blank:]]*\n[[:blank:]]*        {
                             /* Line continuation char followed by newline. */                              /* Line continuation char followed by newline. */
                            ++sudolineno;                            sudolineno++;
                            continued = TRUE;                            continued = true;
                         }                          }
   
     \"                  {      \"                  {
                             LEXTRACE("ENDSTR ");                              LEXTRACE("ENDSTR ");
                             BEGIN prev_state;                              BEGIN prev_state;
   
                            if (yylval.string == NULL) {                            if (sudoerslval.string == NULL) {
                                 LEXTRACE("ERROR "); /* empty string */                                  LEXTRACE("ERROR "); /* empty string */
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
                             if (prev_state == INITIAL) {                              if (prev_state == INITIAL) {
                                switch (yylval.string[0]) {                                switch (sudoerslval.string[0]) {
                                 case '%':                                  case '%':
                                    if (yylval.string[1] == '\0' ||                                    if (sudoerslval.string[1] == '\0' ||
                                        (yylval.string[1] == ':' &&                                        (sudoerslval.string[1] == ':' &&
                                        yylval.string[2] == '\0')) {                                        sudoerslval.string[2] == '\0')) {
                                         LEXTRACE("ERROR "); /* empty group */                                          LEXTRACE("ERROR "); /* empty group */
                                        return ERROR;                                        LEXRETURN(ERROR);
                                     }                                      }
                                     LEXTRACE("USERGROUP ");                                      LEXTRACE("USERGROUP ");
                                    return USERGROUP;                                    LEXRETURN(USERGROUP);
                                 case '+':                                  case '+':
                                    if (yylval.string[1] == '\0') {                                    if (sudoerslval.string[1] == '\0') {
                                         LEXTRACE("ERROR "); /* empty netgroup */                                          LEXTRACE("ERROR "); /* empty netgroup */
                                        return ERROR;                                        LEXRETURN(ERROR);
                                     }                                      }
                                     LEXTRACE("NETGROUP ");                                      LEXTRACE("NETGROUP ");
                                    return NETGROUP;                                    LEXRETURN(NETGROUP);
                                 }                                  }
                             }                              }
                             LEXTRACE("WORD(4) ");                              LEXTRACE("WORD(4) ");
                            return WORD;                            LEXRETURN(WORD);
                         }                          }
   
     \\                  {      \\                  {
                             LEXTRACE("BACKSLASH ");                              LEXTRACE("BACKSLASH ");
                            if (!append(yytext, yyleng))                            if (!append(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                         }                          }
   
     ([^\"\n\\]|\\\")+   {      ([^\"\n\\]|\\\")+   {
                             LEXTRACE("STRBODY ");                              LEXTRACE("STRBODY ");
                            if (!append(yytext, yyleng))                            if (!append(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                         }                          }
 }  }
Line 225  DEFVAR   [a-z_]+ Line 243  DEFVAR   [a-z_]+
     \\[\*\?\[\]\!]      {      \\[\*\?\[\]\!]      {
                             /* quoted fnmatch glob char, pass verbatim */                              /* quoted fnmatch glob char, pass verbatim */
                             LEXTRACE("QUOTEDCHAR ");                              LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext, 2, sawspace))                            if (!fill_args(sudoerstext, 2, sawspace))
                                 yyterminate();                                  yyterminate();
                            sawspace = FALSE;                            sawspace = false;
                         }                          }
   
     \\[:\\,= \t#]       {      \\[:\\,= \t#]       {
                             /* quoted sudoers special char, strip backslash */                              /* quoted sudoers special char, strip backslash */
                             LEXTRACE("QUOTEDCHAR ");                              LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext + 1, 1, sawspace))                            if (!fill_args(sudoerstext + 1, 1, sawspace))
                                 yyterminate();                                  yyterminate();
                            sawspace = FALSE;                            sawspace = false;
                         }                          }
   
     [#:\,=\n]           {      [#:\,=\n]           {
                             BEGIN INITIAL;                              BEGIN INITIAL;
                             yyless(0);                              yyless(0);
                            return COMMAND;                            LEXRETURN(COMMAND);
                         }                       /* end of command line args */                          }                       /* end of command line args */
   
     [^#\\:, \t\n]+      {      [^#\\:, \t\n]+      {
                             LEXTRACE("ARG ");                              LEXTRACE("ARG ");
                            if (!fill_args(yytext, yyleng, sawspace))                            if (!fill_args(sudoerstext, sudoersleng, sawspace))
                                 yyterminate();                                  yyterminate();
                            sawspace = FALSE;                            sawspace = false;
                         }                       /* a command line arg */                          }                       /* a command line arg */
 }  }
   
<INITIAL>^#include[[:blank:]]+\/.*\n {<WANTDIGEST>[[:xdigit:]]+ {
                             /* Only return DIGEST if the length is correct. */
                             if (sudoersleng == digest_len * 2) {
                                 if (!fill(sudoerstext, sudoersleng))
                                     yyterminate();
                                 BEGIN INITIAL;
                                 LEXTRACE("DIGEST ");
                                 LEXRETURN(DIGEST);
                             }
                             BEGIN INITIAL;
                             yyless(sudoersleng);
                         } /* hex digest */
 
 <WANTDIGEST>[A-Za-z0-9\+/=]+ {
                             /* Only return DIGEST if the length is correct. */
                             int len;
                             if (sudoerstext[sudoersleng - 1] == '=') {
                                 /* use padding */
                                 len = 4 * ((digest_len + 2) / 3);
                             } else {
                                 /* no padding */
                                 len = (4 * digest_len + 2) / 3;
                             }
                             if (sudoersleng == len) {
                                 if (!fill(sudoerstext, sudoersleng))
                                     yyterminate();
                                 BEGIN INITIAL;
                                 LEXTRACE("DIGEST ");
                                 LEXRETURN(DIGEST);
                             }
                             BEGIN INITIAL;
                             yyless(sudoersleng);
                         } /* base64 digest */
 
 <INITIAL>^#include[[:blank:]]+.*\n {
                             char *path;                              char *path;
   
                             if (continued) {                              if (continued) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
   
                            if ((path = parse_include(yytext)) == NULL)                            if ((path = parse_include(sudoerstext)) == NULL)
                                 yyterminate();                                  yyterminate();
   
                             LEXTRACE("INCLUDE\n");                              LEXTRACE("INCLUDE\n");
Line 270  DEFVAR   [a-z_]+ Line 322  DEFVAR   [a-z_]+
                                 yyterminate();                                  yyterminate();
                         }                          }
   
<INITIAL>^#includedir[[:blank:]]+\/.*\n {<INITIAL>^#includedir[[:blank:]]+.*\n {
                             char *path;                              char *path;
   
                             if (continued) {                              if (continued) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
   
                            if ((path = parse_include(yytext)) == NULL)                            if ((path = parse_include(sudoerstext)) == NULL)
                                 yyterminate();                                  yyterminate();
   
                             LEXTRACE("INCLUDEDIR\n");                              LEXTRACE("INCLUDEDIR\n");
Line 297  DEFVAR   [a-z_]+ Line 349  DEFVAR   [a-z_]+
   
                             if (continued) {                              if (continued) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
   
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)                            for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
                                 continue;                                  continue;
                             n += sizeof("Defaults") - 1;                              n += sizeof("Defaults") - 1;
                            if ((deftype = yytext[n++]) != '\0') {                            if ((deftype = sudoerstext[n++]) != '\0') {
                                while (isblank((unsigned char)yytext[n]))                                while (isblank((unsigned char)sudoerstext[n]))
                                     n++;                                      n++;
                             }                              }
                             BEGIN GOTDEFS;                              BEGIN GOTDEFS;
Line 312  DEFVAR   [a-z_]+ Line 364  DEFVAR   [a-z_]+
                                 case ':':                                  case ':':
                                     yyless(n);                                      yyless(n);
                                     LEXTRACE("DEFAULTS_USER ");                                      LEXTRACE("DEFAULTS_USER ");
                                    return DEFAULTS_USER;                                    LEXRETURN(DEFAULTS_USER);
                                 case '>':                                  case '>':
                                     yyless(n);                                      yyless(n);
                                     LEXTRACE("DEFAULTS_RUNAS ");                                      LEXTRACE("DEFAULTS_RUNAS ");
                                    return DEFAULTS_RUNAS;                                    LEXRETURN(DEFAULTS_RUNAS);
                                 case '@':                                  case '@':
                                     yyless(n);                                      yyless(n);
                                     LEXTRACE("DEFAULTS_HOST ");                                      LEXTRACE("DEFAULTS_HOST ");
                                    return DEFAULTS_HOST;                                    LEXRETURN(DEFAULTS_HOST);
                                 case '!':                                  case '!':
                                     yyless(n);                                      yyless(n);
                                     LEXTRACE("DEFAULTS_CMND ");                                      LEXTRACE("DEFAULTS_CMND ");
                                    return DEFAULTS_CMND;                                    LEXRETURN(DEFAULTS_CMND);
                                 default:                                  default:
                                     LEXTRACE("DEFAULTS ");                                      LEXTRACE("DEFAULTS ");
                                    return DEFAULTS;                                    LEXRETURN(DEFAULTS);
                             }                              }
                         }                          }
   
Line 336  DEFVAR   [a-z_]+ Line 388  DEFVAR   [a-z_]+
   
                             if (continued) {                              if (continued) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
   
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)                            for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
                                 continue;                                  continue;
                            switch (yytext[n]) {                            switch (sudoerstext[n]) {
                                 case 'H':                                  case 'H':
                                     LEXTRACE("HOSTALIAS ");                                      LEXTRACE("HOSTALIAS ");
                                    return HOSTALIAS;                                    LEXRETURN(HOSTALIAS);
                                 case 'C':                                  case 'C':
                                     LEXTRACE("CMNDALIAS ");                                      LEXTRACE("CMNDALIAS ");
                                    return CMNDALIAS;                                    LEXRETURN(CMNDALIAS);
                                 case 'U':                                  case 'U':
                                     LEXTRACE("USERALIAS ");                                      LEXTRACE("USERALIAS ");
                                    return USERALIAS;                                    LEXRETURN(USERALIAS);
                                 case 'R':                                  case 'R':
                                     LEXTRACE("RUNASALIAS ");                                      LEXTRACE("RUNASALIAS ");
                                    return RUNASALIAS;                                    LEXRETURN(RUNASALIAS);
                             }                              }
                         }                          }
   
 NOPASSWD[[:blank:]]*:   {  NOPASSWD[[:blank:]]*:   {
                                 /* cmnd does not require passwd for this user */                                  /* cmnd does not require passwd for this user */
                                 LEXTRACE("NOPASSWD ");                                  LEXTRACE("NOPASSWD ");
                                return NOPASSWD;                                LEXRETURN(NOPASSWD);
                         }                          }
   
 PASSWD[[:blank:]]*:     {  PASSWD[[:blank:]]*:     {
                                 /* cmnd requires passwd for this user */                                  /* cmnd requires passwd for this user */
                                 LEXTRACE("PASSWD ");                                  LEXTRACE("PASSWD ");
                                return PASSWD;                                LEXRETURN(PASSWD);
                         }                          }
   
 NOEXEC[[:blank:]]*:     {  NOEXEC[[:blank:]]*:     {
                                 LEXTRACE("NOEXEC ");                                  LEXTRACE("NOEXEC ");
                                return NOEXEC;                                LEXRETURN(NOEXEC);
                         }                          }
   
 EXEC[[:blank:]]*:       {  EXEC[[:blank:]]*:       {
                                 LEXTRACE("EXEC ");                                  LEXTRACE("EXEC ");
                                return EXEC;                                LEXRETURN(EXEC);
                         }                          }
   
 SETENV[[:blank:]]*:     {  SETENV[[:blank:]]*:     {
                                 LEXTRACE("SETENV ");                                  LEXTRACE("SETENV ");
                                return SETENV;                                LEXRETURN(SETENV);
                         }                          }
   
 NOSETENV[[:blank:]]*:   {  NOSETENV[[:blank:]]*:   {
                                 LEXTRACE("NOSETENV ");                                  LEXTRACE("NOSETENV ");
                                return NOSETENV;                                LEXRETURN(NOSETENV);
                         }                          }
   
 LOG_OUTPUT[[:blank:]]*: {  LOG_OUTPUT[[:blank:]]*: {
                                 LEXTRACE("LOG_OUTPUT ");                                  LEXTRACE("LOG_OUTPUT ");
                                return LOG_OUTPUT;                                LEXRETURN(LOG_OUTPUT);
                         }                          }
   
 NOLOG_OUTPUT[[:blank:]]*:       {  NOLOG_OUTPUT[[:blank:]]*:       {
                                 LEXTRACE("NOLOG_OUTPUT ");                                  LEXTRACE("NOLOG_OUTPUT ");
                                return NOLOG_OUTPUT;                                LEXRETURN(NOLOG_OUTPUT);
                         }                          }
   
 LOG_INPUT[[:blank:]]*:  {  LOG_INPUT[[:blank:]]*:  {
                                 LEXTRACE("LOG_INPUT ");                                  LEXTRACE("LOG_INPUT ");
                                return LOG_INPUT;                                LEXRETURN(LOG_INPUT);
                         }                          }
   
 NOLOG_INPUT[[:blank:]]*:        {  NOLOG_INPUT[[:blank:]]*:        {
                                 LEXTRACE("NOLOG_INPUT ");                                  LEXTRACE("NOLOG_INPUT ");
                                return NOLOG_INPUT;                                LEXRETURN(NOLOG_INPUT);
                         }                          }
   
 <INITIAL,GOTDEFS>(\+|\%|\%:) {  <INITIAL,GOTDEFS>(\+|\%|\%:) {
                             /* empty group or netgroup */                              /* empty group or netgroup */
                             LEXTRACE("ERROR ");                              LEXTRACE("ERROR ");
                            return ERROR;                            LEXRETURN(ERROR);
                         }                          }
   
 \+{WORD}                {  \+{WORD}                {
                             /* netgroup */                              /* netgroup */
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NETGROUP ");                              LEXTRACE("NETGROUP ");
                            return NETGROUP;                            LEXRETURN(NETGROUP);
                         }                          }
   
 \%:?({WORD}|{ID})       {  \%:?({WORD}|{ID})       {
                             /* group */                              /* group */
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("USERGROUP ");                              LEXTRACE("USERGROUP ");
                            return USERGROUP;                            LEXRETURN(USERGROUP);
                         }                          }
   
 {IPV4ADDR}(\/{IPV4ADDR})? {  {IPV4ADDR}(\/{IPV4ADDR})? {
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                            return NTWKADDR;                            LEXRETURN(NTWKADDR);
                         }                          }
   
 {IPV4ADDR}\/([12]?[0-9]|3[0-2]) {  {IPV4ADDR}\/([12]?[0-9]|3[0-2]) {
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                            return NTWKADDR;                            LEXRETURN(NTWKADDR);
                         }                          }
   
 {IPV6ADDR}(\/{IPV6ADDR})? {  {IPV6ADDR}(\/{IPV6ADDR})? {
                            if (!ipv6_valid(yytext)) {                            if (!ipv6_valid(sudoerstext)) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                            return NTWKADDR;                            LEXRETURN(NTWKADDR);
                         }                          }
   
 {IPV6ADDR}\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]) {  {IPV6ADDR}\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]) {
                            if (!ipv6_valid(yytext)) {                            if (!ipv6_valid(sudoerstext)) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                            return NTWKADDR;                            LEXRETURN(NTWKADDR);
                         }                          }
   
 ALL {  ALL {
                             LEXTRACE("ALL ");                              LEXTRACE("ALL ");
                            return ALL;                            LEXRETURN(ALL);
   
                         }                          }
   
 <INITIAL>ROLE {  <INITIAL>ROLE {
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
                             LEXTRACE("ROLE ");                              LEXTRACE("ROLE ");
                            return ROLE;                            LEXRETURN(ROLE);
 #else  #else
                             goto got_alias;                              goto got_alias;
 #endif  #endif
Line 485  ALL { Line 537  ALL {
 <INITIAL>TYPE {  <INITIAL>TYPE {
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
                             LEXTRACE("TYPE ");                              LEXTRACE("TYPE ");
                            return TYPE;                            LEXRETURN(TYPE);
 #else  #else
                             goto got_alias;                              goto got_alias;
 #endif  #endif
                         }                          }
   <INITIAL>PRIVS {
   #ifdef HAVE_PRIV_SET
                               LEXTRACE("PRIVS ");
                               LEXRETURN(PRIVS);
   #else
                               goto got_alias;
   #endif
                           }
   
   <INITIAL>LIMITPRIVS {
   #ifdef HAVE_PRIV_SET
                               LEXTRACE("LIMITPRIVS ");
                               LEXRETURN(LIMITPRIVS);
   #else
                               goto got_alias;
   #endif
                           }
   
 [[:upper:]][[:upper:][:digit:]_]* {  [[:upper:]][[:upper:][:digit:]_]* {
 #ifndef HAVE_SELINUX  
                         got_alias:                          got_alias:
#endif                            if (!fill(sudoerstext, sudoersleng))
                            if (!fill(yytext, yyleng)) 
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("ALIAS ");                              LEXTRACE("ALIAS ");
                            return ALIAS;                            LEXRETURN(ALIAS);
                         }                          }
   
 <GOTDEFS>({PATH}|sudoedit) {  <GOTDEFS>({PATH}|sudoedit) {
                               /* XXX - no way to specify digest for command */
                             /* no command args allowed for Defaults!/path */                              /* no command args allowed for Defaults!/path */
                            if (!fill_cmnd(yytext, yyleng))                            if (!fill_cmnd(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("COMMAND ");                              LEXTRACE("COMMAND ");
                            return COMMAND;                            LEXRETURN(COMMAND);
                         }                          }
   
   sha224                  {
                               digest_len = SHA224_DIGEST_LENGTH;
                               BEGIN WANTDIGEST;
                               LEXTRACE("SHA224 ");
                               LEXRETURN(SHA224);
                           }
   
   sha256                  {
                               digest_len = SHA256_DIGEST_LENGTH;
                               BEGIN WANTDIGEST;
                               LEXTRACE("SHA256 ");
                               LEXRETURN(SHA256);
                           }
   
   sha384                  {
                               digest_len = SHA384_DIGEST_LENGTH;
                               BEGIN WANTDIGEST;
                               LEXTRACE("SHA384 ");
                               LEXRETURN(SHA384);
                           }
   
   sha512                  {
                               digest_len = SHA512_DIGEST_LENGTH;
                               BEGIN WANTDIGEST;
                               LEXTRACE("SHA512 ");
                               LEXRETURN(SHA512);
                           }
   
 sudoedit                {  sudoedit                {
                             BEGIN GOTCMND;                              BEGIN GOTCMND;
                             LEXTRACE("COMMAND ");                              LEXTRACE("COMMAND ");
                            if (!fill_cmnd(yytext, yyleng))                            if (!fill_cmnd(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                         }                       /* sudo -e */                          }                       /* sudo -e */
   
 {PATH}                  {  {PATH}                  {
                             /* directories can't have args... */                              /* directories can't have args... */
                            if (yytext[yyleng - 1] == '/') {                            if (sudoerstext[sudoersleng - 1] == '/') {
                                 LEXTRACE("COMMAND ");                                  LEXTRACE("COMMAND ");
                                if (!fill_cmnd(yytext, yyleng))                                if (!fill_cmnd(sudoerstext, sudoersleng))
                                     yyterminate();                                      yyterminate();
                                return COMMAND;                                LEXRETURN(COMMAND);
                             } else {                              } else {
                                 BEGIN GOTCMND;                                  BEGIN GOTCMND;
                                 LEXTRACE("COMMAND ");                                  LEXTRACE("COMMAND ");
                                if (!fill_cmnd(yytext, yyleng))                                if (!fill_cmnd(sudoerstext, sudoersleng))
                                     yyterminate();                                      yyterminate();
                             }                              }
                         }                       /* a pathname */                          }                       /* a pathname */
   
 <INITIAL,GOTDEFS>\" {  <INITIAL,GOTDEFS>\" {
                             LEXTRACE("BEGINSTR ");                              LEXTRACE("BEGINSTR ");
                            yylval.string = NULL;                            sudoerslval.string = NULL;
                             prev_state = YY_START;                              prev_state = YY_START;
                             BEGIN INSTR;                              BEGIN INSTR;
                         }                          }
   
 <INITIAL,GOTDEFS>({ID}|{WORD}) {  <INITIAL,GOTDEFS>({ID}|{WORD}) {
                             /* a word */                              /* a word */
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("WORD(5) ");                              LEXTRACE("WORD(5) ");
                            return WORD;                            LEXRETURN(WORD);
                         }                          }
   
 \(                      {  \(                      {
                             LEXTRACE("( ");                              LEXTRACE("( ");
                            return '(';                            LEXRETURN('(');
                         }                          }
   
 \)                      {  \)                      {
                             LEXTRACE(") ");                              LEXTRACE(") ");
                            return ')';                            LEXRETURN(')');
                         }                          }
   
 ,                       {  ,                       {
                             LEXTRACE(", ");                              LEXTRACE(", ");
                            return ',';                            LEXRETURN(',');
                         }                       /* return ',' */                          }                       /* return ',' */
   
 =                       {  =                       {
                             LEXTRACE("= ");                              LEXTRACE("= ");
                            return '=';                            LEXRETURN('=');
                         }                       /* return '=' */                          }                       /* return '=' */
   
 :                       {  :                       {
                             LEXTRACE(": ");                              LEXTRACE(": ");
                            return ':';                            LEXRETURN(':');
                         }                       /* return ':' */                          }                       /* return ':' */
   
 <*>!+                   {  <*>!+                   {
                            if (yyleng & 1) {                            if (sudoersleng & 1) {
                                 LEXTRACE("!");                                  LEXTRACE("!");
                                return '!';       /* return '!' */                                LEXRETURN('!');       /* return '!' */
                             }                              }
                         }                          }
   
 <*>\n                   {  <*>\n                   {
                             if (YY_START == INSTR) {                              if (YY_START == INSTR) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;       /* line break in string */                                LEXRETURN(ERROR);       /* line break in string */
                             }                              }
                             BEGIN INITIAL;                              BEGIN INITIAL;
                            ++sudolineno;                            sudolineno++;
                            continued = FALSE;                            continued = false;
                             LEXTRACE("\n");                              LEXTRACE("\n");
                            return COMMENT;                            LEXRETURN(COMMENT);
                         }                       /* return newline */                          }                       /* return newline */
   
 <*>[[:blank:]]+         {                       /* throw away space/tabs */  <*>[[:blank:]]+         {                       /* throw away space/tabs */
                            sawspace = TRUE;       /* but remember for fill_args */                            sawspace = true;       /* but remember for fill_args */
                         }                          }
   
 <*>\\[[:blank:]]*\n     {  <*>\\[[:blank:]]*\n     {
                            sawspace = TRUE;       /* remember for fill_args */                            sawspace = true;       /* remember for fill_args */
                            ++sudolineno;                            sudolineno++;
                            continued = TRUE;                            continued = true;
                         }                       /* throw away EOL after \ */                          }                       /* throw away EOL after \ */
   
<INITIAL,STARTDEFS,INDEFS>#(-[^\n0-9].*|[^\n0-9-].*)?\n {<INITIAL,STARTDEFS,INDEFS>#(-[^\n0-9].*|[^\n0-9-].*)?\n?       {
                            BEGIN INITIAL;                            if (sudoerstext[sudoersleng - 1] == '\n') {
                            ++sudolineno;                                /* comment ending in a newline */
                            continued = FALSE;                                BEGIN INITIAL;
                                 sudolineno++;
                                 continued = false;
                             } else if (!feof(yyin)) {
                                 LEXTRACE("ERROR ");
                                 LEXRETURN(ERROR);
                             }
                             LEXTRACE("#\n");                              LEXTRACE("#\n");
                            return COMMENT;                            LEXRETURN(COMMENT);
                         }                       /* comment, not uid/gid */                          }                       /* comment, not uid/gid */
   
 <*>.                    {  <*>.                    {
                             LEXTRACE("ERROR ");                              LEXTRACE("ERROR ");
                            return ERROR;                            LEXRETURN(ERROR);
                         }       /* parse error */                          }       /* parse error */
   
 <*><<EOF>>              {  <*><<EOF>>              {
                             if (YY_START != INITIAL) {                              if (YY_START != INITIAL) {
                                 BEGIN INITIAL;                                  BEGIN INITIAL;
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                return ERROR;                                LEXRETURN(ERROR);
                             }                              }
                             if (!pop_include())                              if (!pop_include())
                                 yyterminate();                                  yyterminate();
Line 625  sudoedit  { Line 727  sudoedit  {
   
 %%  %%
 struct path_list {  struct path_list {
       SLIST_ENTRY(path_list) entries;
     char *path;      char *path;
     struct path_list *next;  
 };  };
   
   SLIST_HEAD(path_list_head, path_list);
   
 struct include_stack {  struct include_stack {
     YY_BUFFER_STATE bs;      YY_BUFFER_STATE bs;
     char *path;      char *path;
    struct path_list *more; /* more files in case of includedir */    struct path_list_head more; /* more files in case of includedir */
     int lineno;      int lineno;
    int keepopen;    bool keepopen;
 };  };
   
   /*
    * Compare two struct path_list structs in reverse order.
    */
 static int  static int
 pl_compare(const void *v1, const void *v2)  pl_compare(const void *v1, const void *v2)
 {  {
     const struct path_list * const *p1 = v1;      const struct path_list * const *p1 = v1;
     const struct path_list * const *p2 = v2;      const struct path_list * const *p2 = v2;
   
    return strcmp((*p1)->path, (*p2)->path);    return strcmp((*p2)->path, (*p1)->path);
 }  }
   
 static char *  static char *
 switch_dir(struct include_stack *stack, char *dirpath)  switch_dir(struct include_stack *stack, char *dirpath)
 {  {
     DIR *dir;      DIR *dir;
    int i, count = 0;    unsigned int i, count = 0;
     unsigned int max_paths = 32;
     char *path = NULL;      char *path = NULL;
     struct dirent *dent;      struct dirent *dent;
     struct stat sb;      struct stat sb;
    struct path_list *pl, *first = NULL;    struct path_list *pl, **paths = NULL;
    struct path_list **sorted = NULL;    debug_decl(switch_dir, SUDO_DEBUG_PARSER)
   
     if (!(dir = opendir(dirpath))) {      if (!(dir = opendir(dirpath))) {
         if (errno != ENOENT) {          if (errno != ENOENT) {
            char *errbuf;            warning("%s", dirpath);
            if (asprintf(&errbuf, _("%s: %s"), dirpath, strerror(errno)) != -1) {            sudoerserror(NULL);
                yyerror(errbuf); 
                free(errbuf); 
            } else { 
                yyerror(_("unable to allocate memory")); 
            } 
         }          }
         goto done;          goto done;
     }      }
       paths = malloc(sizeof(*paths) * max_paths);
       if (paths == NULL) {
           closedir(dir);
           goto bad;
       }
     while ((dent = readdir(dir))) {      while ((dent = readdir(dir))) {
         /* Ignore files that end in '~' or have a '.' in them. */          /* Ignore files that end in '~' or have a '.' in them. */
         if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'          if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
Line 688  switch_dir(struct include_stack *stack, char *dirpath) Line 796  switch_dir(struct include_stack *stack, char *dirpath)
         if (pl == NULL)          if (pl == NULL)
             goto bad;              goto bad;
         pl->path = path;          pl->path = path;
        pl->next = first;        if (count >= max_paths) {
        first = pl;            struct path_list **tmp;
        count++;            max_paths <<= 1;
             tmp = realloc(paths, sizeof(*paths) * max_paths);
             if (tmp == NULL) {
                 closedir(dir);
                 goto bad;
             }
             paths = tmp;
         }
         paths[count++] = pl;
         path = NULL;
     }      }
     closedir(dir);      closedir(dir);
   
     if (count == 0)      if (count == 0)
         goto done;          goto done;
   
    /* Sort the list as an array. */    /* Sort the list as an array in reverse order. */
    sorted = malloc(sizeof(*sorted) * count);    qsort(paths, count, sizeof(*paths), pl_compare);
    if (sorted == NULL)
        goto bad;    /* Build up the list in sorted order. */
    pl = first; 
     for (i = 0; i < count; i++) {      for (i = 0; i < count; i++) {
        sorted[i] = pl;        SLIST_INSERT_HEAD(&stack->more, paths[i], entries);
        pl = pl->next; 
     }      }
     qsort(sorted, count, sizeof(*sorted), pl_compare);  
   
     /* Apply sorting to the list. */  
     first = sorted[0];  
     sorted[count - 1]->next = NULL;  
     for (i = 1; i < count; i++)  
         sorted[i - 1]->next = sorted[i];  
     efree(sorted);  
   
     /* Pull out the first element for parsing, leave the rest for later. */      /* Pull out the first element for parsing, leave the rest for later. */
    if (count) {    pl = SLIST_FIRST(&stack->more);
        path = first->path;    SLIST_REMOVE_HEAD(&stack->more, entries);
        pl = first->next;    path = pl->path;
        efree(first);    efree(pl);
        stack->more = pl; 
    } else { 
        path = NULL; 
    } 
 done:  done:
       efree(paths);
     efree(dirpath);      efree(dirpath);
    return path;    debug_return_str(path);
 bad:  bad:
    while (first != NULL) {    for (i = 0; i < count; i++) {
        pl = first;        efree(paths[i]->path);
        first = pl->next;        efree(paths[i]);
        free(pl->path); 
        free(pl); 
     }      }
    efree(sorted);    efree(paths);
     efree(dirpath);      efree(dirpath);
     efree(path);      efree(path);
    return NULL;    debug_return_str(NULL);
 }  }
   
 #define MAX_SUDOERS_DEPTH       128  #define MAX_SUDOERS_DEPTH       128
Line 745  bad: Line 847  bad:
   
 static size_t istacksize, idepth;  static size_t istacksize, idepth;
 static struct include_stack *istack;  static struct include_stack *istack;
static int keepopen;static bool keepopen;
   
 void  void
 init_lexer(void)  init_lexer(void)
 {  {
     struct path_list *pl;      struct path_list *pl;
       debug_decl(init_lexer, SUDO_DEBUG_PARSER)
   
     while (idepth) {      while (idepth) {
         idepth--;          idepth--;
        while ((pl = istack[idepth].more) != NULL) {        while ((pl = SLIST_FIRST(&istack[idepth].more)) != NULL) {
            istack[idepth].more = pl->next;            SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
             efree(pl->path);              efree(pl->path);
             efree(pl);              efree(pl);
         }          }
         efree(istack[idepth].path);          efree(istack[idepth].path);
         if (idepth && !istack[idepth].keepopen)          if (idepth && !istack[idepth].keepopen)
             fclose(istack[idepth].bs->yy_input_file);              fclose(istack[idepth].bs->yy_input_file);
        yy_delete_buffer(istack[idepth].bs);        sudoers_delete_buffer(istack[idepth].bs);
     }      }
     efree(istack);      efree(istack);
     istack = NULL;      istack = NULL;
     istacksize = idepth = 0;      istacksize = idepth = 0;
     sudolineno = 1;      sudolineno = 1;
    keepopen = FALSE;    keepopen = false;
    sawspace = FALSE;    sawspace = false;
    continued = FALSE;    continued = false;
     prev_state = INITIAL;      prev_state = INITIAL;
   
       debug_return;
 }  }
   
static intstatic bool
_push_include(char *path, int isdir)_push_include(char *path, bool isdir)
 {  {
     struct path_list *pl;      struct path_list *pl;
     FILE *fp;      FILE *fp;
       debug_decl(_push_include, SUDO_DEBUG_PARSER)
   
     /* push current state onto stack */      /* push current state onto stack */
     if (idepth >= istacksize) {      if (idepth >= istacksize) {
           struct include_stack *new_istack;
   
         if (idepth > MAX_SUDOERS_DEPTH) {          if (idepth > MAX_SUDOERS_DEPTH) {
            yyerror(_("too many levels of includes"));            sudoerserror(N_("too many levels of includes"));
            return FALSE;            debug_return_bool(false);
         }          }
         istacksize += SUDOERS_STACK_INCREMENT;          istacksize += SUDOERS_STACK_INCREMENT;
        istack = (struct include_stack *) realloc(istack,        new_istack = (struct include_stack *) realloc(istack,
             sizeof(*istack) * istacksize);              sizeof(*istack) * istacksize);
        if (istack == NULL) {        if (new_istack == NULL) {
            yyerror(_("unable to allocate memory"));            warning(NULL);
            return FALSE;            sudoerserror(NULL);
             debug_return_bool(false);
         }          }
           istack = new_istack;
     }      }
       SLIST_INIT(&istack[idepth].more);
     if (isdir) {      if (isdir) {
           struct stat sb;
           switch (sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb)) {
               case SUDO_PATH_SECURE:
                   break;
               case SUDO_PATH_MISSING:
                   debug_return_bool(false);
               case SUDO_PATH_BAD_TYPE:
                   errno = ENOTDIR;
                   if (sudoers_warnings) {
                       warning("%s", path);
                   }
                   debug_return_bool(false);
               case SUDO_PATH_WRONG_OWNER:
                   if (sudoers_warnings) {
                       warningx(U_("%s is owned by uid %u, should be %u"),   
                           path, (unsigned int) sb.st_uid,
                           (unsigned int) sudoers_uid);
                   }
                   debug_return_bool(false);
               case SUDO_PATH_WORLD_WRITABLE:
                   if (sudoers_warnings) {
                       warningx(U_("%s is world writable"), path);
                   }
                   debug_return_bool(false);
               case SUDO_PATH_GROUP_WRITABLE:
                   if (sudoers_warnings) {
                       warningx(U_("%s is owned by gid %u, should be %u"),
                           path, (unsigned int) sb.st_gid,
                           (unsigned int) sudoers_gid);
                   }
                   debug_return_bool(false);
               default:
                   /* NOTREACHED */
                   debug_return_bool(false);
           }
         if (!(path = switch_dir(&istack[idepth], path))) {          if (!(path = switch_dir(&istack[idepth], path))) {
            /* switch_dir() called yyerror() for us */            /* switch_dir() called sudoerserror() for us */
            return FALSE;            debug_return_bool(false);
         }          }
        while ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {        while ((fp = open_sudoers(path, false, &keepopen)) == NULL) {
             /* Unable to open path in includedir, go to next one, if any. */              /* Unable to open path in includedir, go to next one, if any. */
             efree(path);              efree(path);
            if ((pl = istack[idepth].more) == NULL)            if ((pl = SLIST_FIRST(&istack[idepth].more)) == NULL)
                return FALSE;                debug_return_bool(false);
             SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
             path = pl->path;              path = pl->path;
             istack[idepth].more = pl->next;  
             efree(pl);              efree(pl);
         }          }
     } else {      } else {
        if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {        if ((fp = open_sudoers(path, true, &keepopen)) == NULL) {
            char *errbuf;            /* The error was already printed by open_sudoers() */
            if (asprintf(&errbuf, _("%s: %s"), path, strerror(errno)) != -1) {            sudoerserror(NULL);
                yyerror(errbuf);            debug_return_bool(false);
                free(errbuf); 
            } else { 
                yyerror(_("unable to allocate memory")); 
            } 
            return FALSE; 
         }          }
         istack[idepth].more = NULL;  
     }      }
     /* Push the old (current) file and open the new one. */      /* Push the old (current) file and open the new one. */
     istack[idepth].path = sudoers; /* push old path */      istack[idepth].path = sudoers; /* push old path */
Line 829  _push_include(char *path, int isdir) Line 969  _push_include(char *path, int isdir)
     idepth++;      idepth++;
     sudolineno = 1;      sudolineno = 1;
     sudoers = path;      sudoers = path;
    yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));    sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
   
    return TRUE;    debug_return_bool(true);
 }  }
   
static intstatic bool
 pop_include(void)  pop_include(void)
 {  {
     struct path_list *pl;      struct path_list *pl;
     FILE *fp;      FILE *fp;
       debug_decl(pop_include, SUDO_DEBUG_PARSER)
   
     if (idepth == 0)      if (idepth == 0)
        return FALSE;        debug_return_bool(false);
   
     if (!keepopen)      if (!keepopen)
         fclose(YY_CURRENT_BUFFER->yy_input_file);          fclose(YY_CURRENT_BUFFER->yy_input_file);
    yy_delete_buffer(YY_CURRENT_BUFFER);    sudoers_delete_buffer(YY_CURRENT_BUFFER);
     /* If we are in an include dir, move to the next file. */      /* If we are in an include dir, move to the next file. */
    while ((pl = istack[idepth - 1].more) != NULL) {    while ((pl = SLIST_FIRST(&istack[idepth - 1].more)) != NULL) {
        fp = open_sudoers(pl->path, FALSE, &keepopen);        SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
         fp = open_sudoers(pl->path, false, &keepopen);
         if (fp != NULL) {          if (fp != NULL) {
             istack[idepth - 1].more = pl->next;  
             efree(sudoers);              efree(sudoers);
             sudoers = pl->path;              sudoers = pl->path;
             sudolineno = 1;              sudolineno = 1;
            yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));            sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
             efree(pl);              efree(pl);
             break;              break;
         }          }
         /* Unable to open path in include dir, go to next one. */          /* Unable to open path in include dir, go to next one. */
         istack[idepth - 1].more = pl->next;  
         efree(pl->path);          efree(pl->path);
         efree(pl);          efree(pl);
     }      }
     /* If no path list, just pop the last dir on the stack. */      /* If no path list, just pop the last dir on the stack. */
     if (pl == NULL) {      if (pl == NULL) {
         idepth--;          idepth--;
        yy_switch_to_buffer(istack[idepth].bs);        sudoers_switch_to_buffer(istack[idepth].bs);
         efree(sudoers);          efree(sudoers);
         sudoers = istack[idepth].path;          sudoers = istack[idepth].path;
         sudolineno = istack[idepth].lineno;          sudolineno = istack[idepth].lineno;
         keepopen = istack[idepth].keepopen;          keepopen = istack[idepth].keepopen;
     }      }
    return TRUE;    debug_return_bool(true);
 }  }
   
 static char *  static char *
 parse_include(char *base)  parse_include(char *base)
 {  {
    char *cp, *ep, *path;    char *cp, *ep, *path, *pp;
    int len = 0, subst = 0;    int dirlen = 0, len = 0, subst = 0;
     size_t shost_len = 0;      size_t shost_len = 0;
       debug_decl(parse_include, SUDO_DEBUG_PARSER)
   
     /* Pull out path from #include line. */      /* Pull out path from #include line. */
     cp = base + sizeof("#include");      cp = base + sizeof("#include");
Line 898  parse_include(char *base) Line 1039  parse_include(char *base)
         ep++;          ep++;
     }      }
   
    /* Make a copy of path and return it. */    /* Relative paths are located in the same dir as the sudoers file. */
     if (*cp != '/') {
         char *dirend = strrchr(sudoers, '/');
         if (dirend != NULL)
             dirlen = (int)(dirend - sudoers) + 1;
     }
 
     /* Make a copy of the fully-qualified path and return it. */
     len += (int)(ep - cp);      len += (int)(ep - cp);
    if ((path = malloc(len + 1)) == NULL) {    path = pp = malloc(len + dirlen + 1);
        yyerror(_("unable to allocate memory"));    if (path == NULL) {
        return NULL;        warning(NULL);
         sudoerserror(NULL);
         debug_return_str(NULL);
     }      }
       if (dirlen) {
           memcpy(path, sudoers, dirlen);
           pp += dirlen;
       }
     if (subst) {      if (subst) {
         /* substitute for %h */          /* substitute for %h */
         char *pp = path;  
         while (cp < ep) {          while (cp < ep) {
             if (cp[0] == '%' && cp[1] == 'h') {              if (cp[0] == '%' && cp[1] == 'h') {
                 memcpy(pp, user_shost, shost_len);                  memcpy(pp, user_shost, shost_len);
Line 918  parse_include(char *base) Line 1071  parse_include(char *base)
         }          }
         *pp = '\0';          *pp = '\0';
     } else {      } else {
        memcpy(path, cp, len);        memcpy(pp, cp, len);
        path[len] = '\0';        pp[len] = '\0';
     }      }
   
     /* Push any excess characters (e.g. comment, newline) back to the lexer */      /* Push any excess characters (e.g. comment, newline) back to the lexer */
     if (*ep != '\0')      if (*ep != '\0')
         yyless((int)(ep - base));          yyless((int)(ep - base));
   
    return path;    debug_return_str(path);
 }  }
   
 #ifdef TRACELEXER  #ifdef TRACELEXER
static intint
 sudoers_trace_print(const char *msg)  sudoers_trace_print(const char *msg)
 {  {
     return fputs(msg, stderr);      return fputs(msg, stderr);
   }
   #else
   int
   sudoers_trace_print(const char *msg)
   {
       static bool initialized;
       static struct lbuf lbuf;
   
       if (!initialized) {
           initialized = true;
           lbuf_init(&lbuf, NULL, 0, NULL, 0);
       }
   
       lbuf_append(&lbuf, "%s", msg);
       /* XXX - assumes a final newline */
       if (strchr(msg, '\n') != NULL)
       {
           sudo_debug_printf2(NULL, NULL, 0, SUDO_DEBUG_PARSER|SUDO_DEBUG_DEBUG,
               "%s:%d %s", sudoers, sudolineno, lbuf.buf);
           lbuf.len = 0;
       }
       return 0;
 }  }
 #endif /* TRACELEXER */  #endif /* TRACELEXER */

Removed from v.1.1  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>