]> granicus.if.org Git - sudo/commitdiff
More scaffolding for dealing with multiple sudoers files:
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 28 Sep 2004 18:31:24 +0000 (18:31 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 28 Sep 2004 18:31:24 +0000 (18:31 +0000)
 o init_parser() now takes a path used to populate the sudoers global
 o the sudoers global is used to print the correct file in yyerror()
 o when switching to a new sudoers file, perserve old file name and line number

parse.c
parse.h
parse.lex
parse.yacc

diff --git a/parse.c b/parse.c
index f6abd1329c6dc419e775daab50faacdd0c0dfc8f..38c54a2162470094889d14291bc82ac873468f8a 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -96,7 +96,6 @@ extern FILE *yyin, *yyout;
  * Prototypes
  */
 static int has_meta    __P((char *));
-       void init_parser        __P((void));
 
 /*
  * Look up the user in the sudoers file and check to see if they are
@@ -113,7 +112,7 @@ sudoers_lookup(pwflag)
     yyout = stdout;
 
     /* Allocate space for data structures in the parser. */
-    init_parser();
+    init_parser(_PATH_SUDOERS);
 
     /* If pwcheck *could* be "all" or "any", keep more state. */
     if (pwflag > 0)
diff --git a/parse.h b/parse.h
index aa9cb55a5cc4d50011d465ca4f0d1f5511e17618..4f98e9117d1c6e5bd4e5ae6f64529e3433a35911 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -101,5 +101,6 @@ int hostname_matches        __P((char *, char *, char *));
 int netgr_matches      __P((char *, char *, char *, char *));
 int userpw_matches     __P((char *, char *, struct passwd *));
 int usergr_matches     __P((char *, char *, struct passwd *));
+void init_parser       __P((char *));
 
 #endif /* _SUDO_PARSE_H */
index bb959612387e2d71b2ea37a98dab2305d64352d1..c7f8683036165ad29cf7b3ed08c2d1bfc133bf9a 100644 (file)
--- a/parse.lex
+++ b/parse.lex
@@ -62,6 +62,7 @@ static const char rcsid[] = "$Sudo$";
 extern YYSTYPE yylval;
 extern int clearaliases;
 int sudolineno = 1;
+char *sudoers;
 static int sawspace = 0;
 static int arg_len = 0;
 static int arg_size = 0;
@@ -69,7 +70,7 @@ static int arg_size = 0;
 static int fill                        __P((char *, int));
 static int fill_cmnd           __P((char *, int));
 static int fill_args           __P((char *, int, int));
-static int buffer_frob         __P((const char *));
+static int buffer_frob         __P((char *));
 extern void reset_aliases      __P((void));
 extern void yyerror            __P((const char *));
 
@@ -181,6 +182,7 @@ DEFVAR                      [a-z_]+
 
 <INITIAL>^#include[ \t]+.*\n {
                            char *cp, *ep;
+                           ++sudolineno;
                            /* pull out path from #include line */
                            for (cp = yytext + 9; isspace(*cp); cp++)
                                continue;
@@ -505,24 +507,35 @@ fill_args(s, len, addspace)
     return(TRUE);
 }
 
-#define MAX_INCLUDE_DEPTH      128
-int
+struct sudoers_state {
+    YY_BUFFER_STATE bs;
+    char *path;
+    int lineno;
+};
+
+#define MAX_SUDOERS_DEPTH      128
+
+static int
 buffer_frob(path)
-    const char *path;
+    char *path;
 {
     static size_t stacksize, depth;
-    static YY_BUFFER_STATE *bufstack;
+    static struct sudoers_state *state;
     FILE *fp;
 
     if (path != NULL) {
-       /* push */
+       /* push current state */
+       if ((path = strdup(path)) == NULL) {
+           yyerror("unable to allocate memory");
+           return(FALSE);
+       }
        if (depth >= stacksize) {
-           if (depth > MAX_INCLUDE_DEPTH) {
+           if (depth > MAX_SUDOERS_DEPTH) {
                yyerror("too many levels of includes");
                return(FALSE);
            }
            stacksize += 16;
-           if ((bufstack = realloc(bufstack, stacksize)) == NULL) {
+           if ((state = realloc(state, sizeof(state) * stacksize)) == NULL) {
                yyerror("unable to allocate memory");
                return(FALSE);
            }
@@ -531,15 +544,24 @@ buffer_frob(path)
            yyerror(path);
            return(FALSE);
        }
-       bufstack[depth++] = YY_CURRENT_BUFFER;
+       state[depth].bs = YY_CURRENT_BUFFER;
+       state[depth].path = sudoers;
+       state[depth].lineno = sudolineno;
+       depth++;
+       sudolineno = 1;
+       sudoers = path;
        yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
     } else {
        /* pop */
        if (depth == 0)
            return(FALSE);
+       depth--;
        fclose(YY_CURRENT_BUFFER->yy_input_file);
        yy_delete_buffer(YY_CURRENT_BUFFER);
-       yy_switch_to_buffer(bufstack[--depth]);
+       yy_switch_to_buffer(state[depth].bs);
+       free(sudoers);
+       sudoers = state[depth].path;
+       sudolineno = state[depth].lineno;
     }
     return(TRUE);
 }
index 9349ff71e3a249655d6a6418a9c37473155e1b99..cb159e14198848cb6dfd1c3859dd2bb7fddda3a8 100644 (file)
@@ -78,6 +78,7 @@ static const char rcsid[] = "$Sudo$";
  * Globals
  */
 extern int sudolineno, parse_error;
+extern char *sudoers;
 int errorlineno = -1;
 int clearaliases = TRUE;
 int printmatches = FALSE;
@@ -198,7 +199,6 @@ static void expand_ga_list  __P((void));
 static void expand_match_list  __P((void));
 static aliasinfo *find_alias   __P((char *, int));
 static int  more_aliases       __P((void));
-       void init_parser                __P((void));
        void yyerror            __P((const char *));
 
 void
@@ -210,7 +210,7 @@ yyerror(s)
        errorlineno = sudolineno ? sudolineno - 1 : 0;
     if (s && !quiet) {
 #ifndef TRACELEXER
-       (void) fprintf(stderr, ">>> sudoers file: %s, line %d <<<\n", s,
+       (void) fprintf(stderr, ">>> %s: %s, line %d <<<\n", sudoers, s,
            sudolineno ? sudolineno - 1 : 0);
 #else
        (void) fprintf(stderr, "<*> ");
@@ -1250,7 +1250,7 @@ expand_match_list()
  * for various data structures.
  */
 void
-init_parser()
+init_parser(char *path)
 {
 
     /* Free up old data structures if we run the parser more than once. */
@@ -1262,6 +1262,7 @@ init_parser()
        used_runas = FALSE;
        errorlineno = -1;
        sudolineno = 1;
+       free(sudoers);
     }
 
     /* Allocate space for the matching stack. */
@@ -1271,4 +1272,6 @@ init_parser()
     /* Allocate space for the match list (for `sudo -l'). */
     if (printmatches == TRUE)
        expand_match_list();
+
+    sudoers = estrdup(path);
 }