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:
3
parse.c
3
parse.c
@@ -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)
|
||||||
|
1
parse.h
1
parse.h
@@ -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 */
|
||||||
|
42
parse.lex
42
parse.lex
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user