BSD-style copyright. Move parser-specific defines and structs into parse.h + other cosmetic changes
This commit is contained in:
99
parse.c
99
parse.c
@@ -1,29 +1,31 @@
|
|||||||
/*
|
/*
|
||||||
* CU sudo version 1.6
|
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
* All rights reserved.
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 1, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* Please send bugs, changes, problems to sudo-bugs@courtesan.com
|
|
||||||
*
|
|
||||||
*******************************************************************
|
|
||||||
*
|
|
||||||
* parse.c -- sudo parser frontend and comparison routines.
|
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed by Chris Jepeway
|
* This code is derived from software contributed by Chris Jepeway
|
||||||
* <jepeway@cs.utk.edu>
|
* <jepeway@cs.utk.edu>.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -78,6 +80,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
#include "parse.h"
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
@@ -89,7 +92,6 @@ static const char rcsid[] = "$Sudo$";
|
|||||||
*/
|
*/
|
||||||
int parse_error = FALSE;
|
int parse_error = FALSE;
|
||||||
extern FILE *yyin, *yyout;
|
extern FILE *yyin, *yyout;
|
||||||
extern int printmatches;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
@@ -107,10 +109,10 @@ validate(check_cmnd)
|
|||||||
{
|
{
|
||||||
int return_code;
|
int return_code;
|
||||||
|
|
||||||
/* become sudoers file owner */
|
/* Become sudoers file owner */
|
||||||
set_perms(PERM_SUDOERS, 0);
|
set_perms(PERM_SUDOERS, 0);
|
||||||
|
|
||||||
/* we opened _PATH_SUDO_SUDOERS in check_sudoers() so just rewind it */
|
/* We opened _PATH_SUDO_SUDOERS in check_sudoers() so just rewind it. */
|
||||||
rewind(sudoers_fp);
|
rewind(sudoers_fp);
|
||||||
yyin = sudoers_fp;
|
yyin = sudoers_fp;
|
||||||
yyout = stdout;
|
yyout = stdout;
|
||||||
@@ -192,23 +194,20 @@ validate(check_cmnd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we popped everything off the stack =>
|
* We popped everything off the stack and the user was mentioned, but
|
||||||
* user was mentioned, but not explicitly
|
* not explicitly granted nor denied access.
|
||||||
* granted nor denied access => say no
|
|
||||||
*/
|
*/
|
||||||
return(VALIDATE_NOT_OK);
|
return(VALIDATE_NOT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
|
* If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
|
||||||
* otherwise, return TRUE if cmnd names one of the inodes in path.
|
* otherwise, return TRUE if cmnd names one of the inodes in path.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
command_matches(cmnd, user_args, path, sudoers_args)
|
command_matches(cmnd, cmnd_args, path, sudoers_args)
|
||||||
char *cmnd;
|
char *cmnd;
|
||||||
char *user_args;
|
char *cmnd_args;
|
||||||
char *path;
|
char *path;
|
||||||
char *sudoers_args;
|
char *sudoers_args;
|
||||||
{
|
{
|
||||||
@@ -251,12 +250,12 @@ command_matches(cmnd, user_args, path, sudoers_args)
|
|||||||
if (fnmatch(path, cmnd, FNM_PATHNAME) != 0)
|
if (fnmatch(path, cmnd, FNM_PATHNAME) != 0)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
if (!sudoers_args ||
|
if (!sudoers_args ||
|
||||||
(!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
|
(!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
|
||||||
(sudoers_args && fnmatch(sudoers_args, user_args ? user_args : "",
|
(sudoers_args && fnmatch(sudoers_args, cmnd_args ? cmnd_args : "",
|
||||||
0) == 0)) {
|
0) == 0)) {
|
||||||
if (cmnd_safe)
|
if (safe_cmnd)
|
||||||
free(cmnd_safe);
|
free(safe_cmnd);
|
||||||
cmnd_safe = estrdup(cmnd);
|
safe_cmnd = estrdup(user_cmnd);
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
} else
|
} else
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
@@ -285,12 +284,12 @@ command_matches(cmnd, user_args, path, sudoers_args)
|
|||||||
if (cst.st_dev != pst.st_dev || cst.st_ino != pst.st_ino)
|
if (cst.st_dev != pst.st_dev || cst.st_ino != pst.st_ino)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
if (!sudoers_args ||
|
if (!sudoers_args ||
|
||||||
(!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
|
(!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
|
||||||
(sudoers_args &&
|
(sudoers_args &&
|
||||||
fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
|
fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0)) {
|
||||||
if (cmnd_safe)
|
if (safe_cmnd)
|
||||||
free(cmnd_safe);
|
free(safe_cmnd);
|
||||||
cmnd_safe = estrdup(path);
|
safe_cmnd = estrdup(path);
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
} else
|
} else
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
@@ -314,9 +313,9 @@ command_matches(cmnd, user_args, path, sudoers_args)
|
|||||||
if (strcmp(cmnd_base, dent->d_name) != 0 || stat(buf, &pst) == -1)
|
if (strcmp(cmnd_base, dent->d_name) != 0 || stat(buf, &pst) == -1)
|
||||||
continue;
|
continue;
|
||||||
if (cst.st_dev == pst.st_dev && cst.st_ino == pst.st_ino) {
|
if (cst.st_dev == pst.st_dev && cst.st_ino == pst.st_ino) {
|
||||||
if (cmnd_safe)
|
if (safe_cmnd)
|
||||||
free(cmnd_safe);
|
free(safe_cmnd);
|
||||||
cmnd_safe = estrdup(buf);
|
safe_cmnd = estrdup(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,8 +325,6 @@ command_matches(cmnd, user_args, path, sudoers_args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE if "n" is one of our ip addresses or if
|
* Returns TRUE if "n" is one of our ip addresses or if
|
||||||
* "n" is a network that we are on, else returns FALSE.
|
* "n" is a network that we are on, else returns FALSE.
|
||||||
@@ -363,8 +360,6 @@ addr_matches(n)
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE if the given user belongs to the named group,
|
* Returns TRUE if the given user belongs to the named group,
|
||||||
* else returns FALSE.
|
* else returns FALSE.
|
||||||
@@ -402,8 +397,6 @@ usergr_matches(group, user)
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE if "host" and "user" belong to the netgroup "netgr",
|
* Returns TRUE if "host" and "user" belong to the netgroup "netgr",
|
||||||
* else return FALSE. Either of "host" or "user" may be NULL
|
* else return FALSE. Either of "host" or "user" may be NULL
|
||||||
@@ -443,8 +436,6 @@ netgr_matches(netgr, host, user)
|
|||||||
#endif /* HAVE_INNETGR */
|
#endif /* HAVE_INNETGR */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE if "s" has shell meta characters in it,
|
* Returns TRUE if "s" has shell meta characters in it,
|
||||||
* else returns FALSE.
|
* else returns FALSE.
|
||||||
|
94
parse.h
Normal file
94
parse.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Sudo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SUDO_PARSE_H
|
||||||
|
#define _SUDO_PARSE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data structure used in parsing sudoers;
|
||||||
|
* top of stack values are the ones that
|
||||||
|
* apply when parsing is done & can be
|
||||||
|
* accessed by *_matches macros
|
||||||
|
*/
|
||||||
|
#define STACKINCREMENT (32)
|
||||||
|
struct matchstack {
|
||||||
|
int user;
|
||||||
|
int cmnd;
|
||||||
|
int host;
|
||||||
|
int runas;
|
||||||
|
int nopass;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data structure describing a command in the
|
||||||
|
* sudoers file.
|
||||||
|
*/
|
||||||
|
struct sudo_command {
|
||||||
|
char *cmnd;
|
||||||
|
char *args;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define user_matches (match[top-1].user)
|
||||||
|
#define user_matched (match[top].user)
|
||||||
|
#define cmnd_matches (match[top-1].cmnd)
|
||||||
|
#define cmnd_matched (match[top].cmnd)
|
||||||
|
#define host_matches (match[top-1].host)
|
||||||
|
#define host_matched (match[top].host)
|
||||||
|
#define runas_matches (match[top-1].runas)
|
||||||
|
#define runas_matched (match[top].runas)
|
||||||
|
#define no_passwd (match[top-1].nopass)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure containing command matches if "sudo -l" is used.
|
||||||
|
*/
|
||||||
|
struct command_match {
|
||||||
|
char *runas;
|
||||||
|
size_t runas_len;
|
||||||
|
size_t runas_size;
|
||||||
|
char *cmnd;
|
||||||
|
size_t cmnd_len;
|
||||||
|
size_t cmnd_size;
|
||||||
|
int nopasswd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure containing Cmnd_Alias's if "sudo -l" is used.
|
||||||
|
*/
|
||||||
|
struct generic_alias {
|
||||||
|
char *alias;
|
||||||
|
char *entries;
|
||||||
|
size_t entries_size;
|
||||||
|
size_t entries_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The matching stack and number of entries on it. */
|
||||||
|
extern struct matchstack *match;
|
||||||
|
extern int top;
|
||||||
|
|
||||||
|
#endif /* _SUDO_PARSE_H */
|
53
parse.lex
53
parse.lex
@@ -1,30 +1,33 @@
|
|||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* CU sudo version 1.6
|
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
* All rights reserved.
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 1, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* Please send bugs, changes, problems to sudo-bugs@courtesan.com
|
|
||||||
*
|
|
||||||
*******************************************************************
|
|
||||||
*
|
|
||||||
* parse.lex -- lexigraphical analyzer for sudo.
|
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed by Chris Jepeway
|
* This code is derived from software contributed by Chris Jepeway
|
||||||
* <jepeway@cs.utk.edu>
|
* <jepeway@cs.utk.edu>
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed by Chris Jepeway
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -45,6 +48,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
#include "parse.h"
|
||||||
#include "sudo.tab.h"
|
#include "sudo.tab.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
@@ -281,7 +285,6 @@ fill(s, len)
|
|||||||
yylval.string[len] = '\0';
|
yylval.string[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_cmnd(s, len)
|
fill_cmnd(s, len)
|
||||||
char *s;
|
char *s;
|
||||||
@@ -300,7 +303,6 @@ fill_cmnd(s, len)
|
|||||||
yylval.command.args = NULL;
|
yylval.command.args = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_args(s, len, addspace)
|
fill_args(s, len, addspace)
|
||||||
char *s;
|
char *s;
|
||||||
@@ -348,7 +350,6 @@ fill_args(s, len, addspace)
|
|||||||
arg_len = new_len;
|
arg_len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
yywrap()
|
yywrap()
|
||||||
{
|
{
|
||||||
@@ -356,7 +357,7 @@ yywrap()
|
|||||||
YY_NEW_FILE;
|
YY_NEW_FILE;
|
||||||
#endif /* YY_NEW_FILE */
|
#endif /* YY_NEW_FILE */
|
||||||
|
|
||||||
/* don't reset the aliases if called by testsudoers */
|
/* Don't reset the aliases if called by testsudoers. */
|
||||||
if (clearaliases)
|
if (clearaliases)
|
||||||
reset_aliases();
|
reset_aliases();
|
||||||
|
|
||||||
|
197
parse.yacc
197
parse.yacc
@@ -1,31 +1,32 @@
|
|||||||
%{
|
%{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CU sudo version 1.6
|
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
* All rights reserved.
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 1, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* Please send bugs, changes, problems to sudo-bugs@courtesan.com
|
|
||||||
*
|
|
||||||
*******************************************************************
|
|
||||||
*
|
|
||||||
* parse.yacc -- yacc parser and alias manipulation routines for sudo.
|
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed by Chris Jepeway
|
* This code is derived from software contributed by Chris Jepeway
|
||||||
* <jepeway@cs.utk.edu>
|
* <jepeway@cs.utk.edu>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
#endif /* HAVE_LSEARCH */
|
#endif /* HAVE_LSEARCH */
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
#include "parse.h"
|
||||||
|
|
||||||
#ifndef HAVE_LSEARCH
|
#ifndef HAVE_LSEARCH
|
||||||
#include "emul/search.h"
|
#include "emul/search.h"
|
||||||
@@ -157,7 +159,7 @@ void
|
|||||||
yyerror(s)
|
yyerror(s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
/* save the line the first error occured on */
|
/* Save the line the first error occured on. */
|
||||||
if (errorlineno == -1)
|
if (errorlineno == -1)
|
||||||
errorlineno = sudolineno ? sudolineno - 1 : 0;
|
errorlineno = sudolineno ? sudolineno - 1 : 0;
|
||||||
#ifndef TRACELEXER
|
#ifndef TRACELEXER
|
||||||
@@ -177,7 +179,6 @@ yyerror(s)
|
|||||||
int tok;
|
int tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%start file /* special start symbol */
|
%start file /* special start symbol */
|
||||||
%token <string> ALIAS /* an UPPERCASE alias name */
|
%token <string> ALIAS /* an UPPERCASE alias name */
|
||||||
%token <string> NTWKADDR /* w.x.y.z */
|
%token <string> NTWKADDR /* w.x.y.z */
|
||||||
@@ -263,24 +264,24 @@ hostspec : ALL {
|
|||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| NETGROUP {
|
| NETGROUP {
|
||||||
if (netgr_matches($1, host, NULL))
|
if (netgr_matches($1, user_host, NULL))
|
||||||
host_matches = TRUE;
|
host_matches = TRUE;
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| NAME {
|
| NAME {
|
||||||
if (strcasecmp(shost, $1) == 0)
|
if (strcasecmp(user_shost, $1) == 0)
|
||||||
host_matches = TRUE;
|
host_matches = TRUE;
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| FQHOST {
|
| FQHOST {
|
||||||
if (strcasecmp(host, $1) == 0)
|
if (strcasecmp(user_host, $1) == 0)
|
||||||
host_matches = TRUE;
|
host_matches = TRUE;
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| ALIAS {
|
| ALIAS {
|
||||||
/* could be an all-caps hostname */
|
/* could be an all-caps hostname */
|
||||||
if (find_alias($1, HOST_ALIAS) == TRUE ||
|
if (find_alias($1, HOST_ALIAS) == TRUE ||
|
||||||
strcasecmp(shost, $1) == 0)
|
strcasecmp(user_shost, $1) == 0)
|
||||||
host_matches = TRUE;
|
host_matches = TRUE;
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
@@ -340,7 +341,7 @@ runasspec : /* empty */ {
|
|||||||
*/
|
*/
|
||||||
if (runas_matches == -1)
|
if (runas_matches == -1)
|
||||||
runas_matches =
|
runas_matches =
|
||||||
(strcmp(RUNAS_DEFAULT, runas_user) == 0);
|
(strcmp(RUNAS_DEFAULT, user_runas) == 0);
|
||||||
}
|
}
|
||||||
| RUNAS runaslist { ; }
|
| RUNAS runaslist { ; }
|
||||||
;
|
;
|
||||||
@@ -378,7 +379,7 @@ oprunasuser : runasuser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runasuser : NAME {
|
runasuser : NAME {
|
||||||
runas_matches = (strcmp($1, runas_user) == 0);
|
runas_matches = (strcmp($1, user_runas) == 0);
|
||||||
if (printmatches == TRUE && in_alias == TRUE)
|
if (printmatches == TRUE && in_alias == TRUE)
|
||||||
append($1, &ga_list[ga_list_len-1].entries,
|
append($1, &ga_list[ga_list_len-1].entries,
|
||||||
&ga_list[ga_list_len-1].entries_len,
|
&ga_list[ga_list_len-1].entries_len,
|
||||||
@@ -391,7 +392,7 @@ runasuser : NAME {
|
|||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| USERGROUP {
|
| USERGROUP {
|
||||||
runas_matches = usergr_matches($1, runas_user);
|
runas_matches = usergr_matches($1, user_runas);
|
||||||
if (printmatches == TRUE && in_alias == TRUE)
|
if (printmatches == TRUE && in_alias == TRUE)
|
||||||
append($1, &ga_list[ga_list_len-1].entries,
|
append($1, &ga_list[ga_list_len-1].entries,
|
||||||
&ga_list[ga_list_len-1].entries_len,
|
&ga_list[ga_list_len-1].entries_len,
|
||||||
@@ -405,7 +406,7 @@ runasuser : NAME {
|
|||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
| NETGROUP {
|
| NETGROUP {
|
||||||
runas_matches = netgr_matches($1, NULL, runas_user);
|
runas_matches = netgr_matches($1, NULL, user_runas);
|
||||||
if (printmatches == TRUE && in_alias == TRUE)
|
if (printmatches == TRUE && in_alias == TRUE)
|
||||||
append($1, &ga_list[ga_list_len-1].entries,
|
append($1, &ga_list[ga_list_len-1].entries,
|
||||||
&ga_list[ga_list_len-1].entries_len,
|
&ga_list[ga_list_len-1].entries_len,
|
||||||
@@ -421,7 +422,7 @@ runasuser : NAME {
|
|||||||
| ALIAS {
|
| ALIAS {
|
||||||
/* could be an all-caps username */
|
/* could be an all-caps username */
|
||||||
if (find_alias($1, RUNAS_ALIAS) == TRUE ||
|
if (find_alias($1, RUNAS_ALIAS) == TRUE ||
|
||||||
strcmp($1, runas_user) == 0)
|
strcmp($1, user_runas) == 0)
|
||||||
runas_matches = TRUE;
|
runas_matches = TRUE;
|
||||||
else
|
else
|
||||||
runas_matches = FALSE;
|
runas_matches = FALSE;
|
||||||
@@ -482,9 +483,9 @@ cmnd : ALL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$$ = cmnd_matches = TRUE;
|
$$ = cmnd_matches = TRUE;
|
||||||
if (cmnd_safe)
|
if (safe_cmnd)
|
||||||
free(cmnd_safe);
|
free(safe_cmnd);
|
||||||
cmnd_safe = estrdup(cmnd);
|
safe_cmnd = estrdup(user_cmnd);
|
||||||
}
|
}
|
||||||
| ALIAS {
|
| ALIAS {
|
||||||
if (printmatches == TRUE && in_alias == TRUE) {
|
if (printmatches == TRUE && in_alias == TRUE) {
|
||||||
@@ -528,8 +529,8 @@ cmnd : ALL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if NewArgc > 1 pass ptr to 1st arg, else NULL */
|
/* if NewArgc > 1 pass ptr to 1st arg, else NULL */
|
||||||
if (command_matches(cmnd, (NewArgc > 1) ?
|
if (command_matches(user_cmnd, (NewArgc > 1) ?
|
||||||
cmnd_args : NULL, $1.cmnd, $1.args)) {
|
user_args : NULL, $1.cmnd, $1.args)) {
|
||||||
cmnd_matches = TRUE;
|
cmnd_matches = TRUE;
|
||||||
$$ = TRUE;
|
$$ = TRUE;
|
||||||
}
|
}
|
||||||
@@ -665,7 +666,6 @@ user : NAME {
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int type;
|
int type;
|
||||||
char name[BUFSIZ];
|
char name[BUFSIZ];
|
||||||
@@ -677,13 +677,9 @@ size_t naliases = 0;
|
|||||||
size_t nslots = 0;
|
size_t nslots = 0;
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/*
|
||||||
*
|
* Compare two aliasinfo structures, strcmp() style.
|
||||||
* aliascmp()
|
|
||||||
*
|
|
||||||
* This function compares two aliasinfo structures.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
aliascmp(a1, a2)
|
aliascmp(a1, a2)
|
||||||
const VOID *a1, *a2;
|
const VOID *a1, *a2;
|
||||||
@@ -700,14 +696,9 @@ aliascmp(a1, a2)
|
|||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Compare two generic_alias structures, strcmp() style.
|
||||||
*
|
|
||||||
* genaliascmp()
|
|
||||||
*
|
|
||||||
* This function compares two generic_alias structures.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
genaliascmp(entry, key)
|
genaliascmp(entry, key)
|
||||||
const VOID *entry, *key;
|
const VOID *entry, *key;
|
||||||
@@ -719,14 +710,9 @@ genaliascmp(entry, key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/*
|
||||||
*
|
* Adds the named alias of the specified type to the aliases list.
|
||||||
* add_alias()
|
|
||||||
*
|
|
||||||
* This function adds the named alias of the specified type to the
|
|
||||||
* aliases list.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
add_alias(alias, type)
|
add_alias(alias, type)
|
||||||
char *alias;
|
char *alias;
|
||||||
@@ -766,14 +752,9 @@ add_alias(alias, type)
|
|||||||
return(ok);
|
return(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Searches for the named alias of the specified type.
|
||||||
*
|
|
||||||
* find_alias()
|
|
||||||
*
|
|
||||||
* This function searches for the named alias of the specified type.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_alias(alias, type)
|
find_alias(alias, type)
|
||||||
char *alias;
|
char *alias;
|
||||||
@@ -788,17 +769,13 @@ find_alias(alias, type)
|
|||||||
sizeof(ai), aliascmp) != NULL);
|
sizeof(ai), aliascmp) != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Allocates more space for the aliases list.
|
||||||
*
|
|
||||||
* more_aliases()
|
|
||||||
*
|
|
||||||
* This function allocates more space for the aliases list.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
more_aliases()
|
more_aliases()
|
||||||
{
|
{
|
||||||
|
|
||||||
nslots += MOREALIASES;
|
nslots += MOREALIASES;
|
||||||
if (nslots == MOREALIASES)
|
if (nslots == MOREALIASES)
|
||||||
aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
|
aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
|
||||||
@@ -808,14 +785,9 @@ more_aliases()
|
|||||||
return(aliases != NULL);
|
return(aliases != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Lists the contents of the aliases list.
|
||||||
*
|
|
||||||
* dumpaliases()
|
|
||||||
*
|
|
||||||
* This function lists the contents of the aliases list.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dumpaliases()
|
dumpaliases()
|
||||||
{
|
{
|
||||||
@@ -843,15 +815,9 @@ dumpaliases()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Lists the contents of cm_list and ga_list for `sudo -l'.
|
||||||
*
|
|
||||||
* list_matches()
|
|
||||||
*
|
|
||||||
* This function lists the contents of cm_list and ga_list for
|
|
||||||
* `sudo -l'.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
list_matches()
|
list_matches()
|
||||||
{
|
{
|
||||||
@@ -914,15 +880,9 @@ list_matches()
|
|||||||
cm_list_size = 0;
|
cm_list_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Appends a source string to the destination, optionally prefixing a separator.
|
||||||
*
|
|
||||||
* append()
|
|
||||||
*
|
|
||||||
* This function appends a source string to the destination prefixing
|
|
||||||
* a separator if one is given.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append(src, dstp, dst_len, dst_size, separator)
|
append(src, dstp, dst_len, dst_size, separator)
|
||||||
char *src, **dstp;
|
char *src, **dstp;
|
||||||
@@ -958,18 +918,13 @@ append(src, dstp, dst_len, dst_size, separator)
|
|||||||
*dst_len += src_len;
|
*dst_len += src_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Frees up space used by the aliases list and resets the associated counters.
|
||||||
*
|
|
||||||
* reset_aliases()
|
|
||||||
*
|
|
||||||
* This function frees up space used by the aliases list and resets
|
|
||||||
* the associated counters.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
reset_aliases()
|
reset_aliases()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (aliases) {
|
if (aliases) {
|
||||||
free(aliases);
|
free(aliases);
|
||||||
aliases = NULL;
|
aliases = NULL;
|
||||||
@@ -977,17 +932,13 @@ reset_aliases()
|
|||||||
naliases = nslots = 0;
|
naliases = nslots = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Increments ga_list_len, allocating more space as necessary.
|
||||||
*
|
|
||||||
* expand_ga_list()
|
|
||||||
*
|
|
||||||
* This function increments ga_list_len, allocating more space as necessary.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
expand_ga_list()
|
expand_ga_list()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (++ga_list_len >= ga_list_size) {
|
if (++ga_list_len >= ga_list_size) {
|
||||||
while ((ga_list_size += STACKINCREMENT) < ga_list_len)
|
while ((ga_list_size += STACKINCREMENT) < ga_list_len)
|
||||||
;
|
;
|
||||||
@@ -998,17 +949,13 @@ expand_ga_list()
|
|||||||
ga_list[ga_list_len - 1].entries = NULL;
|
ga_list[ga_list_len - 1].entries = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Increments cm_list_len, allocating more space as necessary.
|
||||||
*
|
|
||||||
* expand_match_list()
|
|
||||||
*
|
|
||||||
* This function increments cm_list_len, allocating more space as necessary.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
expand_match_list()
|
expand_match_list()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (++cm_list_len >= cm_list_size) {
|
if (++cm_list_len >= cm_list_size) {
|
||||||
while ((cm_list_size += STACKINCREMENT) < cm_list_len)
|
while ((cm_list_size += STACKINCREMENT) < cm_list_len)
|
||||||
;
|
;
|
||||||
@@ -1022,18 +969,14 @@ expand_match_list()
|
|||||||
cm_list[cm_list_len].nopasswd = FALSE;
|
cm_list[cm_list_len].nopasswd = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
* Frees up spaced used by a previous parser run and allocates new space
|
||||||
*
|
* for various data structures.
|
||||||
* init_parser()
|
|
||||||
*
|
|
||||||
* This function frees up spaced used by a previous parse and
|
|
||||||
* allocates new space for various data structures.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
init_parser()
|
init_parser()
|
||||||
{
|
{
|
||||||
|
|
||||||
/* 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);
|
free(match);
|
||||||
|
Reference in New Issue
Block a user