version 1.11, 2005/06/19 22:00:08 |
version 1.12, 2007/07/26 16:10:16 |
|
|
%{ |
%{ |
/* |
/* |
* Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1996, 1998-2004, 2007 |
|
* 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 |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
* list_matches() can format things the way it wants. |
* list_matches() can format things the way it wants. |
*/ |
*/ |
|
|
#include "config.h" |
#include <config.h> |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#include <sys/param.h> |
|
|
#endif /* HAVE_LSEARCH */ |
#endif /* HAVE_LSEARCH */ |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: parse.yacc,v 1.204 2004/08/11 18:29:10 millert Exp $"; |
__unused static const char rcsid[] = "$Sudo: parse.yacc,v 1.204.2.5 2007/07/09 21:53:01 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* |
/* |
|
|
match[top].runas = UNSPEC; \ |
match[top].runas = UNSPEC; \ |
match[top].nopass = def_authenticate ? UNSPEC : TRUE; \ |
match[top].nopass = def_authenticate ? UNSPEC : TRUE; \ |
match[top].noexec = def_noexec ? TRUE : UNSPEC; \ |
match[top].noexec = def_noexec ? TRUE : UNSPEC; \ |
|
match[top].setenv = def_setenv ? TRUE : UNSPEC; \ |
top++; \ |
top++; \ |
} while (0) |
} while (0) |
|
|
|
|
match[top].runas = match[top-1].runas; \ |
match[top].runas = match[top-1].runas; \ |
match[top].nopass = match[top-1].nopass; \ |
match[top].nopass = match[top-1].nopass; \ |
match[top].noexec = match[top-1].noexec; \ |
match[top].noexec = match[top-1].noexec; \ |
|
match[top].setenv = match[top-1].setenv; \ |
top++; \ |
top++; \ |
} while (0) |
} while (0) |
|
|
|
|
%token <tok> PASSWD /* passwd req for command (default) */ |
%token <tok> PASSWD /* passwd req for command (default) */ |
%token <tok> NOEXEC /* preload dummy execve() for cmnd */ |
%token <tok> NOEXEC /* preload dummy execve() for cmnd */ |
%token <tok> EXEC /* don't preload dummy execve() */ |
%token <tok> EXEC /* don't preload dummy execve() */ |
|
%token <tok> SETENV /* user may set environment for cmnd */ |
|
%token <tok> NOSETENV /* user may not set environment */ |
%token <tok> ALL /* ALL keyword */ |
%token <tok> ALL /* ALL keyword */ |
%token <tok> COMMENT /* comment and/or carriage return */ |
%token <tok> COMMENT /* comment and/or carriage return */ |
%token <tok> HOSTALIAS /* Host_Alias keyword */ |
%token <tok> HOSTALIAS /* Host_Alias keyword */ |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($1); |
efree($1); |
} |
} |
| '!' DEFVAR { |
| '!' DEFVAR { |
if (defaults_matches == TRUE && |
if (defaults_matches == TRUE && |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($2); |
efree($2); |
} |
} |
| DEFVAR '=' WORD { |
| DEFVAR '=' WORD { |
if (defaults_matches == TRUE && |
if (defaults_matches == TRUE && |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($1); |
efree($1); |
free($3); |
efree($3); |
} |
} |
| DEFVAR '+' WORD { |
| DEFVAR '+' WORD { |
if (defaults_matches == TRUE && |
if (defaults_matches == TRUE && |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($1); |
efree($1); |
free($3); |
efree($3); |
} |
} |
| DEFVAR '-' WORD { |
| DEFVAR '-' WORD { |
if (defaults_matches == TRUE && |
if (defaults_matches == TRUE && |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($1); |
efree($1); |
free($3); |
efree($3); |
} |
} |
; |
; |
|
|
|
|
runas_matches = UNSPEC; |
runas_matches = UNSPEC; |
no_passwd = def_authenticate ? UNSPEC : TRUE; |
no_passwd = def_authenticate ? UNSPEC : TRUE; |
no_execve = def_noexec ? TRUE : UNSPEC; |
no_execve = def_noexec ? TRUE : UNSPEC; |
|
setenv_ok = def_setenv ? TRUE : UNSPEC; |
} |
} |
; |
; |
|
|
|
|
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| NETGROUP { |
| NETGROUP { |
if (netgr_matches($1, user_host, user_shost, NULL)) |
if (netgr_matches($1, user_host, user_shost, NULL)) |
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| WORD { |
| WORD { |
if (hostname_matches(user_shost, user_host, $1) == 0) |
if (hostname_matches(user_shost, user_host, $1) == 0) |
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| ALIAS { |
| ALIAS { |
aliasinfo *aip = find_alias($1, HOST_ALIAS); |
aliasinfo *aip = find_alias($1, HOST_ALIAS); |
|
|
} |
} |
$$ = NOMATCH; |
$$ = NOMATCH; |
} |
} |
free($1); |
efree($1); |
} |
} |
; |
; |
|
|
|
|
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
used_runas = TRUE; |
used_runas = TRUE; |
} |
} |
| USERGROUP { |
| USERGROUP { |
|
|
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
used_runas = TRUE; |
used_runas = TRUE; |
} |
} |
| NETGROUP { |
| NETGROUP { |
|
|
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
used_runas = TRUE; |
used_runas = TRUE; |
} |
} |
| ALIAS { |
| ALIAS { |
|
|
} |
} |
$$ = NOMATCH; |
$$ = NOMATCH; |
} |
} |
free($1); |
efree($1); |
used_runas = TRUE; |
used_runas = TRUE; |
} |
} |
| ALL { |
| ALL { |
|
|
; |
; |
|
|
cmndtag : /* empty */ { |
cmndtag : /* empty */ { |
/* Inherit {NOPASSWD,PASSWD,NOEXEC,EXEC} status. */ |
/* Inherit {NO,}{PASSWD,EXEC,SETENV} status. */ |
if (printmatches == TRUE && host_matches == TRUE && |
if (printmatches == TRUE && host_matches == TRUE && |
user_matches == TRUE) { |
user_matches == TRUE) { |
if (no_passwd == TRUE) |
if (no_passwd == TRUE) |
|
|
cm_list[cm_list_len].noexecve = TRUE; |
cm_list[cm_list_len].noexecve = TRUE; |
else |
else |
cm_list[cm_list_len].noexecve = FALSE; |
cm_list[cm_list_len].noexecve = FALSE; |
|
if (setenv_ok == TRUE) |
|
cm_list[cm_list_len].setenv = TRUE; |
|
else |
|
cm_list[cm_list_len].setenv = FALSE; |
} |
} |
} |
} |
| cmndtag NOPASSWD { |
| cmndtag NOPASSWD { |
|
|
user_matches == TRUE) |
user_matches == TRUE) |
cm_list[cm_list_len].noexecve = FALSE; |
cm_list[cm_list_len].noexecve = FALSE; |
} |
} |
|
| cmndtag SETENV { |
|
setenv_ok = TRUE; |
|
if (printmatches == TRUE && host_matches == TRUE && |
|
user_matches == TRUE) |
|
cm_list[cm_list_len].setenv = TRUE; |
|
} |
|
| cmndtag NOSETENV { |
|
setenv_ok = FALSE; |
|
if (printmatches == TRUE && host_matches == TRUE && |
|
user_matches == TRUE) |
|
cm_list[cm_list_len].setenv = FALSE; |
|
} |
; |
; |
|
|
cmnd : ALL { |
cmnd : ALL { |
|
|
} |
} |
} |
} |
|
|
|
efree(safe_cmnd); |
|
safe_cmnd = NULL; |
$$ = TRUE; |
$$ = TRUE; |
} |
} |
| ALIAS { |
| ALIAS { |
|
|
} |
} |
$$ = NOMATCH; |
$$ = NOMATCH; |
} |
} |
free($1); |
efree($1); |
} |
} |
| COMMAND { |
| COMMAND { |
if (printmatches == TRUE) { |
if (printmatches == TRUE) { |
|
|
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
|
|
free($1.cmnd); |
efree($1.cmnd); |
if ($1.args) |
efree($1.args); |
free($1.args); |
|
} |
} |
; |
; |
|
|
|
|
YYERROR; |
YYERROR; |
} |
} |
pop; |
pop; |
free($1); |
efree($1); |
|
|
if (printmatches == TRUE) |
if (printmatches == TRUE) |
in_alias = FALSE; |
in_alias = FALSE; |
|
|
yyerror(NULL); |
yyerror(NULL); |
YYERROR; |
YYERROR; |
} |
} |
free($1); |
efree($1); |
|
|
if (printmatches == TRUE) |
if (printmatches == TRUE) |
in_alias = FALSE; |
in_alias = FALSE; |
|
|
YYERROR; |
YYERROR; |
} |
} |
pop; |
pop; |
free($1); |
efree($1); |
} |
} |
; |
; |
|
|
|
|
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| USERGROUP { |
| USERGROUP { |
if (usergr_matches($1, user_name, sudo_user.pw)) |
if (usergr_matches($1, user_name, sudo_user.pw)) |
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| NETGROUP { |
| NETGROUP { |
if (netgr_matches($1, NULL, NULL, user_name)) |
if (netgr_matches($1, NULL, NULL, user_name)) |
$$ = TRUE; |
$$ = TRUE; |
else |
else |
$$ = NOMATCH; |
$$ = NOMATCH; |
free($1); |
efree($1); |
} |
} |
| ALIAS { |
| ALIAS { |
aliasinfo *aip = find_alias($1, USER_ALIAS); |
aliasinfo *aip = find_alias($1, USER_ALIAS); |
|
|
} |
} |
$$ = NOMATCH; |
$$ = NOMATCH; |
} |
} |
free($1); |
efree($1); |
} |
} |
| ALL { |
| ALL { |
$$ = TRUE; |
$$ = TRUE; |
|
|
else if (cm_list[count].nopasswd == FALSE && !def_authenticate) |
else if (cm_list[count].nopasswd == FALSE && !def_authenticate) |
(void) fputs("PASSWD: ", stdout); |
(void) fputs("PASSWD: ", stdout); |
|
|
|
/* Is setenv enabled? */ |
|
if (cm_list[count].setenv == TRUE && !def_setenv) |
|
(void) fputs("SETENV: ", stdout); |
|
else if (cm_list[count].setenv == FALSE && def_setenv) |
|
(void) fputs("NOSETENV: ", stdout); |
|
|
/* Print the actual command or expanded Cmnd_Alias. */ |
/* Print the actual command or expanded Cmnd_Alias. */ |
key.alias = cm_list[count].cmnd; |
key.alias = cm_list[count].cmnd; |
key.type = CMND_ALIAS; |
key.type = CMND_ALIAS; |
|
|
|
|
/* Be nice and free up space now that we are done. */ |
/* Be nice and free up space now that we are done. */ |
for (count = 0; count < ga_list_len; count++) { |
for (count = 0; count < ga_list_len; count++) { |
free(ga_list[count].alias); |
efree(ga_list[count].alias); |
free(ga_list[count].entries); |
efree(ga_list[count].entries); |
} |
} |
free(ga_list); |
efree(ga_list); |
ga_list = NULL; |
ga_list = NULL; |
|
|
for (count = 0; count < cm_list_len; count++) { |
for (count = 0; count < cm_list_len; count++) { |
free(cm_list[count].runas); |
efree(cm_list[count].runas); |
free(cm_list[count].cmnd); |
efree(cm_list[count].cmnd); |
} |
} |
free(cm_list); |
efree(cm_list); |
cm_list = NULL; |
cm_list = NULL; |
cm_list_len = 0; |
cm_list_len = 0; |
cm_list_size = 0; |
cm_list_size = 0; |
|
|
|
|
if (aliases) { |
if (aliases) { |
for (n = 0; n < naliases; n++) |
for (n = 0; n < naliases; n++) |
free(aliases[n].name); |
efree(aliases[n].name); |
free(aliases); |
efree(aliases); |
aliases = NULL; |
aliases = NULL; |
} |
} |
naliases = nslots = 0; |
naliases = nslots = 0; |
|
|
cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL; |
cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL; |
cm_list[cm_list_len].nopasswd = FALSE; |
cm_list[cm_list_len].nopasswd = FALSE; |
cm_list[cm_list_len].noexecve = FALSE; |
cm_list[cm_list_len].noexecve = FALSE; |
|
cm_list[cm_list_len].setenv = FALSE; |
} |
} |
|
|
/* |
/* |
|
|
|
|
/* 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. */ |
if (match) { |
if (match) { |
free(match); |
efree(match); |
match = NULL; |
match = NULL; |
top = 0; |
top = 0; |
parse_error = FALSE; |
parse_error = FALSE; |