More scaffolding for dealing with multiple sudoers files:

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
This commit is contained in:
Todd C. Miller
2004-09-28 18:31:24 +00:00
parent b99ad3ee2b
commit db2a97fd0a
4 changed files with 40 additions and 15 deletions

View File

@@ -96,7 +96,6 @@ extern FILE *yyin, *yyout;
* Prototypes * Prototypes
*/ */
static int has_meta __P((char *)); 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 * Look up the user in the sudoers file and check to see if they are
@@ -113,7 +112,7 @@ sudoers_lookup(pwflag)
yyout = stdout; yyout = stdout;
/* Allocate space for data structures in the parser. */ /* 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 pwcheck *could* be "all" or "any", keep more state. */
if (pwflag > 0) if (pwflag > 0)

View File

@@ -101,5 +101,6 @@ int hostname_matches __P((char *, char *, char *));
int netgr_matches __P((char *, char *, char *, char *)); int netgr_matches __P((char *, char *, char *, char *));
int userpw_matches __P((char *, char *, struct passwd *)); int userpw_matches __P((char *, char *, struct passwd *));
int usergr_matches __P((char *, char *, struct passwd *)); int usergr_matches __P((char *, char *, struct passwd *));
void init_parser __P((char *));
#endif /* _SUDO_PARSE_H */ #endif /* _SUDO_PARSE_H */

View File

@@ -62,6 +62,7 @@ static const char rcsid[] = "$Sudo$";
extern YYSTYPE yylval; extern YYSTYPE yylval;
extern int clearaliases; extern int clearaliases;
int sudolineno = 1; int sudolineno = 1;
char *sudoers;
static int sawspace = 0; static int sawspace = 0;
static int arg_len = 0; static int arg_len = 0;
static int arg_size = 0; static int arg_size = 0;
@@ -69,7 +70,7 @@ static int arg_size = 0;
static int fill __P((char *, int)); static int fill __P((char *, 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 buffer_frob __P((const char *)); static int buffer_frob __P((char *));
extern void reset_aliases __P((void)); extern void reset_aliases __P((void));
extern void yyerror __P((const char *)); extern void yyerror __P((const char *));
@@ -181,6 +182,7 @@ DEFVAR [a-z_]+
<INITIAL>^#include[ \t]+.*\n { <INITIAL>^#include[ \t]+.*\n {
char *cp, *ep; char *cp, *ep;
++sudolineno;
/* pull out path from #include line */ /* pull out path from #include line */
for (cp = yytext + 9; isspace(*cp); cp++) for (cp = yytext + 9; isspace(*cp); cp++)
continue; continue;
@@ -505,24 +507,35 @@ fill_args(s, len, addspace)
return(TRUE); return(TRUE);
} }
#define MAX_INCLUDE_DEPTH 128 struct sudoers_state {
int YY_BUFFER_STATE bs;
char *path;
int lineno;
};
#define MAX_SUDOERS_DEPTH 128
static int
buffer_frob(path) buffer_frob(path)
const char *path; char *path;
{ {
static size_t stacksize, depth; static size_t stacksize, depth;
static YY_BUFFER_STATE *bufstack; static struct sudoers_state *state;
FILE *fp; FILE *fp;
if (path != NULL) { if (path != NULL) {
/* push */ /* push current state */
if ((path = strdup(path)) == NULL) {
yyerror("unable to allocate memory");
return(FALSE);
}
if (depth >= stacksize) { if (depth >= stacksize) {
if (depth > MAX_INCLUDE_DEPTH) { if (depth > MAX_SUDOERS_DEPTH) {
yyerror("too many levels of includes"); yyerror("too many levels of includes");
return(FALSE); return(FALSE);
} }
stacksize += 16; stacksize += 16;
if ((bufstack = realloc(bufstack, stacksize)) == NULL) { if ((state = realloc(state, sizeof(state) * stacksize)) == NULL) {
yyerror("unable to allocate memory"); yyerror("unable to allocate memory");
return(FALSE); return(FALSE);
} }
@@ -531,15 +544,24 @@ buffer_frob(path)
yyerror(path); yyerror(path);
return(FALSE); 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)); yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
} else { } else {
/* pop */ /* pop */
if (depth == 0) if (depth == 0)
return(FALSE); return(FALSE);
depth--;
fclose(YY_CURRENT_BUFFER->yy_input_file); fclose(YY_CURRENT_BUFFER->yy_input_file);
yy_delete_buffer(YY_CURRENT_BUFFER); 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); return(TRUE);
} }

View File

@@ -78,6 +78,7 @@ static const char rcsid[] = "$Sudo$";
* Globals * Globals
*/ */
extern int sudolineno, parse_error; extern int sudolineno, parse_error;
extern char *sudoers;
int errorlineno = -1; int errorlineno = -1;
int clearaliases = TRUE; int clearaliases = TRUE;
int printmatches = FALSE; int printmatches = FALSE;
@@ -198,7 +199,6 @@ static void expand_ga_list __P((void));
static void expand_match_list __P((void)); static void expand_match_list __P((void));
static aliasinfo *find_alias __P((char *, int)); static aliasinfo *find_alias __P((char *, int));
static int more_aliases __P((void)); static int more_aliases __P((void));
void init_parser __P((void));
void yyerror __P((const char *)); void yyerror __P((const char *));
void void
@@ -210,7 +210,7 @@ yyerror(s)
errorlineno = sudolineno ? sudolineno - 1 : 0; errorlineno = sudolineno ? sudolineno - 1 : 0;
if (s && !quiet) { if (s && !quiet) {
#ifndef TRACELEXER #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); sudolineno ? sudolineno - 1 : 0);
#else #else
(void) fprintf(stderr, "<*> "); (void) fprintf(stderr, "<*> ");
@@ -1250,7 +1250,7 @@ expand_match_list()
* for various data structures. * for various data structures.
*/ */
void void
init_parser() init_parser(char *path)
{ {
/* Free up old data structures if we run the parser more than once. */ /* Free up old data structures if we run the parser more than once. */
@@ -1262,6 +1262,7 @@ init_parser()
used_runas = FALSE; used_runas = FALSE;
errorlineno = -1; errorlineno = -1;
sudolineno = 1; sudolineno = 1;
free(sudoers);
} }
/* Allocate space for the matching stack. */ /* Allocate space for the matching stack. */
@@ -1271,4 +1272,6 @@ init_parser()
/* Allocate space for the match list (for `sudo -l'). */ /* Allocate space for the match list (for `sudo -l'). */
if (printmatches == TRUE) if (printmatches == TRUE)
expand_match_list(); expand_match_list();
sudoers = estrdup(path);
} }