version 1.5, 2000/08/13 21:58:52 |
version 1.5.4.1, 2002/01/18 17:20:23 |
|
|
/* |
/* |
* Copyright (c) 1996, 1998-2000 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1996, 1998-2002 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 <sys/stat.h> |
#include <stdio.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 */ |
#ifdef HAVE_FNMATCH |
#ifdef HAVE_FNMATCH |
# include <fnmatch.h> |
# include <fnmatch.h> |
#endif /* HAVE_FNMATCH_H */ |
#endif /* HAVE_FNMATCH_H */ |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <grp.h> |
#include <grp.h> |
#include <sys/param.h> |
|
#include <sys/types.h> |
|
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
#include <netdb.h> |
#include <netdb.h> |
#include <sys/stat.h> |
#ifdef HAVE_DIRENT_H |
#if HAVE_DIRENT_H |
|
# include <dirent.h> |
# include <dirent.h> |
# define NAMLEN(dirent) strlen((dirent)->d_name) |
# define NAMLEN(dirent) strlen((dirent)->d_name) |
#else |
#else |
# define dirent direct |
# define dirent direct |
# define NAMLEN(dirent) (dirent)->d_namlen |
# define NAMLEN(dirent) (dirent)->d_namlen |
# if HAVE_SYS_NDIR_H |
# ifdef HAVE_SYS_NDIR_H |
# include <sys/ndir.h> |
# include <sys/ndir.h> |
# endif |
# endif |
# if HAVE_SYS_DIR_H |
# ifdef HAVE_SYS_DIR_H |
# include <sys/dir.h> |
# include <sys/dir.h> |
# endif |
# endif |
# if HAVE_NDIR_H |
# ifdef HAVE_NDIR_H |
# include <ndir.h> |
# include <ndir.h> |
# endif |
# endif |
#endif |
#endif |
|
|
#endif /* HAVE_FNMATCH */ |
#endif /* HAVE_FNMATCH */ |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: parse.c,v 1.130 2000/03/23 04:38:19 millert Exp $"; |
static const char rcsid[] = "$Sudo: parse.c,v 1.136 2002/01/08 15:00:18 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* |
/* |
|
|
* allowed to run the specified command on this host as the target user. |
* allowed to run the specified command on this host as the target user. |
*/ |
*/ |
int |
int |
sudoers_lookup(sudo_mode) |
sudoers_lookup(pwflag) |
int sudo_mode; |
int pwflag; |
{ |
{ |
int error; |
int error; |
int pwcheck; |
int pwcheck; |
|
int nopass; |
|
|
/* Become sudoers file owner */ |
/* Become sudoers file owner */ |
set_perms(PERM_SUDOERS, 0); |
set_perms(PERM_SUDOERS, 0); |
|
|
init_parser(); |
init_parser(); |
|
|
/* If pwcheck *could* be PWCHECK_ALL or PWCHECK_ANY, keep more state. */ |
/* If pwcheck *could* be PWCHECK_ALL or PWCHECK_ANY, keep more state. */ |
if (!(sudo_mode & MODE_RUN) && sudo_mode != MODE_KILL && |
if (pwflag > 0) |
sudo_mode != MODE_INVALIDATE) |
|
keepall = TRUE; |
keepall = TRUE; |
|
|
/* Need to be root while stat'ing things in the parser. */ |
/* Need to be root while stat'ing things in the parser. */ |
|
|
* The pw options may have changed during sudoers parse so we |
* The pw options may have changed during sudoers parse so we |
* wait until now to set this. |
* wait until now to set this. |
*/ |
*/ |
switch (sudo_mode) { |
if (pwflag) |
case MODE_VALIDATE: |
pwcheck = (pwflag == -1) ? PWCHECK_NEVER : def_ival(pwflag); |
pwcheck = def_ival(I_VERIFYPW); |
else |
break; |
pwcheck = 0; |
case MODE_LIST: |
|
pwcheck = def_ival(I_LISTPW); |
|
break; |
|
case MODE_KILL: |
|
case MODE_INVALIDATE: |
|
pwcheck = PWCHECK_NEVER; |
|
break; |
|
default: |
|
pwcheck = 0; |
|
break; |
|
} |
|
|
|
/* |
/* |
* Assume the worst. If the stack is empty the user was |
* Assume the worst. If the stack is empty the user was |
|
|
* It is set for the "validate", "list" and "kill" pseudo-commands. |
* It is set for the "validate", "list" and "kill" pseudo-commands. |
* Always check the host and user. |
* Always check the host and user. |
*/ |
*/ |
|
nopass = -1; |
if (pwcheck) { |
if (pwcheck) { |
int nopass, found; |
int found; |
|
|
if (pwcheck == PWCHECK_NEVER || !def_flag(I_AUTHENTICATE)) |
if (pwcheck == PWCHECK_NEVER || !def_flag(I_AUTHENTICATE)) |
nopass = FLAG_NOPASS; |
nopass = FLAG_NOPASS; |
else |
|
nopass = -1; |
|
found = 0; |
found = 0; |
while (top) { |
while (top) { |
if (host_matches == TRUE) { |
if (host_matches == TRUE) { |
|
|
/* |
/* |
* The user was not explicitly granted nor denied access. |
* The user was not explicitly granted nor denied access. |
*/ |
*/ |
return(error); |
if (nopass == -1) |
|
nopass = 0; |
|
return(error | nopass); |
} |
} |
|
|
/* |
/* |
|
|
addr.s_addr = inet_addr(n); |
addr.s_addr = inet_addr(n); |
if (strchr(m, '.')) |
if (strchr(m, '.')) |
mask.s_addr = inet_addr(m); |
mask.s_addr = inet_addr(m); |
else |
else { |
mask.s_addr = (1 << atoi(m)) - 1; /* XXX - better way? */ |
i = 32 - atoi(m); |
|
mask.s_addr = 0xffffffff; |
|
mask.s_addr >>= i; |
|
mask.s_addr <<= i; |
|
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++) |