version 1.10, 2003/04/19 21:57:17 |
version 1.11, 2004/09/28 15:10:51 |
|
|
/* |
/* |
* Copyright (c) 1996, 1998-2003 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com> |
* All rights reserved. |
|
* |
* |
* This code is derived from software contributed by Chris Jepeway. |
* Permission to use, copy, modify, and distribute this software for any |
|
* purpose with or without fee is hereby granted, provided that the above |
|
* copyright notice and this permission notice appear in all copies. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
* modification, are permitted provided that the following conditions |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
* are met: |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
* |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
* 1. Redistributions of source code must retain the above copyright |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
* notice, this list of conditions and the following disclaimer. |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
* 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. |
|
* |
|
* 4. Products derived from this software may not be called "Sudo" nor |
|
* may "Sudo" appear in their names without specific prior written |
|
* permission from the author. |
|
* |
|
* 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 |
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* |
|
|
#endif /* HAVE_FNMATCH */ |
#endif /* HAVE_FNMATCH */ |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: testsudoers.c,v 1.82 2003/04/16 00:42:10 millert Exp $"; |
static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88 2004/08/02 18:44:58 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
|
|
|
|
char *s; |
char *s; |
{ |
{ |
char *t; |
char *t; |
|
|
for (t = s; *t; t++) { |
for (t = s; *t; t++) { |
if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']') |
if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']') |
return(TRUE); |
return(TRUE); |
|
|
} |
} |
|
|
/* |
/* |
* Returns TRUE if cmnd matches, in the sudo sense, |
* Returns TRUE if user_cmnd matches, in the sudo sense, |
* the pathname in path; otherwise, return FALSE |
* the pathname in path; otherwise, return FALSE |
*/ |
*/ |
int |
int |
command_matches(cmnd, cmnd_args, path, sudoers_args) |
command_matches(path, sudoers_args) |
char *cmnd; |
|
char *cmnd_args; |
|
char *path; |
char *path; |
char *sudoers_args; |
char *sudoers_args; |
{ |
{ |
int clen, plen; |
int clen, plen; |
char *args; |
char *args; |
|
|
if (cmnd == NULL) |
if (user_cmnd == NULL) |
return(FALSE); |
return(FALSE); |
|
|
if ((args = strchr(path, ' '))) |
if ((args = strchr(path, ' '))) |
*args++ = '\0'; |
*args++ = '\0'; |
|
|
if (has_meta(path)) { |
if (has_meta(path)) { |
if (fnmatch(path, cmnd, FNM_PATHNAME)) |
if (fnmatch(path, user_cmnd, FNM_PATHNAME)) |
return(FALSE); |
return(FALSE); |
if (!sudoers_args) |
if (!sudoers_args) |
return(TRUE); |
return(TRUE); |
else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) |
else if (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) |
return(TRUE); |
return(TRUE); |
else if (sudoers_args) |
else if (sudoers_args) |
return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0)); |
return((fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)); |
else |
else |
return(FALSE); |
return(FALSE); |
} else { |
} else { |
plen = strlen(path); |
plen = strlen(path); |
if (path[plen - 1] != '/') { |
if (path[plen - 1] != '/') { |
if (strcmp(cmnd, path)) |
if (strcmp(user_cmnd, path)) |
return(FALSE); |
return(FALSE); |
if (!sudoers_args) |
if (!sudoers_args) |
return(TRUE); |
return(TRUE); |
else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) |
else if (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) |
return(TRUE); |
return(TRUE); |
else if (sudoers_args) |
else if (sudoers_args) |
return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0)); |
return((fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)); |
else |
else |
return(FALSE); |
return(FALSE); |
} |
} |
|
|
clen = strlen(cmnd); |
clen = strlen(user_cmnd); |
if (clen < plen + 1) |
if (clen < plen + 1) |
/* path cannot be the parent dir of cmnd */ |
/* path cannot be the parent dir of user_cmnd */ |
return(FALSE); |
return(FALSE); |
|
|
if (strchr(cmnd + plen + 1, '/') != NULL) |
if (strchr(user_cmnd + plen + 1, '/') != NULL) |
/* path could only be an anscestor of cmnd -- */ |
/* path could only be an anscestor of user_cmnd -- */ |
/* ignoring, of course, things like // & /./ */ |
/* ignoring, of course, things like // & /./ */ |
return(FALSE); |
return(FALSE); |
|
|
/* see whether path is the prefix of cmnd */ |
/* see whether path is the prefix of user_cmnd */ |
return((strncmp(cmnd, path, plen) == 0)); |
return((strncmp(user_cmnd, path, plen) == 0)); |
} |
} |
} |
} |
|
|
|
|
mask.s_addr <<= i; |
mask.s_addr <<= i; |
mask.s_addr = htonl(mask.s_addr); |
mask.s_addr = htonl(mask.s_addr); |
} |
} |
*(m - 1) = '/'; |
*(m - 1) = '/'; |
|
|
for (i = 0; i < num_interfaces; i++) |
for (i = 0; i < num_interfaces; i++) |
if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr) |
if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr) |
|
|
char *lhost; |
char *lhost; |
char *pattern; |
char *pattern; |
{ |
{ |
if (has_meta(pattern)) { |
if (has_meta(pattern)) { |
if (strchr(pattern, '.')) |
if (strchr(pattern, '.')) |
return(fnmatch(pattern, lhost, FNM_CASEFOLD)); |
return(fnmatch(pattern, lhost, FNM_CASEFOLD)); |
else |
else |
return(fnmatch(pattern, shost, FNM_CASEFOLD)); |
return(fnmatch(pattern, shost, FNM_CASEFOLD)); |
|
|
} |
} |
|
|
int |
int |
usergr_matches(group, user) |
userpw_matches(sudoers_user, user, pw) |
|
char *sudoers_user; |
|
char *user; |
|
struct passwd *pw; |
|
{ |
|
if (pw != NULL && *sudoers_user == '#') { |
|
uid_t uid = atoi(sudoers_user + 1); |
|
if (uid == pw->pw_uid) |
|
return(1); |
|
} |
|
return(strcmp(sudoers_user, user) == 0); |
|
} |
|
|
|
int |
|
usergr_matches(group, user, pw) |
char *group; |
char *group; |
char *user; |
char *user; |
|
struct passwd *pw; |
{ |
{ |
struct group *grp; |
struct group *grp; |
char **cur; |
char **cur; |
|
|
if (*group++ != '%') |
if (*group++ != '%') |
return(FALSE); |
return(FALSE); |
|
|
if ((grp = getgrnam(group)) == NULL) |
if ((grp = getgrnam(group)) == NULL) |
return(FALSE); |
return(FALSE); |
|
|
/* |
/* |
|
|
return; |
return; |
} |
} |
|
|
|
int |
|
set_runaspw(user) |
|
char *user; |
|
{ |
|
return(TRUE); |
|
} |
|
|
void |
void |
init_envtables() |
init_envtables() |
{ |
{ |
|
|
user_shost = user_host; |
user_shost = user_host; |
} |
} |
|
|
/* Fill in cmnd_args from NewArgv. */ |
/* Fill in user_args from NewArgv. */ |
if (NewArgc > 1) { |
if (NewArgc > 1) { |
char *to, **from; |
char *to, **from; |
size_t size, n; |
size_t size, n; |