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

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.5, 2014/06/15 16:12:54
Line 1 Line 1
 %{  %{
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2012 * 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 72 Line 76
 #include "toke.h"  #include "toke.h"
 #include <gram.h>  #include <gram.h>
 #include "lbuf.h"  #include "lbuf.h"
   #include "sha2.h"
 #include "secure_path.h"  #include "secure_path.h"
   
extern YYSTYPE yylval;int sudolineno;                 /* current sudoers line number. */
extern bool parse_error;int last_token;                 /* last token that was parsed. */
extern bool sudoers_warnings;char *sudoers;                  /* sudoers file being parsed. */
int sudolineno; 
int last_token; 
char *sudoers; 
   
 /* Default sudoers path, mode and owner (may be set via sudo.conf) */  /* Default sudoers path, mode and owner (may be set via sudo.conf) */
 const char *sudoers_file = _PATH_SUDOERS;  const char *sudoers_file = _PATH_SUDOERS;
Line 89  gid_t sudoers_gid = SUDOERS_GID; Line 91  gid_t sudoers_gid = SUDOERS_GID;
   
 static bool continued, sawspace;  static bool continued, sawspace;
 static int prev_state;  static int prev_state;
   static int digest_len;
   
 static bool _push_include(char *, bool);  static bool _push_include(char *, bool);
 static bool pop_include(void);  static bool pop_include(void);
Line 101  int (*trace_print)(const char *msg) = sudoers_trace_pr Line 104  int (*trace_print)(const char *msg) = sudoers_trace_pr
         return (n);             \          return (n);             \
 } while (0)  } while (0)
   
#define ECHO    ignore_result(fwrite(yytext, yyleng, 1, yyout))#define ECHO    ignore_result(fwrite(sudoerstext, sudoersleng, 1, sudoersout))
   
 #define push_include(_p)        (_push_include((_p), false))  #define push_include(_p)        (_push_include((_p), false))
 #define push_includedir(_p)     (_push_include((_p), true))  #define push_includedir(_p)     (_push_include((_p), true))
Line 122  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:]]* {
Line 140  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();
                             LEXRETURN(DEFVAR);                              LEXRETURN(DEFVAR);
                         }                          }
Line 169  DEFVAR   [a-z_]+ Line 174  DEFVAR   [a-z_]+
   
     \"                  {      \"                  {
                             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();
                             LEXRETURN(WORD);                              LEXRETURN(WORD);
                         }                          }
Line 193  DEFVAR   [a-z_]+ Line 198  DEFVAR   [a-z_]+
                             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 */
                                 LEXRETURN(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 */
                                         LEXRETURN(ERROR);                                          LEXRETURN(ERROR);
                                     }                                      }
                                     LEXTRACE("USERGROUP ");                                      LEXTRACE("USERGROUP ");
                                     LEXRETURN(USERGROUP);                                      LEXRETURN(USERGROUP);
                                 case '+':                                  case '+':
                                    if (yylval.string[1] == '\0') {                                    if (sudoerslval.string[1] == '\0') {
                                         LEXTRACE("ERROR "); /* empty netgroup */                                          LEXTRACE("ERROR "); /* empty netgroup */
                                         LEXRETURN(ERROR);                                          LEXRETURN(ERROR);
                                     }                                      }
Line 223  DEFVAR   [a-z_]+ Line 228  DEFVAR   [a-z_]+
   
     \\                  {      \\                  {
                             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 238  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;
                         }                          }
Line 246  DEFVAR   [a-z_]+ Line 251  DEFVAR   [a-z_]+
     \\[:\\,= \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;
                         }                          }
Line 259  DEFVAR   [a-z_]+ Line 264  DEFVAR   [a-z_]+
   
     [^#\\:, \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 */
 }  }
   
   <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 {  <INITIAL>^#include[[:blank:]]+.*\n {
                             char *path;                              char *path;
   
Line 273  DEFVAR   [a-z_]+ Line 312  DEFVAR   [a-z_]+
                                 LEXRETURN(ERROR);                                  LEXRETURN(ERROR);
                             }                              }
   
                            if ((path = parse_include(yytext)) == NULL)                            if ((path = parse_include(sudoerstext)) == NULL)
                                 yyterminate();                                  yyterminate();
   
                             LEXTRACE("INCLUDE\n");                              LEXTRACE("INCLUDE\n");
