[BACK]Return to toke.l CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Diff for /src/usr.bin/sudo/Attic/toke.l between version 1.3 and 1.4

version 1.3, 2009/04/11 11:48:06 version 1.4, 2009/06/21 14:48:42
Line 1 
Line 1 
 %{  %{
 /*  /*
  * Copyright (c) 1996, 1998-2005, 2007-2008   * Copyright (c) 1996, 1998-2005, 2007-2009
  *      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 27 
Line 27 
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  #include <sys/param.h>
   #include <sys/stat.h>
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
 # include <stdlib.h>  # include <stdlib.h>
Line 49 
Line 50 
 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)  #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
 # include <malloc.h>  # include <malloc.h>
 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */  #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
   #ifdef HAVE_DIRENT_H
   # include <dirent.h>
   # define NAMLEN(dirent) strlen((dirent)->d_name)
   #else
   # define dirent direct
   # define NAMLEN(dirent) (dirent)->d_namlen
   # ifdef HAVE_SYS_NDIR_H
   #  include <sys/ndir.h>
   # endif
   # ifdef HAVE_SYS_DIR_H
   #  include <sys/dir.h>
   # endif
   # ifdef HAVE_NDIR_H
   #  include <ndir.h>
   # endif
   #endif
 #include <ctype.h>  #include <ctype.h>
 #include "sudo.h"  #include "sudo.h"
 #include "parse.h"  #include "parse.h"
 #include <gram.h>  #include <gram.h>
   
 #ifndef lint  #ifndef lint
 __unused static const char rcsid[] = "$Sudo: toke.l,v 1.29 2009/02/21 21:49:19 millert Exp $";  __unused static const char rcsid[] = "$Sudo: toke.l,v 1.37 2009/05/27 00:46:51 millert Exp $";
 #endif /* lint */  #endif /* lint */
   
 extern YYSTYPE yylval;  extern YYSTYPE yylval;
Line 69 
Line 86 
 static int _fill                __P((char *, int, int));  static int _fill                __P((char *, int, int));
 static int fill_cmnd            __P((char *, int));  static int fill_cmnd            __P((char *, int));
 static int fill_args            __P((char *, int, int));  static int fill_args            __P((char *, int, int));
 static int switch_buffer        __P((char *));  static int _push_include        __P((char *, int));
   static int pop_include          __P((void));
 static int ipv6_valid           __P((const char *s));  static int ipv6_valid           __P((const char *s));
 static char *parse_include      __P((char *));  static char *parse_include      __P((char *));
 extern void yyerror             __P((const char *));  extern void yyerror             __P((const char *));
   
 #define fill(a, b)              _fill(a, b, 0)  #define fill(a, b)              _fill(a, b, 0)
   
 #define push_include(_p)        (switch_buffer((_p)))  #define push_include(_p)        (_push_include((_p), FALSE))
 #define pop_include()           (switch_buffer(NULL))  #define push_includedir(_p)     (_push_include((_p), TRUE))
   
 /* realloc() to size + COMMANDARGINC to make room for command args */  /* realloc() to size + COMMANDARGINC to make room for command args */
 #define COMMANDARGINC   64  #define COMMANDARGINC   64
Line 227 
Line 245 
                                 yyterminate();                                  yyterminate();
                         }                          }
   
   <INITIAL>^#includedir[[:blank:]]+\/.*\n {
                               char *path;
   
                               if ((path = parse_include(yytext)) == NULL)
                                   yyterminate();
   
                               LEXTRACE("INCLUDEDIR\n");
   
                               /* Push current buffer and switch to include file */
                               if (!push_includedir(path))
                                   yyterminate();
                           }
   
 <INITIAL>^[[:blank:]]*Defaults([:@>\!]{WORD})? {  <INITIAL>^[[:blank:]]*Defaults([:@>\!]{WORD})? {
                             int n;                              int n;
                             for (n = 0; isblank((unsigned char)yytext[n]); n++)                              for (n = 0; isblank((unsigned char)yytext[n]); n++)
Line 316 
Line 347 
                             return(NETGROUP);                              return(NETGROUP);
                         }                          }
   
 \%{WORD}                {  \%:?{WORD}              {
                             /* UN*X group */                              /* UN*X group */
                             if (!fill(yytext, yyleng))                              if (!fill(yytext, yyleng))
                                 yyterminate();                                  yyterminate();
Line 412 
Line 443 
                             }                              }
                         }                       /* a pathname */                          }                       /* a pathname */
   
   <INITIAL,GOTDEFS>\"[^"\n]+\" {
                               /* a quoted user/group name */
                               if (!fill(yytext + 1, yyleng - 2))
                                   yyterminate();
                               switch (yytext[1]) {
                               case '%':
                                   LEXTRACE("USERGROUP ");
                                   return(USERGROUP);
                               case '+':
                                   LEXTRACE("NETGROUP ");
                                   return(NETGROUP);
                               default:
                                   LEXTRACE("WORD(4) ");
                                   return(WORD);
                               }
                           }
   
 <INITIAL,GOTDEFS>({ID}|{WORD}) {  <INITIAL,GOTDEFS>({ID}|{WORD}) {
                             /* a word */                              /* a word */
                             if (!fill(yytext, yyleng))                              if (!fill(yytext, yyleng))
                                 yyterminate();                                  yyterminate();
                             LEXTRACE("WORD(4) ");                              LEXTRACE("WORD(5) ");
                             return(WORD);                              return(WORD);
                         }                          }
   
