version 1.3, 2000/03/27 03:44:38 |
version 1.3.8.1, 2002/01/18 16:14:46 |
|
|
%{ |
%{ |
/* |
/* |
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com> |
* All rights reserved. |
* All rights reserved. |
* |
* |
* This code is derived from software contributed by Chris Jepeway |
* This code is derived from software contributed by Chris Jepeway |
|
|
|
|
#include "config.h" |
#include "config.h" |
|
|
|
#include <sys/types.h> |
|
#include <sys/param.h> |
|
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
#include <stdlib.h> |
# include <stdlib.h> |
|
# include <stddef.h> |
|
#else |
|
# ifdef HAVE_STDLIB_H |
|
# include <stdlib.h> |
|
# endif |
#endif /* STDC_HEADERS */ |
#endif /* STDC_HEADERS */ |
#ifdef HAVE_UNISTD_H |
|
#include <unistd.h> |
|
#endif /* HAVE_UNISTD_H */ |
|
#ifdef HAVE_STRING_H |
#ifdef HAVE_STRING_H |
#include <string.h> |
# include <string.h> |
|
#else |
|
# ifdef HAVE_STRINGS_H |
|
# include <strings.h> |
|
# endif |
#endif /* HAVE_STRING_H */ |
#endif /* HAVE_STRING_H */ |
#ifdef HAVE_STRINGS_H |
#ifdef HAVE_UNISTD_H |
#include <strings.h> |
# include <unistd.h> |
#endif /* HAVE_STRINGS_H */ |
#endif /* HAVE_UNISTD_H */ |
#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 */ |
#include <ctype.h> |
#include <ctype.h> |
#include <sys/types.h> |
|
#include <sys/param.h> |
|
#include "sudo.h" |
#include "sudo.h" |
#include "parse.h" |
#include "parse.h" |
#include "sudo.tab.h" |
#include <sudo.tab.h> |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: parse.lex,v 1.111 2000/03/23 04:38:20 millert Exp $"; |
static const char rcsid[] = "$Sudo: parse.lex,v 1.118 2002/01/15 18:16:31 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
#undef yywrap /* guard against a yywrap macro */ |
#undef yywrap /* guard against a yywrap macro */ |
|
|
OCTET (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]) |
OCTET (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]) |
DOTTEDQUAD {OCTET}(\.{OCTET}){3} |
DOTTEDQUAD {OCTET}(\.{OCTET}){3} |
HOSTNAME [[:alnum:]_-]+ |
HOSTNAME [[:alnum:]_-]+ |
WORD ([^@!=:,\(\) \t\n\\]|\\[^\n])+ |
WORD ([^#@!=:,\(\) \t\n\\]|\\[^\n])+ |
|
ENVAR ([^#!=, \t\n\\]|\\[^\n])([^#=, \t\n\\]|\\[^\n])* |
|
DEFVAR [a-z_]+ |
|
|
%s GOTCMND |
/* XXX - convert GOTRUNAS to exclusive state (GOTDEFS cannot be) */ |
%s GOTRUNAS |
%s GOTRUNAS |
%s GOTDEFS |
%s GOTDEFS |
|
%x GOTCMND |
|
%x STARTDEFS |
|
%x INDEFS |
|
|
%% |
%% |
[ \t]+ { /* throw away space/tabs */ |
<GOTDEFS>[[:blank:]]+ BEGIN STARTDEFS; |
sawspace = TRUE; /* but remember for fill_args */ |
|
|
<STARTDEFS>{DEFVAR} { |
|
BEGIN INDEFS; |
|
LEXTRACE("DEFVAR "); |
|
fill(yytext, yyleng); |
|
return(DEFVAR); |
} |
} |
|
|
\\[ \t]*\n { |
<INDEFS>{ |
sawspace = TRUE; /* remember for fill_args */ |
, { |
++sudolineno; |
BEGIN STARTDEFS; |
LEXTRACE("\n\t"); |
LEXTRACE(", "); |
} /* throw away EOL after \ */ |
return(','); |
|
} /* return ',' */ |
|
|
<GOTCMND>\\[:\,=\\ \t] { |
= { |
LEXTRACE("QUOTEDCHAR "); |
LEXTRACE("= "); |
fill_args(yytext + 1, 1, sawspace); |
return('='); |
sawspace = FALSE; |
} /* return '=' */ |
} |
|
|
|
<GOTDEFS>\"([^\"]|\\\")+\" { |
\+= { |
|
LEXTRACE("+= "); |
|
return('+'); |
|
} /* return '+' */ |
|
|
|
-= { |
|
LEXTRACE("-= "); |
|
return('-'); |
|
} /* return '-' */ |
|
|
|
\"([^\"]|\\\")+\" { |
LEXTRACE("WORD(1) "); |
LEXTRACE("WORD(1) "); |
fill(yytext + 1, yyleng - 2); |
fill(yytext + 1, yyleng - 2); |
return(WORD); |
return(WORD); |
} |
} |
|
|
<GOTDEFS>(#.*)?\n { |
{ENVAR} { |
BEGIN INITIAL; |
LEXTRACE("WORD(2) "); |
++sudolineno; |
fill(yytext, yyleng); |
LEXTRACE("\n"); |
return(WORD); |
return(COMMENT); |
|
} |
} |
|
} |
|
|
<GOTCMND>[:\,=\n] { |
<GOTCMND>{ |
|
\\[:\\,= \t#] { |
|
LEXTRACE("QUOTEDCHAR "); |
|
fill_args(yytext + 1, 1, sawspace); |
|
sawspace = FALSE; |
|
} |
|
|
|
[#:\,=\n] { |
BEGIN INITIAL; |
BEGIN INITIAL; |
unput(*yytext); |
unput(*yytext); |
return(COMMAND); |
return(COMMAND); |
} /* end of command line args */ |
} /* end of command line args */ |
|
|
\n { |
[^\\:, \t\n]+ { |
++sudolineno; |
|
LEXTRACE("\n"); |
|
BEGIN INITIAL; |
|
return(COMMENT); |
|
} /* return newline */ |
|
|
|
<INITIAL>#.*\n { |
|
++sudolineno; |
|
LEXTRACE("\n"); |
|
return(COMMENT); |
|
} /* return comments */ |
|
|
|
<GOTCMND>[^\\:, \t\n]+ { |
|
LEXTRACE("ARG "); |
LEXTRACE("ARG "); |
fill_args(yytext, yyleng, sawspace); |
fill_args(yytext, yyleng, sawspace); |
sawspace = FALSE; |
sawspace = FALSE; |
} /* a command line arg */ |
} /* a command line arg */ |
|
} |
|
|
, { |
<INITIAL>^Defaults[:@]? { |
LEXTRACE(", "); |
BEGIN GOTDEFS; |
return(','); |
switch (yytext[8]) { |
} /* return ',' */ |
case ':': |
|
LEXTRACE("DEFAULTS_USER "); |
|
return(DEFAULTS_USER); |
|
case '@': |
|
LEXTRACE("DEFAULTS_HOST "); |
|
return(DEFAULTS_HOST); |
|
default: |
|
LEXTRACE("DEFAULTS "); |
|
return(DEFAULTS); |
|
} |
|
} |
|
|
!+ { |
<INITIAL>^(Host|Cmnd|User|Runas)_Alias { |
if (yyleng % 2 == 1) |
fill(yytext, yyleng); |
return('!'); /* return '!' */ |
switch (*yytext) { |
|
case 'H': |
|
LEXTRACE("HOSTALIAS "); |
|
return(HOSTALIAS); |
|
case 'C': |
|
LEXTRACE("CMNDALIAS "); |
|
return(CMNDALIAS); |
|
case 'U': |
|
LEXTRACE("USERALIAS "); |
|
return(USERALIAS); |
|
case 'R': |
|
LEXTRACE("RUNASALIAS "); |
|
BEGIN GOTRUNAS; |
|
return(RUNASALIAS); |
|
} |
} |
} |
|
|
= { |
|
LEXTRACE("= "); |
|
return('='); |
|
} /* return '=' */ |
|
|
|
: { |
|
LEXTRACE(": "); |
|
return(':'); |
|
} /* return ':' */ |
|
|
|
NOPASSWD[[:blank:]]*: { |
NOPASSWD[[:blank:]]*: { |
/* cmnd does not require passwd for this user */ |
/* cmnd does not require passwd for this user */ |
LEXTRACE("NOPASSWD "); |
LEXTRACE("NOPASSWD "); |
|
|
return (RUNAS); |
return (RUNAS); |
} |
} |
|
|
<GOTRUNAS>[[:upper:]][[:upper:][:digit:]_]* { |
[[:upper:]][[:upper:][:digit:]_]* { |
/* Runas_Alias user can run command as or ALL */ |
|
if (strcmp(yytext, "ALL") == 0) { |
if (strcmp(yytext, "ALL") == 0) { |
LEXTRACE("ALL "); |
LEXTRACE("ALL "); |
return(ALL); |
return(ALL); |
|
|
} |
} |
} |
} |
|
|
<GOTRUNAS>#?{WORD} { |
<GOTRUNAS>(#[0-9-]+|{WORD}) { |
/* username/uid that user can run command as */ |
/* username/uid that user can run command as */ |
fill(yytext, yyleng); |
fill(yytext, yyleng); |
LEXTRACE("WORD(2) "); |
LEXTRACE("WORD(3) "); |
return(WORD); |
return(WORD); |
} |
} |
|
|
|
|
BEGIN INITIAL; |
BEGIN INITIAL; |
} |
} |
|
|
[[:upper:]][[:upper:][:digit:]_]* { |
\/(\\[\,:= \t#]|[^\,:=\\ \t\n#])+ { |
if (strcmp(yytext, "ALL") == 0) { |
|
LEXTRACE("ALL "); |
|
return(ALL); |
|
} else { |
|
fill(yytext, yyleng); |
|
LEXTRACE("ALIAS "); |
|
return(ALIAS); |
|
} |
|
} |
|
|
|
<GOTDEFS>{WORD} { |
|
LEXTRACE("WORD(3) "); |
|
fill(yytext, yyleng); |
|
return(WORD); |
|
} |
|
|
|
<INITIAL>^Defaults[:@]? { |
|
BEGIN GOTDEFS; |
|
if (yyleng == 9) { |
|
switch (yytext[8]) { |
|
case ':' : |
|
LEXTRACE("DEFAULTS_USER "); |
|
return(DEFAULTS_USER); |
|
case '@' : |
|
LEXTRACE("DEFAULTS_HOST "); |
|
return(DEFAULTS_HOST); |
|
} |
|
} else { |
|
LEXTRACE("DEFAULTS "); |
|
return(DEFAULTS); |
|
} |
|
} |
|
|
|
<INITIAL>^(Host|Cmnd|User|Runas)_Alias { |
|
fill(yytext, yyleng); |
|
if (*yytext == 'H') { |
|
LEXTRACE("HOSTALIAS "); |
|
return(HOSTALIAS); |
|
} |
|
if (*yytext == 'C') { |
|
LEXTRACE("CMNDALIAS "); |
|
return(CMNDALIAS); |
|
} |
|
if (*yytext == 'U') { |
|
LEXTRACE("USERALIAS "); |
|
return(USERALIAS); |
|
} |
|
if (*yytext == 'R') { |
|
LEXTRACE("RUNASALIAS "); |
|
BEGIN GOTRUNAS; |
|
return(RUNASALIAS); |
|
} |
|
} |
|
|
|
\/[^\,:=\\ \t\n#]+ { |
|
/* directories can't have args... */ |
/* directories can't have args... */ |
if (yytext[yyleng - 1] == '/') { |
if (yytext[yyleng - 1] == '/') { |
LEXTRACE("COMMAND "); |
LEXTRACE("COMMAND "); |
|
|
} |
} |
} /* a pathname */ |
} /* a pathname */ |
|
|
<INITIAL>{WORD} { |
<INITIAL,GOTDEFS>{WORD} { |
/* a word */ |
/* a word */ |
fill(yytext, yyleng); |
fill(yytext, yyleng); |
LEXTRACE("WORD(4) "); |
LEXTRACE("WORD(4) "); |
return(WORD); |
return(WORD); |
} |
} |
|
|
. { |
, { |
|
LEXTRACE(", "); |
|
return(','); |
|
} /* return ',' */ |
|
|
|
= { |
|
LEXTRACE("= "); |
|
return('='); |
|
} /* return '=' */ |
|
|
|
: { |
|
LEXTRACE(": "); |
|
return(':'); |
|
} /* return ':' */ |
|
|
|
<*>!+ { |
|
if (yyleng % 2 == 1) |
|
return('!'); /* return '!' */ |
|
} |
|
|
|
<*>\n { |
|
BEGIN INITIAL; |
|
++sudolineno; |
|
LEXTRACE("\n"); |
|
return(COMMENT); |
|
} /* return newline */ |
|
|
|
<*>[[:blank:]]+ { /* throw away space/tabs */ |
|
sawspace = TRUE; /* but remember for fill_args */ |
|
} |
|
|
|
<*>\\[[:blank:]]*\n { |
|
sawspace = TRUE; /* remember for fill_args */ |
|
++sudolineno; |
|
LEXTRACE("\n\t"); |
|
} /* throw away EOL after \ */ |
|
|
|
<INITIAL,STARTDEFS,INDEFS>#.*\n { |
|
BEGIN INITIAL; |
|
++sudolineno; |
|
LEXTRACE("\n"); |
|
return(COMMENT); |
|
} /* return comments */ |
|
|
|
<*>. { |
LEXTRACE("ERROR "); |
LEXTRACE("ERROR "); |
return(ERROR); |
return(ERROR); |
} /* parse error */ |
} /* parse error */ |
|
|
if (yylval.command.cmnd == NULL) |
if (yylval.command.cmnd == NULL) |
yyerror("unable to allocate memory"); |
yyerror("unable to allocate memory"); |
|
|
/* copy the string and NULL-terminate it */ |
/* copy the string and NULL-terminate it (escapes handled by fnmatch) */ |
(void) strncpy(yylval.command.cmnd, s, len); |
(void) strncpy(yylval.command.cmnd, s, len); |
yylval.command.cmnd[len] = '\0'; |
yylval.command.cmnd[len] = '\0'; |
|
|