Line 291  DEFVAR   [a-z_]+ Line 330  DEFVAR   [a-z_]+
                                 LEXRETURN(ERROR);                                  LEXRETURN(ERROR);
                             }                              }
   
                            if ((path = parse_include(yytext)) == NULL)                            if ((path = parse_include(sudoerstext)) == NULL)
                                 yyterminate();                                  yyterminate();
   
                             LEXTRACE("INCLUDEDIR\n");                              LEXTRACE("INCLUDEDIR\n");
Line 313  DEFVAR   [a-z_]+ Line 352  DEFVAR   [a-z_]+
                                 LEXRETURN(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 352  DEFVAR   [a-z_]+ Line 391  DEFVAR   [a-z_]+
                                 LEXRETURN(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 ");
                                     LEXRETURN(HOSTALIAS);                                      LEXRETURN(HOSTALIAS);
Line 430  NOLOG_INPUT[[:blank:]]*: { Line 469  NOLOG_INPUT[[:blank:]]*: {
   
 \+{WORD}                {  \+{WORD}                {
                             /* netgroup */                              /* netgroup */
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NETGROUP ");                              LEXTRACE("NETGROUP ");
                             LEXRETURN(NETGROUP);                              LEXRETURN(NETGROUP);
Line 438  NOLOG_INPUT[[:blank:]]*: { Line 477  NOLOG_INPUT[[:blank:]]*: {
   
 \%:?({WORD}|{ID})       {  \%:?({WORD}|{ID})       {
                             /* group */                              /* group */
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("USERGROUP ");                              LEXTRACE("USERGROUP ");
                             LEXRETURN(USERGROUP);                              LEXRETURN(USERGROUP);
                         }                          }
   
 {IPV4ADDR}(\/{IPV4ADDR})? {  {IPV4ADDR}(\/{IPV4ADDR})? {
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                             LEXRETURN(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 ");
                             LEXRETURN(NTWKADDR);                              LEXRETURN(NTWKADDR);
                         }                          }
   
 {IPV6ADDR}(\/{IPV6ADDR})? {  {IPV6ADDR}(\/{IPV6ADDR})? {
                            if (!ipv6_valid(yytext)) {                            if (!ipv6_valid(sudoerstext)) {
                                 LEXTRACE("ERROR ");                                  LEXTRACE("ERROR ");
                                 LEXRETURN(ERROR);                                  LEXRETURN(ERROR);
                             }                              }
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                             LEXRETURN(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 ");
                                 LEXRETURN(ERROR);                                  LEXRETURN(ERROR);
                             }                              }
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("NTWKADDR ");                              LEXTRACE("NTWKADDR ");
                             LEXRETURN(NTWKADDR);                              LEXRETURN(NTWKADDR);
Line 523  ALL { Line 562  ALL {
   
 [[:upper:]][[:upper:][:digit:]_]* {  [[:upper:]][[:upper:][:digit:]_]* {
                         got_alias:                          got_alias:
                            if (!fill(yytext, yyleng))                            if (!fill(sudoerstext, sudoersleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("ALIAS ");                              LEXTRACE("ALIAS ");
                             LEXRETURN(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 ");
                             LEXRETURN(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();
                                 LEXRETURN(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) ");
                             LEXRETURN(WORD);                              LEXRETURN(WORD);
Line 600  sudoedit  { Line 668  sudoedit  {
                         }                       /* return ':' */                          }                       /* return ':' */
   
 <*>!+                   {  <*>!+                   {
                            if (yyleng & 1) {                            if (sudoersleng & 1) {
                                 LEXTRACE("!");                                  LEXTRACE("!");
                                 LEXRETURN('!'); /* return '!' */                                  LEXRETURN('!'); /* return '!' */
                             }                              }
Line 628  sudoedit  { Line 696  sudoedit  {
                             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");
                             LEXRETURN(COMMENT);                              LEXRETURN(COMMENT);
                         }                       /* comment, not uid/gid */                          }                       /* comment, not uid/gid */
Line 653  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;
     bool 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)      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 717  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);
     debug_return_str(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);
     debug_return_str(NULL);      debug_return_str(NULL);
Line 784  init_lexer(void) Line 857  init_lexer(void)
   
     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;
Line 815  _push_include(char *path, bool isdir) Line 888  _push_include(char *path, bool isdir)
   
     /* 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"));
             debug_return_bool(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);
             sudoerserror(NULL);
             debug_return_bool(false);              debug_return_bool(false);
         }          }
           istack = new_istack;
     }      }
       SLIST_INIT(&istack[idepth].more);
     if (isdir) {      if (isdir) {
         struct stat sb;          struct stat sb;
         switch (sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb)) {          switch (sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb)) {
Line 842  _push_include(char *path, bool isdir) Line 920  _push_include(char *path, bool isdir)
                 debug_return_bool(false);                  debug_return_bool(false);
             case SUDO_PATH_WRONG_OWNER:              case SUDO_PATH_WRONG_OWNER:
                 if (sudoers_warnings) {                  if (sudoers_warnings) {
                    warningx(_("%s is owned by uid %u, should be %u"),                       warningx(U_("%s is owned by uid %u, should be %u"),   
                         path, (unsigned int) sb.st_uid,                          path, (unsigned int) sb.st_uid,
                         (unsigned int) sudoers_uid);                          (unsigned int) sudoers_uid);
                 }                  }
                 debug_return_bool(false);                  debug_return_bool(false);
             case SUDO_PATH_WORLD_WRITABLE:              case SUDO_PATH_WORLD_WRITABLE:
                 if (sudoers_warnings) {                  if (sudoers_warnings) {
                    warningx(_("%s is world writable"), path);                    warningx(U_("%s is world writable"), path);
                 }                  }
                 debug_return_bool(false);                  debug_return_bool(false);
             case SUDO_PATH_GROUP_WRITABLE:              case SUDO_PATH_GROUP_WRITABLE:
                 if (sudoers_warnings) {                  if (sudoers_warnings) {
                    warningx(_("%s is owned by gid %u, should be %u"),                    warningx(U_("%s is owned by gid %u, should be %u"),
                         path, (unsigned int) sb.st_gid,                          path, (unsigned int) sb.st_gid,
                         (unsigned int) sudoers_gid);                          (unsigned int) sudoers_gid);
                 }                  }
Line 864  _push_include(char *path, bool isdir) Line 942  _push_include(char *path, bool isdir)
                 debug_return_bool(false);                  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 */
             debug_return_bool(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)
                 debug_return_bool(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) {
             /* The error was already printed by open_sudoers() */              /* The error was already printed by open_sudoers() */
            yyerror(NULL);            sudoerserror(NULL);
             debug_return_bool(false);              debug_return_bool(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 892  _push_include(char *path, bool isdir) Line 969  _push_include(char *path, bool 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));
   
     debug_return_bool(true);      debug_return_bool(true);
 }  }
Line 909  pop_include(void) Line 986  pop_include(void)
   
     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) {
         SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
         fp = open_sudoers(pl->path, false, &keepopen);          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;
Line 974  parse_include(char *base) Line 1050  parse_include(char *base)
     len += (int)(ep - cp);      len += (int)(ep - cp);
     path = pp = malloc(len + dirlen + 1);      path = pp = malloc(len + dirlen + 1);
     if (path == NULL) {      if (path == NULL) {
        yyerror(_("unable to allocate memory"));        warning(NULL);
         sudoerserror(NULL);
         debug_return_str(NULL);          debug_return_str(NULL);
     }      }
     if (dirlen) {      if (dirlen) {

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


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