Line 490 
Line 538 
                         }                          }
   
 %%  %%
   static unsigned char
   hexchar(s)
       const char *s;
   {
       int i;
       int result = 0;
   
       s += 2; /* skip \\x */
       for (i = 0; i < 2; i++) {
           switch (*s) {
           case 'A':
           case 'a':
               result += 10;
               break;
           case 'B':
           case 'b':
               result += 11;
               break;
           case 'C':
           case 'c':
               result += 12;
               break;
           case 'D':
           case 'd':
               result += 13;
               break;
           case 'E':
           case 'e':
               result += 14;
               break;
           case 'F':
           case 'f':
               result += 15;
               break;
           default:
               result += *s - '0';
               break;
           }
           if (i == 0) {
               result *= 16;
               s++;
           }
       }
       return((unsigned char)result);
   }
   
 static int  static int
 _fill(src, len, olen)  _fill(src, len, olen)
     char *src;      char *src;
     int len, olen;      int len, olen;
 {  {
     int i, j;  
     char *dst;      char *dst;
   
     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);      dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
Line 507 
Line 600 
   
     /* Copy the string and collapse any escaped characters. */      /* Copy the string and collapse any escaped characters. */
     dst += olen;      dst += olen;
     for (i = 0, j = 0; i < len; i++, j++) {      while (len--) {
         if (src[i] == '\\' && i != len - 1)          if (*src == '\\' && len) {
             dst[j] = src[++i];              if (src[1] == 'x' && len >= 3 &&
         else                  isxdigit((unsigned char) src[2]) &&
             dst[j] = src[i];                  isxdigit((unsigned char) src[3])) {
                   *dst++ = hexchar(src);
                   src += 4;
                   len -= 3;
               } else {
                   src++;
                   len--;
                   *dst++ = *src++;
               }
           } else {
               *dst++ = *src++;
           }
     }      }
     dst[j] = '\0';      *dst = '\0';
     return(TRUE);      return(TRUE);
 }  }
   
Line 605 
Line 709 
     return(TRUE);      return(TRUE);
 }  }
   
 struct sudoers_state {  struct path_list {
       char *path;
       struct path_list *next;
   };
   
   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 */
     int lineno;      int lineno;
       int keepopen;
 };  };
   
   static int
   pl_compare(v1, v2)
       const void *v1;
       const void *v2;
   {
       const struct path_list * const *p1 = v1;
       const struct path_list * const *p2 = v2;
   
       return(strcmp((*p1)->path, (*p2)->path));
   }
   
   static char *
   switch_dir(stack, dirpath)
       struct include_stack *stack;
       char *dirpath;
   {
       DIR *dir;
       int i, count = 0;
       char *path = NULL;
       struct dirent *dent;
       struct stat sb;
       struct path_list *pl, *first = NULL;
       struct path_list **sorted = NULL;
   
       if (!(dir = opendir(dirpath))) {
           yyerror(dirpath);
           return(FALSE);
       }
       while ((dent = readdir(dir))) {
           /* Ignore files that end in '~' or have a '.' in them. */
           if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
               || strchr(dent->d_name, '.') != NULL) {
               continue;
           }
           if (asprintf(&path, "%s/%s", dirpath, dent->d_name) == -1) {
               closedir(dir);
               goto bad;
           }
           if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
               efree(path);
               continue;
           }
           pl = malloc(sizeof(*pl));
           if (pl == NULL)
               goto bad;
           pl->path = path;
           pl->next = first;
           first = pl;
           count++;
       }
       closedir(dir);
   
       if (count == 0)
           goto done;
   
       /* Sort the list as an array. */
       sorted = malloc(sizeof(*sorted) * count);
       if (sorted == NULL)
           goto bad;
       pl = first;
       for (i = 0; i < count; i++) {
           sorted[i] = pl;
           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. */
       if (count) {
           path = first->path;
           pl = first->next;
           efree(first);
           stack->more = pl;
       } else {
           path = NULL;
       }
   done:
       efree(dirpath);
       return(path);
   bad:
       while (first != NULL) {
           pl = first;
           first = pl->next;
           free(pl->path);
           free(pl);
       }
       efree(sorted);
       efree(dirpath);
       efree(path);
       return(NULL);
   }
   
 #define MAX_SUDOERS_DEPTH       128  #define MAX_SUDOERS_DEPTH       128
 #define SUDOERS_STACK_INCREMENT 16  #define SUDOERS_STACK_INCREMENT 16
   
   static size_t istacksize, idepth;
   static struct include_stack *istack;
   static int keepopen;
   
   void
   init_lexer()
   {
       struct path_list *pl;
   
       while (idepth) {
           idepth--;
           while ((pl = istack[idepth].more) != NULL) {
               istack[idepth].more = pl->next;
               efree(pl->path);
               efree(pl);
           }
           efree(istack[idepth].path);
           if (!istack[idepth].keepopen)
               fclose(istack[idepth].bs->yy_input_file);
           yy_delete_buffer(istack[idepth].bs);
       }
       efree(istack);
       istack = NULL;
       istacksize = idepth = 0;
       keepopen = FALSE;
   }
   
 static int  static int
 switch_buffer(path)  _push_include(path, isdir)
     char *path;      char *path;
       int isdir;
 {  {
     static size_t stacksize, depth;  
     static struct sudoers_state *state;  
     static int keepopen;  
     FILE *fp;      FILE *fp;
   
     if (path != NULL) {      /* push current state onto stack */
         /* push current state */      if (idepth >= istacksize) {
         if (depth >= stacksize) {          if (idepth > MAX_SUDOERS_DEPTH) {
             if (depth > MAX_SUDOERS_DEPTH) {              yyerror("too many levels of includes");
                 yyerror("too many levels of includes");              return(FALSE);
                 return(FALSE);  
             }  
             stacksize += SUDOERS_STACK_INCREMENT;  
             state = (struct sudoers_state *) realloc(state,  
                 sizeof(state) * stacksize);  
             if (state == NULL) {  
                 yyerror("unable to allocate memory");  
                 return(FALSE);  
             }  
         }          }
         if ((fp = open_sudoers(path, &keepopen)) == NULL) {          istacksize += SUDOERS_STACK_INCREMENT;
           istack = (struct include_stack *) realloc(istack,
               sizeof(istack) * istacksize);
           if (istack == NULL) {
               yyerror("unable to allocate memory");
               return(FALSE);
           }
       }
       if (isdir) {
           if (!(path = switch_dir(&istack[idepth], path))) {
             yyerror(path);              yyerror(path);
             return(FALSE);              return(FALSE);
         }          }
         state[depth].bs = YY_CURRENT_BUFFER;          if ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {
         state[depth].path = sudoers;              yyerror(path);
         state[depth].lineno = sudolineno;              return(FALSE); /* XXX - just to go next one? */
         depth++;          }
       } else {
           if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {
               yyerror(path);
               return(FALSE);
           }
           istack[idepth].more = NULL;
       }
       /* Push the old (current) file and open the new one. */
       istack[idepth].path = sudoers; /* push old path */
       istack[idepth].bs = YY_CURRENT_BUFFER;
       istack[idepth].lineno = sudolineno;
       istack[idepth].keepopen = keepopen;
       idepth++;
       sudolineno = 1;
       sudoers = path;
       yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
   
       return(TRUE);
   }
   
   static int
   pop_include()
   {
       struct path_list *pl;
       FILE *fp;
   
       if (idepth == 0)
           return(FALSE);
   
       if (!keepopen)
           fclose(YY_CURRENT_BUFFER->yy_input_file);
       yy_delete_buffer(YY_CURRENT_BUFFER);
       keepopen = FALSE;
       if ((pl = istack[idepth - 1].more) != NULL) {
           /* Move to next file in the dir. */
           istack[idepth - 1].more = pl->next;
           if ((fp = open_sudoers(pl->path, FALSE, &keepopen)) == NULL) {
               yyerror(pl->path);
               return(FALSE); /* XXX - just to go next one? */
           }
           efree(sudoers);
           sudoers = pl->path;
         sudolineno = 1;          sudolineno = 1;
         sudoers = path;  
         yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));          yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
           efree(pl);
     } else {      } else {
         /* pop */          idepth--;
         if (depth == 0)          yy_switch_to_buffer(istack[idepth].bs);
             return(FALSE);  
         depth--;  
         if (!keepopen)  
             fclose(YY_CURRENT_BUFFER->yy_input_file);  
         yy_delete_buffer(YY_CURRENT_BUFFER);  
         yy_switch_to_buffer(state[depth].bs);  
         efree(sudoers);          efree(sudoers);
         sudoers = state[depth].path;          sudoers = istack[idepth].path;
         sudolineno = state[depth].lineno;          sudolineno = istack[idepth].lineno;
         keepopen = FALSE;  
     }      }
     return(TRUE);      return(TRUE);
 }  }
Line 676 
Line 945 
   
     /* Pull out path from #include line. */      /* Pull out path from #include line. */
     cp = base + sizeof("#include");      cp = base + sizeof("#include");
       if (*cp == 'i')
           cp += 3; /* includedir */
     while (isblank((unsigned char) *cp))      while (isblank((unsigned char) *cp))
         cp++;          cp++;
     ep = cp;      ep = cp;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4