2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

New Defaults options:

o stay_setuid - sudo will remain setuid if system has saved uids or setreuid(2)
 o env_reset - reset the environment to a sane default
 o env_keep - preserve environment variables that would otherwise be cleared

No longer use getenv/putenv/setenv functions--do environment munging by hand.
Potentially dangerous environment variables can be cleared only if they
contain '/' pr '%' characters to protect buggy programs.
Moved environment routines into env.c (new file)
This commit is contained in:
Todd C. Miller 2000-12-30 03:29:47 +00:00
parent f88c0c930b
commit 998631b73a
25 changed files with 1445 additions and 1026 deletions

62
CHANGES
View File

@ -1298,12 +1298,68 @@ Sudo 1.6.2 released.
Sudo 1.6.3 released.
409) Visudo now checks for the existence of an editor and gives a sensible
409) Fixed targetpw, rootpw, and runaspw options when used with non-passwd
authentication (pam, etc).
Sudo 1.6.3p1 released.
410) When the targetpw flag is set, use the target username as part
of the timestamp path.
Sudo 1.6.3p2 released.
411) Fixed a bug that prevented the -H option from being useful.
Sudo 1.6.3p3 released.
412) Fixed a case where a string was used after it had been freed.
Sudo 1.6.3p4 released.
413) Fixed listpw and verifypw sudoers options.
414) Do not write NUL when writing passwd prompt; hag@linnaean.org.
Sudo 1.6.3p5 released.
415) Visudo now checks for the existence of an editor and gives a sensible
error if it does not exist.
410) The path to the editor for visudo is now a colon-separated list of
416) The path to the editor for visudo is now a colon-separated list of
allowable editors. If the user has $EDITOR set and it matches
one of the allowed editors that editor will be used. If not,
the first editor that actually exists is used.
411) Visudo now does its own fork/exec instead of calling system(3).
417) Visudo now does its own fork/exec instead of calling system(3).
418) Call clean_env very early in main() for paranoia's sake. Idea from
Marc Esipovich.
419) Allow special characters (including '#') to be embedded in pathnames
if quoted by a '\\'. The quoted chars will be dealt with by fnmatch().
Unfortunately, 'sudo -l' still prints the '\\'.
420) Added always_set_home option.
421) Strip NLSPATH and PATH_LOCALE out from the environment to prevent
reading of protected files by a less priviledged user.
422) Add support for BSD authentication and associated -a flag.
423) Added check for _innetgr(3) since NCR systems have this instead
of innetgr(3).
424) Added stay_setuid option for systems that have libraries that perform
extra paranoia checks in system libraries for setuid programs.
425) Environment munging is now done by hand. We build up a new environment
and assign it to "environ". This means we don't rely on getenv(3),
putenv(3), or setenv(3).
426) Added env_reset and env_keep options. This allows the sysadmin to
force commands to run with a clean environment. Any variable in
the env_keep list will not get cleared when the environment is reset
*or* purged of dangerous vars (e.g. LD_*).
427) Added a class of environment variables that are only cleared if they
contain '/' or '%' characters.

View File

@ -109,10 +109,10 @@ SHELL = /bin/sh
PROGS = @PROGS@
SRCS = alloc.c alloca.c check.c defaults.c fileops.c find_path.c fnmatch.c \
getcwd.c getspwuid.c goodpath.c interfaces.c lex.yy.c lsearch.c \
logging.c parse.c parse.lex parse.yacc putenv.c set_perms.c snprintf.c \
strcasecmp.c strerror.c sudo.c sudo.tab.c sudo_setenv.c testsudoers.c \
SRCS = alloc.c alloca.c check.c defaults.c env.c fileops.c find_path.c \
fnmatch.c getcwd.c getspwuid.c goodpath.c interfaces.c lex.yy.c \
lsearch.c logging.c parse.c parse.lex parse.yacc set_perms.c \
snprintf.c strcasecmp.c strerror.c sudo.c sudo.tab.c testsudoers.c \
tgetpass.c utime.c visudo.c $(AUTH_SRCS)
AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
@ -127,8 +127,8 @@ AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o
SUDOBJS = check.o getspwuid.o goodpath.o fileops.o find_path.o interfaces.o \
logging.o parse.o set_perms.o sudo.o sudo_setenv.o tgetpass.o \
SUDOBJS = check.o env.o getspwuid.o goodpath.o fileops.o find_path.o \
interfaces.o logging.o parse.o set_perms.o sudo.o tgetpass.o \
$(AUTH_OBJS) $(PARSEOBJS)
VISUDOBJS = visudo.o fileops.o goodpath.o find_path.o $(PARSEOBJS)
@ -199,13 +199,13 @@ testsudoers: $(TESTOBJS) $(LIBOBJS)
# Dependencies (not counting auth functions)
alloc.o: alloc.c $(SUDODEP)
check.o: check.c $(SUDODEP)
env.o: env.c $(SUDODEP)
fileops.o: fileops.c $(SUDODEP)
find_path.o: find_path.c $(SUDODEP)
getspwuid.o: getspwuid.c $(SUDODEP)
goodpath.o: goodpath.c $(SUDODEP)
logging.o: logging.c $(SUDODEP)
set_perms.o: set_perms.c $(SUDODEP)
sudo_setenv.o: sudo_setenv.c $(SUDODEP)
tgetpass.o: tgetpass.c $(SUDODEP)
visudo.o: visudo.c $(SUDODEP) version.h
sudo.o: sudo.c $(SUDODEP) interfaces.h version.h
@ -218,7 +218,6 @@ defaults.o: defaults.c $(SUDODEP) auth/sudo_auth.h
fnmatch.o: fnmatch.c config.h compat.h emul/fnmatch.h
getcwd.o: getcwd.c config.h compat.h
lsearch.o: lsearch.c config.h compat.h emul/search.h
putenv.o: putenv.c config.h compat.h
snprintf.o: snprintf.c config.h compat.h
strcasecmp.o: strcasecmp.c config.h
strerror.o: strerror.c config.h

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1993-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -155,6 +155,14 @@
# endif /* __hpux */
#endif /* HAVE_SETEUID */
/*
* Emulate setreuid() for HP-UX via setresuid(2)
*/
#if !defined(HAVE_SETREUID) && defined(__hpux)
# define setreuid(_RUID, _EUID) (setresuid(_RUID, _EUID, (uid_t) -1))
# define HAVE_SETREUID
#endif /* !HAVE_SETEUID && __hpux */
/*
* NCR's SVr4 has _innetgr(3) instead of innetgr(3) for some reason.
*/

View File

@ -173,12 +173,6 @@
/* Define if you have sysconf(3c). */
#undef HAVE_SYSCONF
/* Define if you have putenv(3). */
#undef HAVE_PUTENV
/* Define if you have setenv(3). */
#undef HAVE_SETENV
/* Define if you have strcasecmp(3). */
#undef HAVE_STRCASECMP
@ -242,6 +236,9 @@
/* Define if you have seteuid(3). */
#undef HAVE_SETEUID
/* Define if you have setreuid(3). */
#undef HAVE_SETREUID
/* Define if you have waitpid(2). */
#undef HAVE_WAITPID

650
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1448,6 +1448,18 @@ case "$host" in
CHECKSHADOW="false"
fi
;;
*-*-*openbsd*)
BROKEN_SETREUID=yes
if test "$CHECKSHADOW" = "true"; then
CHECKSHADOW="false"
fi
;;
*-*-*netbsd*)
BROKEN_SETREUID=yes
if test "$CHECKSHADOW" = "true"; then
CHECKSHADOW="false"
fi
;;
*-*-*bsd*)
if test "$CHECKSHADOW" = "true"; then
CHECKSHADOW="false"
@ -1534,6 +1546,9 @@ dnl
dnl Function checks
dnl
AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf sigaction tzset seteuid strftime setrlimit initgroups fstat)
if test -z "$BROKEN_SETREUID"; then
AC_CHECK_FUNCS(setreuid)
fi
if test X"$with_interfaces" != X"no"; then
AC_CHECK_FUNCS(getifaddrs)
fi
@ -1549,7 +1564,6 @@ AC_CHECK_FUNC(lockf, AC_DEFINE(HAVE_LOCKF), AC_CHECK_FUNCS(flock))
AC_CHECK_FUNC(waitpid, AC_DEFINE(HAVE_WAITPID), AC_CHECK_FUNCS(wait3))
AC_CHECK_FUNC(innetgr, AC_DEFINE(HAVE_INNETGR) AC_CHECK_FUNCS(getdomainname), [AC_CHECK_FUNC(_innetgr, AC_DEFINE(HAVE__INNETGR) AC_CHECK_FUNCS(getdomainname))])
AC_CHECK_FUNC(lsearch, AC_DEFINE(HAVE_LSEARCH), AC_CHECK_LIB(compat, lsearch, AC_CHECK_HEADER(search.h, AC_DEFINE(HAVE_LSEARCH) [LIBS="${LIBS} -lcompat"], LIBOBJS="$LIBOBJS lsearch.o"), LIBOBJS="$LIBOBJS lsearch.o"))
AC_CHECK_FUNC(setenv, AC_DEFINE(HAVE_SETENV), AC_FUNC_CHECK(putenv, AC_DEFINE(HAVE_PUTENV), LIBOBJS="$LIBOBJS putenv.o"))
AC_CHECK_FUNC(utime, AC_DEFINE(HAVE_UTIME)
SUDO_FUNC_UTIME_POSIX, LIBOBJS="$LIBOBJS utime.o")
SUDO_FUNC_FNMATCH(AC_DEFINE(HAVE_FNMATCH), LIBOBJS="$LIBOBJS fnmatch.o")

View File

@ -205,6 +205,9 @@ struct sudo_defs_types sudo_defs_table[] = {
}, {
"stay_setuid", T_FLAG,
"Only set the effective uid to the target user, not the real uid"
}, {
"env_reset", T_FLAG,
"Reset the environment to a default set of variables"
}, {
"loglinelen", T_INT|T_BOOL,
"Length at which to wrap log file lines (0 for no wrap): %d"
@ -256,6 +259,9 @@ struct sudo_defs_types sudo_defs_table[] = {
}, {
"editor", T_STR|T_PATH,
"Path to the editor for use by visudo: %s"
}, {
"env_keep", T_STR|T_BOOL,
"Environment variables to preserve: %s"
}, {
"listpw_i", T_INT, NULL
}, {

View File

@ -119,35 +119,37 @@ struct sudo_defs_types {
#define I_LOGINCLASS 29
#define I_LOGNAME 30
#define I_STAY_SETUID 31
#define I_ENV_RESET 32
/* Integer values */
#define I_LOGLEN 32 /* wrap log file line after N chars */
#define I_TS_TIMEOUT 33 /* timestamp stale after N minutes */
#define I_PW_TIMEOUT 34 /* exit if pass not entered in N minutes */
#define I_PW_TRIES 35 /* exit after N bad password tries */
#define I_UMASK 36 /* umask to use or 0777 to use user's */
#define I_LOGLEN 33 /* wrap log file line after N chars */
#define I_TS_TIMEOUT 34 /* timestamp stale after N minutes */
#define I_PW_TIMEOUT 35 /* exit if pass not entered in N minutes */
#define I_PW_TRIES 36 /* exit after N bad password tries */
#define I_UMASK 37 /* umask to use or 0777 to use user's */
/* Strings */
#define I_LOGFILE 37 /* path to logfile (or NULL for none) */
#define I_MAILERPATH 38 /* path to sendmail or other mailer */
#define I_MAILERFLAGS 39 /* flags to pass to the mailer */
#define I_MAILTO 40 /* who to send bitch mail to */
#define I_MAILSUB 41 /* subject line of mail msg */
#define I_BADPASS_MSG 42 /* what to say when passwd is wrong */
#define I_TIMESTAMPDIR 43 /* path to timestamp dir */
#define I_EXEMPT_GRP 44 /* no password or PATH override for these */
#define I_PASSPROMPT 45 /* password prompt */
#define I_RUNAS_DEF 46 /* default user to run commands as */
#define I_SECURE_PATH 47 /* set $PATH to this if not NULL */
#define I_EDITOR 48 /* path to editor used by visudo */
#define I_LOGFILE 38 /* path to logfile (or NULL for none) */
#define I_MAILERPATH 39 /* path to sendmail or other mailer */
#define I_MAILERFLAGS 40 /* flags to pass to the mailer */
#define I_MAILTO 41 /* who to send bitch mail to */
#define I_MAILSUB 42 /* subject line of mail msg */
#define I_BADPASS_MSG 43 /* what to say when passwd is wrong */
#define I_TIMESTAMPDIR 44 /* path to timestamp dir */
#define I_EXEMPT_GRP 45 /* no password or PATH override for these */
#define I_PASSPROMPT 46 /* password prompt */
#define I_RUNAS_DEF 47 /* default user to run commands as */
#define I_SECURE_PATH 48 /* set $PATH to this if not NULL */
#define I_EDITOR 49 /* path to editor used by visudo */
#define I_ENV_KEEP 50 /* list of env vars to preserve */
/* Integer versions of list/verify options */
#define I_LISTPW 49
#define I_VERIFYPW 50
#define I_LISTPW 51
#define I_VERIFYPW 52
/* String versions of list/verify options */
#define I_LISTPWSTR 51
#define I_VERIFYPWSTR 52
#define I_LISTPWSTR 53
#define I_VERIFYPWSTR 54
/*
* Macros for accessing sudo_defs_table.

372
env.c Normal file
View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2000 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.
*
* 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
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif /* STDC_HEADERS */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <pwd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include "sudo.h"
#ifndef lint
static const char rcsid[] = "$Sudo$";
#endif /* lint */
/*
* Local type declarations
*/
struct env_table {
char *name;
int len;
int check;
};
/*
* Prototypes
*/
char **rebuild_env __P((int, char **));
char **zero_env __P((char **));
static void insert_env __P((char **, char *));
static char *format_env __P((char *, char *));
/*
* Table of "bad" envariables to remove and len for strncmp()
*/
static struct env_table badenv_table[] = {
{ "IFS=", 4, 0 },
{ "LOCALDOMAIN=", 12, 0 },
{ "RES_OPTIONS=", 12, 0 },
{ "HOSTALIASES=", 12, 0 },
{ "NLSPATH=", 8, 0 },
{ "PATH_LOCALE=", 12, 0 },
{ "LD_", 3, 0 },
{ "_RLD", 4, 0 },
#ifdef __hpux
{ "SHLIB_PATH=", 11, 0 },
#endif /* __hpux */
#ifdef _AIX
{ "LIBPATH=", 8, 0 },
#endif /* _AIX */
#ifdef HAVE_KERB4
{ "KRB_CONF", 8, 0 },
{ "KRBCONFDIR=", 11, 0 },
{ "KRBTKFILE=", 10, 0 },
#endif /* HAVE_KERB4 */
#ifdef HAVE_KERB5
{ "KRB5_CONFIG", 11, 0 },
#endif /* HAVE_KERB5 */
#ifdef HAVE_SECURID
{ "VAR_ACE=", 8, 0 },
{ "USR_ACE=", 8, 0 },
{ "DLC_ACE=", 8, 0 },
#endif /* HAVE_SECURID */
{ "TERMINFO=", 9, 0 },
{ "TERMINFO_DIRS=", 14, 0 },
{ "TERMPATH=", 9, 0 },
{ "TERMCAP=/", 9, 0 },
{ "ENV=", 4, 0 },
{ "BASH_ENV=", 9, 0 },
{ "LC_", 3, 1 },
{ "LANG=", 5, 1 },
{ (char *) NULL, 0, 0 }
};
/*
* Zero out environment and replace with a minimal set of
* USER, LOGNAME, HOME, TZ, PATH (XXX - should just set path to default)
* May set user_path, user_shell, and/or user_prompt as side effects.
*/
char **
zero_env(envp)
char **envp;
{
char **ep, **nep;
static char *newenv[7];
for (ep = envp; *ep; ep++) {
switch (**ep) {
case 'H':
if (strncmp("HOME=", *ep, 5) == 0)
break;
case 'L':
if (strncmp("LOGNAME=", *ep, 8) == 0)
break;
case 'P':
if (strncmp("PATH=", *ep, 5) == 0) {
user_path = *ep + 5;
/* XXX - set to sane default instead of user's? */
break;
}
case 'S':
if (strncmp("SHELL=", *ep, 6) == 0) {
user_shell = *ep + 6;
continue;
} else if (!user_prompt && !strncmp("SUDO_PROMPT=", *ep, 12)) {
user_prompt = *ep + 12;
continue;
}
case 'T':
if (strncmp("TZ=", *ep, 3) == 0)
break;
case 'U':
if (strncmp("USER=", *ep, 5) == 0)
break;
default:
continue;
}
/* Deal with multiply defined variables (take first instantiation) */
for (nep = newenv; *nep; nep++) {
if (**nep == **ep)
break;
}
if (*nep == NULL)
*nep++ = *ep;
}
return(&newenv[0]);
}
/*
* Given a variable and value, allocate and format an environment string.
*/
static char *
format_env(var, val)
char *var;
char *val;
{
char *estring, *p;
size_t varlen, vallen;
varlen = strlen(var);
vallen = strlen(val);
p = estring = (char *) emalloc(varlen + vallen + 2);
strcpy(p, var);
p += varlen;
*p++ = '=';
strcpy(p, val);
return(estring);
}
/*
* Insert str into envp.
* Assumes str has an '=' in it and does not check for available space!
*/
static void
insert_env(envp, str)
char **envp;
char *str;
{
char **ep;
size_t varlen;
varlen = (strchr(str, '=') - str) + 1;
for (ep = envp; *ep; ep++) {
if (strncmp(str, *ep, varlen) == 0) {
*ep = str;
break;
}
}
if (*ep == NULL) {
*ep++ = str;
*ep = NULL;
}
}
/*
* Build a new environment and ether clear potentially dangerous
* variables from the old one or starts with a clean slate.
* Also adds sudo-specific variables (SUDO_*).
*/
char **
rebuild_env(sudo_mode, envp)
int sudo_mode;
char **envp;
{
char **newenvp, **ep, **nep, **ek, *cp;
char *ekflat, *ps1, **env_keep;
size_t env_size, eklen;
struct env_table *entry;
eklen = 0;
ekflat = ps1 = NULL;
env_keep = NULL;
if (def_str(I_ENV_KEEP)) {
/* XXX - start eklen at 1 instead? */
for (cp = def_str(I_ENV_KEEP), eklen = 2; *cp; cp++)
if (*cp == ' ' || *cp == '\t')
eklen++;
env_keep = emalloc(sizeof(char *) * eklen);
cp = ekflat = estrdup(def_str(I_ENV_KEEP));
eklen = 0;
if ((cp = strtok(cp, " \t"))) {
do {
/* XXX - hack due to assumption in rebuild_env */
if (strcmp("PATH", cp) && strcmp("TERM", cp))
env_keep[eklen++] = cp;
} while ((cp = strtok(NULL, " \t")));
}
env_keep[eklen] = NULL;
}
/*
* Either clean out the environment or reset to a safe default.
*/
if (def_flag(I_ENV_RESET)) {
int didterm;
/* Alloc space for new environment. */
env_size = 32 + eklen;
nep = newenvp = (char **) emalloc(env_size * sizeof(char *));
/* XXX - set all to target user instead for -S */
*nep++ = format_env("HOME", user_dir);
*nep++ = format_env("SHELL", user_shell);
if (def_flag(I_LOGNAME) && runas_pw->pw_name) {
*nep++ = format_env("LOGNAME", runas_pw->pw_name);
*nep++ = format_env("USER", runas_pw->pw_name);
} else {
*nep++ = format_env("LOGNAME", user_name);
*nep++ = format_env("USER", user_name);
}
/* Pull in vars we want to keep from the old environment */
didterm = 0;
for (ep = envp; *ep; ep++) {
if (env_keep) {
for (ek = env_keep; *ek; ek++) {
eklen = strlen(*ek);
if (strncmp(*ek, *ep, eklen) == 0 && (*ep)[eklen] == '=') {
*nep++ = *ep;
break;
}
}
}
/* We assume PATH and TERM are not listed in env_keep. */
if (!def_str(I_SECURE_PATH) && strncmp(*ep, "PATH=", 5) == 0) {
*nep++ = *ep;
} else if (!didterm && strncmp(*ep, "TERM=", 5) == 0) {
*nep++ = *ep;
didterm = 1;
} else if (strncmp(*ep, "SUDO_PS1=", 8) == 0)
ps1 = *ep + 5;
}
#if 0
/* XXX - set to _PATH_DEFPATH if no secure path? */
if (!def_str(I_SECURE_PATH))
*nep++ = "PATH" _PATH_DEFPATH); /* XXX - concat macro? */
#endif
if (!didterm)
*nep++ = "TERM=unknown";
} else {
/* Alloc space for new environment. */
for (env_size = 16 + eklen, ep = envp; *ep; ep++, env_size++)
;
nep = newenvp = (char **) emalloc(env_size * sizeof(char *));
/* Copy envp entries as long as they don't match badenv_table. */
for (ep = envp; *ep; ep++) {
for (entry = badenv_table; entry->name; entry++) {
if (strncmp(*ep, entry->name, entry->len) != 0 ||
(entry->check && !strpbrk(*ep, "/%"))) {
if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
ps1 = *ep + 5;
*nep++ = *ep;
break;
}
}
}
}
*nep = NULL;
/*
* At this point we must use insert_env() to modify newenvp.
* Access via 'nep' is not allowed (since we must check for dupes).
*/
/* Replace the PATH envariable with a secure one. */
if (def_str(I_SECURE_PATH) && !user_is_exempt())
insert_env(newenvp, format_env("PATH", def_str(I_SECURE_PATH)));
/* Set $HOME for `sudo -H'. Only valid at PERM_RUNAS. */
if ((sudo_mode & MODE_RESET_HOME) && runas_pw->pw_dir)
insert_env(newenvp, format_env("HOME", runas_pw->pw_dir));
/* Set PS1 if SUDO_PS1 is set. */
if (ps1)
insert_env(newenvp, ps1);
/* Add the SUDO_COMMAND envariable (cmnd + args). */
if (user_args) {
cp = emalloc(strlen(user_cmnd) + strlen(user_args) + 14);
sprintf(cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args);
insert_env(newenvp, cp);
} else
insert_env(newenvp, format_env("SUDO_COMMAND", user_cmnd));
/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
insert_env(newenvp, format_env("SUDO_USER", user_name));
cp = emalloc(MAX_UID_T_LEN + 10);
sprintf(cp, "SUDO_UID=%ld", (long) user_uid);
insert_env(newenvp, cp);
cp = emalloc(MAX_UID_T_LEN + 10);
sprintf(cp, "SUDO_GID=%ld", (long) user_gid);
insert_env(newenvp, cp);
if (env_keep) {
free(env_keep);
free(ekflat);
}
return(newenvp);
}

View File

@ -55,7 +55,6 @@
#include "sudo.h"
#ifndef STDC_HEADERS
extern char *getenv __P((const char *));
extern char *strcpy __P((char *, const char *));
extern int fprintf __P((FILE *, const char *, ...));
extern ssize_t readlink __P((const char *, VOID *, size_t));
@ -75,13 +74,13 @@ static const char rcsid[] = "$Sudo$";
* but it is in '.' and IGNORE_DOT is set.
*/
int
find_path(infile, outfile)
find_path(infile, outfile, path)
char *infile; /* file to find */
char **outfile; /* result parameter */
char *path; /* path to search */
{
static char command[MAXPATHLEN]; /* qualified filename */
char *n; /* for traversing path */
char *path = NULL; /* contents of PATH env var */
char *origpath; /* so we can free path later */
char *result = NULL; /* result of path/file lookup */
int checkdot = 0; /* check current dir? */
@ -104,13 +103,10 @@ find_path(infile, outfile)
return(NOT_FOUND);
}
/*
* Grab PATH out of the environment (or from the string table
* if SECURE_PATH is in effect) and make a local copy.
*/
/* Use PATH passed in unless SECURE_PATH is in effect. */
if (def_str(I_SECURE_PATH) && !user_is_exempt())
path = def_str(I_SECURE_PATH);
else if ((path = getenv("PATH")) == NULL)
else if (path == NULL)
return(NOT_FOUND);
path = estrdup(path);
origpath = path;

View File

@ -78,10 +78,6 @@
static const char rcsid[] = "$Sudo$";
#endif /* lint */
#ifndef STDC_HEADERS
extern char *getenv __P((const char *));
#endif /* !STDC_HEADERS */
/*
* Global variables (yuck)
*/
@ -98,8 +94,8 @@ static struct passwd *sudo_pwdup __P((struct passwd *));
/*
* Return the user's shell based on either the SHELL
* environment variable or the passwd(5) entry (in that order).
* Return the user's shell based on either the SHELL environment variable
* (already assigned to user_shell) or, failing that, the passwd(5) entry.
*/
static char *
sudo_getshell(pw)
@ -107,14 +103,12 @@ sudo_getshell(pw)
{
char *pw_shell;
if ((pw_shell = getenv("SHELL")) == NULL)
if ((pw_shell = user_shell) == NULL)
pw_shell = pw->pw_shell;
#ifdef _PATH_BSHELL
/* empty string "" means bourne shell */
if (*pw_shell == '\0')
pw_shell = _PATH_BSHELL;
#endif /* _PATH_BSHELL */
return(pw_shell);
}

View File

@ -64,161 +64,56 @@ static const char rcsid[] = "$Sudo$";
#endif /* lint */
/*
* It might be better to use sysconf(_SC_SAVED_IDS) instead but
* I'm * not aware of any system where this would be necessary.
* Prototypes
*/
#ifdef _POSIX_SAVED_IDS
# define TOGGLE_ROOT \
if (seteuid(0)) { \
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, \
"seteuid(0)"); \
}
# define TOGGLE_USER \
if (seteuid(user_uid)) { \
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, \
"seteuid(%ld)", (long) user_uid); \
}
#else
# ifdef HAVE_SETREUID
# define TOGGLE_ROOT \
if (setreuid(user_uid, 0)) { \
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, \
"setreuid(%ld, 0)", (long) user_uid); \
}
# define TOGGLE_USER \
if (setreuid(0, user_uid)) { \
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, \
"setreuid(0, %ld)", (long) user_uid); \
}
# else /* !_POSIX_SAVED_IDS && !HAVE_SETREUID */
# define TOGGLE_ROOT \
;
# define TOGGLE_USER \
if (seteuid(user_uid)) { \
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, \
"seteuid(%ld)", (long) user_uid); \
}
# endif /* HAVE_SETREUID */
#endif /* _POSIX_SAVED_IDS */
static void runas_setup __P((void));
static void fatal __P((char *));
/*
* Set real and effective uids and gids based on perm.
* If we have POSIX saved IDs or setreuid(2) we can get away with only
* Since we have POSIX saved IDs we can get away with just
* toggling the effective uid/gid unless we are headed for an exec().
*/
void
set_perms(perm, sudo_mode)
set_perms_saved_uid(perm, sudo_mode)
int perm;
int sudo_mode;
{
struct passwd *pw;
int error;
#ifdef HAVE_LOGIN_CAP_H
extern login_cap_t *lc;
#endif
extern char *runas_homedir;
/*
* If we only have setuid() and seteuid() we have to set both to root
* initially.
*/
#if !defined(_POSIX_SAVED_IDS) && !defined(HAVE_SETREUID)
if (setuid(0)) {
perror("setuid(0)");
exit(1);
}
#endif
switch (perm) {
case PERM_ROOT:
TOGGLE_ROOT;
if (seteuid(0))
fatal("seteuid(0)");
break;
case PERM_USER:
(void) setegid(user_gid);
TOGGLE_USER;
if (seteuid(user_uid))
fatal("seteuid(user_uid)");
break;
case PERM_FULL_USER:
/* headed for exec() */
(void) setgid(user_gid);
if (setuid(user_uid)) {
perror("setuid(user_uid)");
exit(1);
}
if (setuid(user_uid))
fatal("setuid(user_uid)");
break;
case PERM_RUNAS:
/* headed for exec(), assume euid == 0 */
/* XXX - add group/gid support */
if (**user_runas == '#') {
if (def_flag(I_STAY_SETUID))
error = seteuid(atoi(*user_runas + 1));
else
error = setuid(atoi(*user_runas + 1));
if (error)
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"cannot set uid to %s", *user_runas);
} else {
if (!(pw = getpwnam(*user_runas)))
log_error(NO_MAIL|MSG_ONLY,
"no passwd entry for %s!",
*user_runas);
/* Set $USER and $LOGNAME to target user */
if (def_flag(I_LOGNAME)) {
sudo_setenv("USER", pw->pw_name);
sudo_setenv("LOGNAME", pw->pw_name);
}
#ifdef HAVE_LOGIN_CAP_H
if (def_flag(I_LOGINCLASS)) {
/*
* We don't have setusercontext()
* set the user since we may only
* want to set the effective uid.
*/
error = setusercontext(lc, pw, pw->pw_uid,
LOGIN_SETGROUP|LOGIN_SETRESOURCES|LOGIN_SETPRIORITY);
if (error)
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"setusercontext() failed for login class %s",
login_class);
} else
#endif /* HAVE_LOGIN_CAP_H */
{
if (setgid(pw->pw_gid))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"cannot set gid to %ld: %s",
(long) pw->pw_gid);
#ifdef HAVE_INITGROUPS
/*
* Initialize group vector only if are
* going to run as a non-root user.
*/
if (strcmp(*user_runas, "root") != 0 &&
initgroups(*user_runas, pw->pw_gid) < 0)
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"cannot set group vector");
#endif /* HAVE_INITGROUPS */
}
if (def_flag(I_STAY_SETUID))
error = seteuid(pw->pw_uid);
else
error = setuid(pw->pw_uid);
if (error)
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"cannot set uid to %ld",
(long) pw->pw_uid);
if (sudo_mode & MODE_RESET_HOME)
runas_homedir = pw->pw_dir;
}
runas_setup();
if (def_flag(I_STAY_SETUID))
error = seteuid(runas_pw->pw_uid);
else
error = setuid(runas_pw->pw_uid);
if (error)
fatal("unable to change to runas uid");
break;
case PERM_SUDOERS:
/* assume euid == 0, ruid == user */
if (setegid(SUDOERS_GID))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"setegid(SUDOERS_GID)");
fatal("unable to change to sudoers gid");
/*
* If SUDOERS_UID == 0 and SUDOERS_MODE
@ -227,27 +122,191 @@ set_perms(perm, sudo_mode)
* Using uid 1 is a bit bogus but should
* work on all OS's.
*/
#if defined(HAVE_SETREUID) && !defined(_POSIX_SAVED_IDS)
if (SUDOERS_UID == 0) {
if ((SUDOERS_MODE & 040) && setreuid(0, 1))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"setreuid(0, 1)");
} else {
if (setreuid(0, SUDOERS_UID))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"setreuid(0, SUDOERS_UID)");
}
#else
if (SUDOERS_UID == 0) {
if ((SUDOERS_MODE & 040) && seteuid(1))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"seteuid(1)");
fatal("seteuid(1)");
} else {
if (seteuid(SUDOERS_UID))
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
"seteuid(SUDOERS_UID)");
fatal("seteuid(SUDOERS_UID)");
}
#endif /* HAVE_SETREUID && !_POSIX_SAVED_IDS */
break;
}
}
/*
* Set real and effective uids and gids based on perm.
* We always retain a real or effective uid of 0 unless
* we are headed for an exec().
*/
void
set_perms_setreuid(perm, sudo_mode)
int perm;
int sudo_mode;
{
int error;
switch (perm) {
case PERM_ROOT:
if (setuid(0))
fatal("setuid(0)");
break;
case PERM_USER:
(void) setegid(user_gid);
if (setreuid(0, user_uid))
fatal("setreuid(0, user_uid)");
break;
case PERM_FULL_USER:
/* headed for exec() */
(void) setgid(user_gid);
if (setuid(user_uid)) {
fatal("setuid(user_uid)");
exit(1);
}
break;
case PERM_RUNAS:
/* headed for exec(), assume euid == 0 */
runas_setup();
if (def_flag(I_STAY_SETUID))
error = setreuid(user_uid, runas_pw->pw_uid);
else
error = setuid(runas_pw->pw_uid);
if (error)
fatal("unable to change to runas uid");
break;
case PERM_SUDOERS:
/* assume euid == 0, ruid == user */
if (setegid(SUDOERS_GID))
fatal("unable to change to sudoers gid");
/*
* If SUDOERS_UID == 0 and SUDOERS_MODE
* is group readable we use a non-zero
* uid in order to avoid NFS lossage.
* Using uid 1 is a bit bogus but should
* work on all OS's.
*/
if (SUDOERS_UID == 0) {
if ((SUDOERS_MODE & 040) && setreuid(0, 1))
fatal("setreuid(0, 1)");
} else {
if (setreuid(0, SUDOERS_UID))
fatal("setreuid(0, SUDOERS_UID)");
}
break;
}
}
#ifndef HAVE_SETREUID
/*
* Set real and effective uids and gids based on perm.
* NOTE: does not support the "stay_setuid" option.
*/
void
set_perms_fallback(perm, sudo_mode)
int perm;
int sudo_mode;
{
/*
* Since we only have setuid() and seteuid() we have to set
* real and effective uidss to 0 initially.
*/
if (setuid(0))
fatal("setuid(0)");
switch (perm) {
case PERM_USER:
(void) setegid(user_gid);
if (seteuid(user_uid))
fatal("seteuid(user_uid)");
break;
case PERM_FULL_USER:
/* headed for exec() */
(void) setgid(user_gid);
if (setuid(user_uid))
fatal("setuid(user_uid)");
break;
case PERM_RUNAS:
/* headed for exec(), assume euid == 0 */
runas_setup();
if (setuid(runas_pw->pw_uid))
fatal("unable to change to runas uid");
break;
case PERM_SUDOERS:
/* assume euid == 0, ruid == user */
if (setegid(SUDOERS_GID))
fatal("unable to change to sudoers gid");
/*
* If SUDOERS_UID == 0 and SUDOERS_MODE
* is group readable we use a non-zero
* uid in order to avoid NFS lossage.
* Using uid 1 is a bit bogus but should
* work on all OS's.
*/
if (SUDOERS_UID == 0) {
if ((SUDOERS_MODE & 040) && seteuid(1))
fatal("seteuid(1)");
} else {
if (seteuid(SUDOERS_UID))
fatal("seteuid(SUDOERS_UID)");
}
break;
}
}
#endif /* HAVE_SETREUID */
static void
runas_setup()
{
#ifdef HAVE_LOGIN_CAP_H
int error;
extern login_cap_t *lc;
#endif
if (runas_pw->pw_name != NULL) {
#ifdef HAVE_LOGIN_CAP_H
if (def_flag(I_LOGINCLASS)) {
/*
* We don't have setusercontext()
* set the user since we may only
* want to set the effective uid.
*/
error = setusercontext(lc, runas_pw,
runas_pw->pw_uid,
LOGIN_SETGROUP|LOGIN_SETRESOURCES|LOGIN_SETPRIORITY);
if (error)
perror("unable to set user context");
} else
#endif /* HAVE_LOGIN_CAP_H */
{
if (setgid(runas_pw->pw_gid))
perror("cannot set gid to runas gid");
#ifdef HAVE_INITGROUPS
/*
* Initialize group vector only if are
* going to run as a non-root user.
*/
if (strcmp(*user_runas, "root") != 0 &&
initgroups(*user_runas, runas_pw->pw_gid) < 0)
perror("cannot set group vector");
#endif /* HAVE_INITGROUPS */
}
}
}
static void
fatal(str)
char *str;
{
if (str)
perror(str);
exit(1);
}

291
sudo.c
View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994-1996,1998-2000 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1993-1996,1998-2000 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -88,45 +88,35 @@
#include "interfaces.h"
#include "version.h"
#ifndef STDC_HEADERS
extern char *getenv __P((char *));
#endif /* STDC_HEADERS */
#ifndef lint
static const char rcsid[] = "$Sudo$";
#endif /* lint */
/* XXX - for debugging, will become a runtime option */
#ifdef STAY_SETUID
# define SETUID(_x) seteuid(_x)
#else
# define SETUID(_x) setuid(_x)
#endif /* XXX */
/*
* Local type declarations
*/
struct env_table {
char *name;
int len;
int check;
};
/*
* Prototypes
*/
static int parse_args __P((void));
static int init_vars __P((int));
static int parse_args __P((void));
static void check_sudoers __P((void));
static void initial_setup __P((void));
static void set_loginclass __P((struct passwd *));
static void usage __P((int));
static void usage_excl __P((int));
static void check_sudoers __P((void));
static int init_vars __P((int));
static void set_loginclass __P((struct passwd *));
static void add_env __P((int));
static void clean_env __P((char **, struct env_table *, struct env_table *));
static void initial_setup __P((void));
static struct passwd *get_authpw __P((void));
extern struct passwd *sudo_getpwuid __P((uid_t));
extern struct passwd *sudo_getpwnam __P((const char *));
extern void list_matches __P((void));
extern char **rebuild_env __P((int, char **));
extern char **zero_env __P((char **));
extern struct passwd *sudo_getpwnam __P((const char *));
extern struct passwd *sudo_getpwuid __P((uid_t));
/*
* Globals
@ -142,7 +132,6 @@ struct interface *interfaces;
int num_interfaces;
int tgetpass_flags;
extern int errorlineno;
char *runas_homedir = NULL; /* XXX */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
static struct rlimit corelimit;
#endif /* RLIMIT_CORE */
@ -152,60 +141,14 @@ login_cap_t *lc;
#ifdef HAVE_BSD_AUTH_H
char *login_style;
#endif /* HAVE_BSD_AUTH_H */
/*
* Table of "bad" envariables to remove and len for strncmp()
*/
static struct env_table badenv_table[] = {
{ "IFS=", 4 },
{ "LOCALDOMAIN=", 12 },
{ "RES_OPTIONS=", 12 },
{ "HOSTALIASES=", 12 },
{ "NLSPATH=", 8 },
{ "PATH_LOCALE=", 12 },
{ "LD_", 3 },
{ "_RLD", 4 },
#ifdef __hpux
{ "SHLIB_PATH=", 11 },
#endif /* __hpux */
#ifdef _AIX
{ "LIBPATH=", 8 },
#endif /* _AIX */
#ifdef HAVE_KERB4
{ "KRB_CONF", 8 },
{ "KRBCONFDIR=", 11 },
{ "KRBTKFILE=", 10 },
#endif /* HAVE_KERB4 */
#ifdef HAVE_KERB5
{ "KRB5_CONFIG", 11 },
#endif /* HAVE_KERB5 */
#ifdef HAVE_SECURID
{ "VAR_ACE=", 8 },
{ "USR_ACE=", 8 },
{ "DLC_ACE=", 8 },
#endif /* HAVE_SECURID */
{ "TERMINFO=", 9 },
{ "TERMINFO_DIRS=", 14 },
{ "TERMPATH=", 9 },
{ "TERMCAP=/", 9 },
{ "ENV=", 4 },
{ "BASH_ENV=", 9 },
{ (char *) NULL, 0 }
};
/*
* Table of envariables to remove if they contain '/' or '%'
*/
static struct env_table naughtyenv_table[] = {
{ "LC_=", 4 },
{ "LANG=", 5 },
{ (char *) NULL, 0 }
};
void (*set_perms) __P((int, int));
int
main(argc, argv)
main(argc, argv, envp)
int argc;
char **argv;
char **envp;
{
int validated;
int fd;
@ -217,8 +160,8 @@ main(argc, argv)
#else
int omask;
#endif /* POSIX_SIGNALS */
extern char **environ;
extern int printmatches;
extern char **environ;
/* Must be done as the first thing... */
#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS)
@ -228,8 +171,8 @@ main(argc, argv)
# endif
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
/* Get rid of any nasty bits in the environment. */
clean_env(environ, badenv_table, naughtyenv_table);
/* Zero out the environment. */
environ = zero_env(envp);
Argv = argv;
Argc = argc;
@ -258,11 +201,6 @@ main(argc, argv)
*/
initial_setup();
/*
* Set the prompt based on $SUDO_PROMPT (can be overridden by `-p')
*/
user_prompt = getenv("SUDO_PROMPT");
/* Parse our arguments. */
sudo_mode = parse_args();
@ -316,15 +254,31 @@ main(argc, argv)
cmnd_status = init_vars(sudo_mode);
/* At this point, ruid == euid == 0 */
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */
/* Validate the user but don't search for pseudo-commands. */
validated = sudoers_lookup(pwflag);
/*
* Look up runas user passwd struct. If we are given a uid then
* there may be no corresponding passwd(5) entry (which is OK).
*/
if (**user_runas == '#') {
runas_pw = sudo_getpwuid(atoi(*user_runas + 1));
if (runas_pw == NULL) {
runas_pw = emalloc(sizeof(struct passwd));
(void) memset((VOID *)runas_pw, 0, sizeof(struct passwd));
runas_pw->pw_uid = atoi(*user_runas + 1);
}
} else {
runas_pw = sudo_getpwnam(*user_runas);
if (runas_pw == NULL)
log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
}
/* Customize environment and get rid of any nasty bits. */
environ = rebuild_env(sudo_mode, envp);
/* This goes after the sudoers parse since we honor sudoers options. */
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
remove_timestamp((sudo_mode == MODE_KILL));
@ -404,10 +358,6 @@ main(argc, argv)
if (def_ival(I_UMASK) != 0777)
(void) umask(def_mode(I_UMASK));
/* Replace the PATH envariable with a secure one. */
if (def_str(I_SECURE_PATH) && !user_is_exempt())
sudo_setenv("PATH", def_str(I_SECURE_PATH));
/* Restore coredumpsize resource limit. */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
(void) setrlimit(RLIMIT_CORE, &corelimit);
@ -416,10 +366,6 @@ main(argc, argv)
/* Become specified user or root. */
set_perms(PERM_RUNAS, sudo_mode);
/* Set $HOME for `sudo -H'. Only valid at PERM_RUNAS. */
if ((sudo_mode & MODE_RESET_HOME) && runas_homedir)
sudo_setenv("HOME", runas_homedir);
#ifndef PROFILING
if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
exit(0);
@ -475,7 +421,7 @@ init_vars(sudo_mode)
int sudo_mode;
{
char *p, thost[MAXHOSTNAMELEN];
int nohostname;
int nohostname, rval;
/* Sanity check command from user. */
if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) {
@ -542,6 +488,7 @@ init_vars(sudo_mode)
log_error(0, "uid %ld does not exist in the passwd file!",
(long) pw.pw_uid);
}
user_shell = sudo_user.pw->pw_shell;
/* It is now safe to use log_error() and set_perms() */
@ -586,10 +533,36 @@ init_vars(sudo_mode)
set_loginclass(sudo_user.pw);
/* Resolve the path and return. */
if ((sudo_mode & MODE_RUN))
return(find_path(NewArgv[0], &user_cmnd));
else
return(FOUND);
if ((sudo_mode & MODE_RUN)) {
rval = find_path(NewArgv[0], &user_cmnd, user_path);
/* set user_args */
if (NewArgc > 1) {
char *to, **from;
size_t size;
/* If MODE_SHELL not set then NewArgv is contiguous so just count */
if (!(sudo_mode & MODE_SHELL)) {
size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
strlen(NewArgv[NewArgc-1]) + 1;
} else {
for (size = 0, from = NewArgv + 1; *from; from++)
size += strlen(*from) + 1;
}
/* alloc and copy. */
to = user_args = (char *) emalloc(size);
for (from = NewArgv + 1; *from; from++) {
(void) strcpy(to, *from);
to += strlen(*from);
*to++ = ' ';
}
*--to = '\0';
}
} else
rval = FOUND;
return(rval);
}
/*
@ -748,70 +721,6 @@ parse_args()
return(rval);
}
/*
* Add sudo-specific variables into the environment.
* Sets ``cmnd_args'' as a side effect.
*/
static void
add_env(contiguous)
int contiguous;
{
char idstr[MAX_UID_T_LEN + 1];
size_t size;
char *buf;
/* Add the SUDO_COMMAND envariable (cmnd + args). */
size = strlen(user_cmnd) + 1;
if (NewArgc > 1) {
char *to, **from;
if (contiguous) {
size += (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
strlen(NewArgv[NewArgc-1]) + 1;
} else {
for (from = &NewArgv[1]; *from; from++)
size += strlen(*from) + 1;
}
buf = (char *) emalloc(size);
/*
* Copy the command and it's arguments info buf.
*/
(void) strcpy(buf, user_cmnd);
to = buf + strlen(user_cmnd);
for (from = &NewArgv[1]; *from; from++) {
*to++ = ' ';
(void) strcpy(to, *from);
to += strlen(*from);
}
} else {
buf = user_cmnd;
}
sudo_setenv("SUDO_COMMAND", buf);
if (NewArgc > 1)
free(buf);
/* Grab a pointer to the flat arg string from the environment. */
if (NewArgc > 1 && (user_args = getenv("SUDO_COMMAND"))) {
if ((user_args = strchr(user_args, ' ')))
user_args++;
else
user_args = NULL;
}
/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
sudo_setenv("SUDO_USER", user_name);
(void) sprintf(idstr, "%ld", (long) user_uid);
sudo_setenv("SUDO_UID", idstr);
(void) sprintf(idstr, "%ld", (long) user_gid);
sudo_setenv("SUDO_GID", idstr);
/* Set PS1 if SUDO_PS1 is set. */
if ((buf = getenv("SUDO_PS1")))
sudo_setenv("PS1", buf);
}
/*
* Sanity check sudoers mode/owner/type.
* Leaves a file pointer to the sudoers file open in ``fp''.
@ -862,6 +771,8 @@ check_sudoers()
log_error(USE_ERRNO, "can't stat %s", _PATH_SUDOERS);
else if (!S_ISREG(statbuf.st_mode))
log_error(0, "%s is not a regular file", _PATH_SUDOERS);
else if (statbuf.st_size == 0)
log_error(0, "%s is zero length", _PATH_SUDOERS);
else if ((statbuf.st_mode & 07777) != SUDOERS_MODE)
log_error(0, "%s is mode 0%o, should be 0%o", _PATH_SUDOERS,
(statbuf.st_mode & 07777), SUDOERS_MODE);
@ -891,55 +802,9 @@ check_sudoers()
set_perms(PERM_ROOT, 0); /* change back to root */
}
/*
* Remove environment variables that match the entries in badenv_table.
*/
static void
clean_env(envp, badenv_table, naughtyenv_table)
char **envp;
struct env_table *badenv_table;
struct env_table *naughtyenv_table;
{
struct env_table *entry;
char **cur;
/*
* Remove any envars that match entries in badenv_table.
*/
for (cur = envp; *cur; cur++) {
for (entry = badenv_table; entry->name; entry++) {
if (strncmp(*cur, entry->name, entry->len) == 0) {
/* Got a match so remove it. */
char **move;
for (move = cur; *move; move++)
*move = *(move + 1);
cur--;
break;
}
}
for (entry = naughtyenv_table; entry->name; entry++) {
if (strncmp(*cur, entry->name, entry->len) == 0 &&
strpbrk((const char *)cur, "/%") != NULL) {
/* Got a match so remove it. */
char **move;
for (move = cur; *move; move++)
*move = *(move + 1);
cur--;
break;
}
}
}
}
/*
* Close all open files (except std*) and turn off core dumps.
* Also sets the set_perms() pointer to the correct function.
*/
static void
initial_setup()
@ -987,6 +852,18 @@ initial_setup()
#else
(void) signal(SIGCHLD, reapchild);
#endif /* POSIX_SIGNALS */
/* Set set_perms pointer to the correct function */
#if defined(_SC_SAVED_IDS) && defined(_SC_VERSION)
if (sysconf(_SC_SAVED_IDS) == 1 && sysconf(_SC_VERSION) >= 199009)
set_perms = set_perms_saved_uid;
else
#endif
#ifdef HAVE_SETREUID
set_perms = set_perms_setreuid;
#else
set_perms = set_perms_fallback;
#endif
}
#ifdef HAVE_LOGIN_CAP_H

View File

@ -40,7 +40,7 @@ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
----vvvv flags. This allows users to determine for themselves
whether or not they are allowed to use ssssuuuuddddoooo.
ssssuuuuddddoooo can log both successful an unsuccessful attempts (as
ssssuuuuddddoooo can log both successful and unsuccessful attempts (as
well as errors) to _s_y_s_l_o_g(3), a log file, or both. By
default ssssuuuuddddoooo will log via _s_y_s_l_o_g(3) but this is changeable
at configure time or via the _s_u_d_o_e_r_s file.
@ -61,7 +61,7 @@ OOOOPPPPTTTTIIIIOOOONNNNSSSS
October 26, 2000 1.6.4 1
December 29, 2000 1.6.4 1
@ -107,7 +107,7 @@ sudo(1m) MAINTENANCE COMMANDS sudo(1m)
as defined in /etc/login.conf, or a single '-' charac­
ter. Specifying a _c_l_a_s_s of `-' indicates that the
command should be run restricted by the default login
capibilities for the user the command is run as. If
capabilities for the user the command is run as. If
the _c_l_a_s_s argument specifies an existing user class,
the command must be run as root, or the ssssuuuuddddoooo command
must be run from a shell that is already root. This
@ -127,7 +127,7 @@ sudo(1m) MAINTENANCE COMMANDS sudo(1m)
October 26, 2000 1.6.4 2
December 29, 2000 1.6.4 2
@ -182,18 +182,18 @@ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY NNNNOOOOTTTTE
only), and `LIBPATH' (AIX only) environment variables are
removed from the environment passed on to all commands
executed. ssssuuuuddddoooo will also remove the `IFS', `ENV',
`BASH_ENV', `KRB_CONF', `KRB5_CONFIG', `LOCALDOMAIN',
`RES_OPTIONS' and `HOSTALIASES' variables as they too can
pose a threat.
To prevent command spoofing, ssssuuuuddddoooo checks "." and "" (both
denoting current directory) last when searching for a com­
mand in the user's PATH (if one or both are in the PATH).
Note, however, that the actual `PATH' environment variable
`BASH_ENV', `KRB_CONF', `KRBCONFDIR', `KRBTKFILE',
`KRB5_CONFIG', `LOCALDOMAIN', `RES_OPTIONS', `HOSTAL­
IASES', `NLSPATH', `PATH_LOCALE', `TERMINFO', `TER­
MINFO_DIRS' and `TERMPATH' variables as they too can pose
a threat. If the `TERMCAP' variable is set and is a path­
name, it too is ignored. Additionally, if the `LC_*' or
`LANGUAGE' variables contain the `/' or `%' characters,
they are ignored. If ssssuuuuddddoooo has been compiled with SecurID
October 26, 2000 1.6.4 3
December 29, 2000 1.6.4 3
@ -202,6 +202,13 @@ October 26, 2000 1.6.4 3
sudo(1m) MAINTENANCE COMMANDS sudo(1m)
support, the `VAR_ACE', `USR_ACE' and `DLC_ACE' variables
are cleared as well.
To prevent command spoofing, ssssuuuuddddoooo checks "." and "" (both
denoting current directory) last when searching for a com­
mand in the user's PATH (if one or both are in the PATH).
Note, however, that the actual `PATH' environment variable
is _n_o_t modified and is passed unchanged to the program
that ssssuuuuddddoooo executes.
@ -216,8 +223,8 @@ sudo(1m) MAINTENANCE COMMANDS sudo(1m)
tents if it is not owned by root and only writable by
root. On systems that allow non-root users to give away
files via _c_h_o_w_n(2), if the timestamp directory is located
in a directory writable by anyone (eg: _/_t_m_p), it is possi­
ble for a user to create the timestamp directory before
in a directory writable by anyone (e.g.: _/_t_m_p), it is pos­
sible for a user to create the timestamp directory before
ssssuuuuddddoooo is run. However, because ssssuuuuddddoooo checks the ownership
and mode of the directory and its contents, the only dam­
age that can be done is to "hide" files by putting them in
@ -249,17 +256,10 @@ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
where the filesystem holding ~yazza is not exported as
root:
% sudo -u yazza ls ~yazza
To edit the _i_n_d_e_x_._h_t_m_l file as user www:
% sudo -u www vi ~www/htdocs/index.html
To shutdown a machine:
October 26, 2000 1.6.4 4
December 29, 2000 1.6.4 4
@ -268,6 +268,14 @@ October 26, 2000 1.6.4 4
sudo(1m) MAINTENANCE COMMANDS sudo(1m)
% sudo -u yazza ls ~yazza
To edit the _i_n_d_e_x_._h_t_m_l file as user www:
% sudo -u www vi ~www/htdocs/index.html
To shutdown a machine:
% sudo shutdown -r +15 "quick reboot"
To make a usage listing of the directories in the /home
@ -315,17 +323,9 @@ BBBBUUUUGGGGSSSS
If you feel you have found a bug in sudo, please submit a
bug report at http://www.courtesan.com/sudo/bugs/
DDDDIIIISSSSCCCCLLLLAAAAIIIIMMMMEEEERRRR
SSSSuuuuddddoooo is provided ``AS IS'' and any express or implied war­
ranties, including, but not limited to, the implied war­
ranties of merchantability and fitness for a particular
purpose are disclaimed. See the LICENSE file distributed
with ssssuuuuddddoooo for complete details.
October 26, 2000 1.6.4 5
December 29, 2000 1.6.4 5
@ -334,6 +334,13 @@ October 26, 2000 1.6.4 5
sudo(1m) MAINTENANCE COMMANDS sudo(1m)
DDDDIIIISSSSCCCCLLLLAAAAIIIIMMMMEEEERRRR
SSSSuuuuddddoooo is provided ``AS IS'' and any express or implied war­
ranties, including, but not limited to, the implied war­
ranties of merchantability and fitness for a particular
purpose are disclaimed. See the LICENSE file distributed
with ssssuuuuddddoooo for complete details.
CCCCAAAAVVVVEEEEAAAATTTTSSSS
There is no easy way to prevent a user from gaining a root
shell if that user has access to commands allowing shell
@ -384,13 +391,6 @@ SSSSEEEEEEEE AAAALLLLSSSSOOOO
October 26, 2000 1.6.4 6
December 29, 2000 1.6.4 6

21
sudo.h
View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994-1996,1998-2000 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1993-1996,1998-2000 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -47,6 +47,9 @@
*/
struct sudo_user {
struct passwd *pw;
struct passwd *_runas_pw;
char *path;
char *shell;
char *tty;
char cwd[MAXPATHLEN];
char *host;
@ -119,18 +122,20 @@ struct sudo_user {
#define user_passwd (sudo_user.pw->pw_passwd)
#define user_uid (sudo_user.pw->pw_uid)
#define user_gid (sudo_user.pw->pw_gid)
#define user_shell (sudo_user.pw->pw_shell)
#define user_dir (sudo_user.pw->pw_dir)
#define user_shell (sudo_user.shell)
#define user_tty (sudo_user.tty)
#define user_cwd (sudo_user.cwd)
#define user_runas (sudo_user.runas)
#define user_cmnd (sudo_user.cmnd)
#define user_args (sudo_user.cmnd_args)
#define user_path (sudo_user.path)
#define user_prompt (sudo_user.prompt)
#define user_host (sudo_user.host)
#define user_shost (sudo_user.shost)
#define safe_cmnd (sudo_user.cmnd_safe)
#define login_class (sudo_user.class_name)
#define runas_pw (sudo_user._runas_pw)
/*
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
@ -173,9 +178,6 @@ struct sudo_user {
#ifndef HAVE_GETCWD
char *getcwd __P((char *, size_t size));
#endif
#if !defined(HAVE_PUTENV) && !defined(HAVE_SETENV)
int putenv __P((const char *));
#endif
#ifndef HAVE_SNPRINTF
int snprintf __P((char *, size_t, const char *, ...));
#endif
@ -192,13 +194,14 @@ int vasprintf __P((char **, const char *, va_list));
int strcasecmp __P((const char *, const char *));
#endif
char *sudo_goodpath __P((const char *));
void sudo_setenv __P((char *, char *));
char *tgetpass __P((const char *, int, int));
int find_path __P((char *, char **));
int find_path __P((char *, char **, char *));
void check_user __P((void));
void verify_user __P((struct passwd *, char *));
int sudoers_lookup __P((int));
void set_perms __P((int, int));
void set_perms_saved_uid __P((int, int));
void set_perms_setreuid __P((int, int));
void set_perms_fallback __P((int, int));
void remove_timestamp __P((int));
int check_secureware __P((char *));
void sia_attempt_auth __P((void));
@ -228,6 +231,8 @@ extern int Argc;
extern char **Argv;
extern FILE *sudoers_fp;
extern int tgetpass_flags;
extern void (*set_perms) __P((int, int));
#endif
extern int errno;

View File

@ -1,5 +1,5 @@
.\" Automatically generated by Pod::Man version 1.04
.\" Thu Oct 26 11:02:49 2000
.\" Fri Dec 29 20:16:40 2000
.\"
.\" Standard preamble:
.\" ======================================================================
@ -138,7 +138,7 @@
.\" ======================================================================
.\"
.IX Title "sudo @mansectsu@"
.TH sudo @mansectsu@ "1.6.4" "October 26, 2000" "MAINTENANCE COMMANDS"
.TH sudo @mansectsu@ "1.6.4" "December 29, 2000" "MAINTENANCE COMMANDS"
.UC
.SH "NAME"
sudo \- execute a command as another user
@ -176,7 +176,7 @@ to run sudo with the \fB\-l\fR or \fB\-v\fR flags. This allows users to
determine for themselves whether or not they are allowed to use
\&\fBsudo\fR.
.PP
\&\fBsudo\fR can log both successful an unsuccessful attempts (as well
\&\fBsudo\fR can log both successful and unsuccessful attempts (as well
as errors) to \fIsyslog\fR\|(3), a log file, or both. By default \fBsudo\fR
will log via \fIsyslog\fR\|(3) but this is changeable at configure time
or via the \fIsudoers\fR file.
@ -236,7 +236,7 @@ with resources limited by the specified login class. The \fIclass\fR
argument can be either a class name as defined in /etc/login.conf,
or a single '\-' character. Specifying a \fIclass\fR of \f(CW\*(C`\-\*(C'\fR indicates
that the command should be run restricted by the default login
capibilities for the user the command is run as. If the \fIclass\fR
capabilities for the user the command is run as. If the \fIclass\fR
argument specifies an existing user class, the command must be run
as root, or the \fBsudo\fR command must be run from a shell that is already
root. This option is only available on systems with \s-1BSD\s0 login classes
@ -296,9 +296,15 @@ to subvert the program that \fBsudo\fR runs. To combat this the
\&\f(CW\*(C`LD_*\*(C'\fR, \f(CW\*(C`_RLD_*\*(C'\fR, \f(CW\*(C`SHLIB_PATH\*(C'\fR (\s-1HP-UX\s0 only), and \f(CW\*(C`LIBPATH\*(C'\fR (\s-1AIX\s0
only) environment variables are removed from the environment passed
on to all commands executed. \fBsudo\fR will also remove the \f(CW\*(C`IFS\*(C'\fR,
\&\f(CW\*(C`ENV\*(C'\fR, \f(CW\*(C`BASH_ENV\*(C'\fR, \f(CW\*(C`KRB_CONF\*(C'\fR, \f(CW\*(C`KRB5_CONFIG\*(C'\fR, \f(CW\*(C`LOCALDOMAIN\*(C'\fR,
\&\f(CW\*(C`RES_OPTIONS\*(C'\fR and \f(CW\*(C`HOSTALIASES\*(C'\fR variables as they too can pose a
threat.
\&\f(CW\*(C`ENV\*(C'\fR, \f(CW\*(C`BASH_ENV\*(C'\fR, \f(CW\*(C`KRB_CONF\*(C'\fR, \f(CW\*(C`KRBCONFDIR\*(C'\fR, \f(CW\*(C`KRBTKFILE\*(C'\fR,
\&\f(CW\*(C`KRB5_CONFIG\*(C'\fR, \f(CW\*(C`LOCALDOMAIN\*(C'\fR, \f(CW\*(C`RES_OPTIONS\*(C'\fR, \f(CW\*(C`HOSTALIASES\*(C'\fR,
\&\f(CW\*(C`NLSPATH\*(C'\fR, \f(CW\*(C`PATH_LOCALE\*(C'\fR, \f(CW\*(C`TERMINFO\*(C'\fR, \f(CW\*(C`TERMINFO_DIRS\*(C'\fR and
\&\f(CW\*(C`TERMPATH\*(C'\fR variables as they too can pose a threat. If the
\&\f(CW\*(C`TERMCAP\*(C'\fR variable is set and is a pathname, it too is ignored.
Additionally, if the \f(CW\*(C`LC_*\*(C'\fR or \f(CW\*(C`LANGUAGE\*(C'\fR variables contain the
\&\f(CW\*(C`/\*(C'\fR or \f(CW\*(C`%\*(C'\fR characters, they are ignored. If \fBsudo\fR has been
compiled with SecurID support, the \f(CW\*(C`VAR_ACE\*(C'\fR, \f(CW\*(C`USR_ACE\*(C'\fR and
\&\f(CW\*(C`DLC_ACE\*(C'\fR variables are cleared as well.
.PP
To prevent command spoofing, \fBsudo\fR checks \*(L".\*(R" and "" (both denoting
current directory) last when searching for a command in the user's
@ -315,7 +321,7 @@ behavior or link \fBsudo\fR statically.
(\fI@timedir@\fR by default) and ignore the directory's contents if
it is not owned by root and only writable by root. On systems that
allow non-root users to give away files via \fIchown\fR\|(2), if the timestamp
directory is located in a directory writable by anyone (eg: \fI/tmp\fR),
directory is located in a directory writable by anyone (e.g.: \fI/tmp\fR),
it is possible for a user to create the timestamp directory before
\&\fBsudo\fR is run. However, because \fBsudo\fR checks the ownership and
mode of the directory and its contents, the only damage that can

View File

@ -218,9 +218,15 @@ to subvert the program that B<sudo> runs. To combat this the
C<LD_*>, C<_RLD_*>, C<SHLIB_PATH> (HP-UX only), and C<LIBPATH> (AIX
only) environment variables are removed from the environment passed
on to all commands executed. B<sudo> will also remove the C<IFS>,
C<ENV>, C<BASH_ENV>, C<KRB_CONF>, C<KRB5_CONFIG>, C<LOCALDOMAIN>,
C<RES_OPTIONS> and C<HOSTALIASES> variables as they too can pose a
threat.
C<ENV>, C<BASH_ENV>, C<KRB_CONF>, C<KRBCONFDIR>, C<KRBTKFILE>,
C<KRB5_CONFIG>, C<LOCALDOMAIN>, C<RES_OPTIONS>, C<HOSTALIASES>,
C<NLSPATH>, C<PATH_LOCALE>, C<TERMINFO>, C<TERMINFO_DIRS> and
C<TERMPATH> variables as they too can pose a threat. If the
C<TERMCAP> variable is set and is a pathname, it too is ignored.
Additionally, if the C<LC_*> or C<LANGUAGE> variables contain the
C</> or C<%> characters, they are ignored. If B<sudo> has been
compiled with SecurID support, the C<VAR_ACE>, C<USR_ACE> and
C<DLC_ACE> variables are cleared as well.
To prevent command spoofing, B<sudo> checks "." and "" (both denoting
current directory) last when searching for a command in the user's

View File

@ -61,7 +61,7 @@ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
September 6, 2000 1.6.4 1
December 29, 2000 1.6.4 1
@ -127,7 +127,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
September 6, 2000 1.6.4 2
December 29, 2000 1.6.4 2
@ -193,7 +193,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
September 6, 2000 1.6.4 3
December 29, 2000 1.6.4 3
@ -259,7 +259,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
September 6, 2000 1.6.4 4
December 29, 2000 1.6.4 4
@ -325,7 +325,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
September 6, 2000 1.6.4 5
December 29, 2000 1.6.4 5
@ -375,7 +375,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
get all aliases from DNS. If your machine's
hostname (as returned by the `hostname' com­
mand) is already fully qualified you shouldn't
need to set _f_q_f_n. This flag is _o_f_f by
need to set _f_q_d_n. This flag is _o_f_f by
default.
insults If set, ssssuuuuddddoooo will insult users when they enter
@ -391,7 +391,7 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
September 6, 2000 1.6.4 6
December 29, 2000 1.6.4 6
@ -440,6 +440,36 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
this behavior. This can be done by negating
the set_logname option.
stay_setuid Normally, when ssssuuuuddddoooo executes a command the
real and effective UIDs are set to the target
user (root by default). This option changes
that behavior such that the real UID is left
as the invoking user's UID. In other words,
this makes ssssuuuuddddoooo act as a setuid wrapper. This
can be useful on systems that disable some
potentially dangerous functionality when a
program is run setuid.
env_reset If set, ssssuuuuddddoooo will reset the environment to
only contain the following variables: `HOME',
`SHELL', `LOGNAME', and `USER' (in addition to
the `SUDO_*' variables). The `PATH'
December 29, 2000 1.6.4 7
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
environment variable is preserved unaltered.
Other specific variables may be preserved with
the i<env_keep> option.
use_loginclass
If set, ssssuuuuddddoooo will apply the defaults specified
for the target user's login class if one
@ -454,18 +484,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
his/her password before ssssuuuuddddoooo logs the failure
and exits. The default is `3'.
September 6, 2000 1.6.4 7
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
IIIInnnntttteeeeggggeeeerrrrssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt:
loglinelen Number of characters per line for the file
@ -486,9 +504,9 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
prompt times out. The default is `5', set
this to `0' for no password timeout.
umask Umask to use when running the root command.
Set this to 0777 to not override the user's
umask. The default is `0022'.
umask Umask to use when running the command. Negate
this option or set it to 0777 to preserve the
user's umask. The default is `0022'.
SSSSttttrrrriiiinnnnggggssss:
@ -502,6 +520,18 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
incorrect password. The default is `Sorry,
try again.' unless insults are enabled.
December 29, 2000 1.6.4 8
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
timestampdir
The directory in which ssssuuuuddddoooo stores its times­
tamp files. The default is _/_v_a_r_/_r_u_n_/_s_u_d_o.
@ -519,19 +549,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
flag is not specified on the command line.
This defaults to `root'.
September 6, 2000 1.6.4 8
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
syslog_goodpri
Syslog priority to use when user authenticates
successfully. Defaults to `notice'.
@ -540,6 +557,16 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
Syslog priority to use when user authenticates
unsuccessfully. Defaults to `alert'.
env_keep A double-quoted, space-separated list of envi­
ronment variables to be preserved in the
user's environment. When used in conjuction
with the _e_n_v___r_e_s_e_t option, this allows fine
control over the environment ssssuuuuddddoooo-spawned pro­
cesses will get. If the _e_n_v___r_e_s_e_t option is
not used, _e_n_v___k_e_e_p can be used to make excep­
tions to the built in list of "dangerous"
environment variables.
editor A colon (':') separated list of editors
allowed to be used with vvvviiiissssuuuuddddoooo. vvvviiiissssuuuuddddoooo will
choose the editor that matches the user's USER
@ -558,6 +585,19 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
logging (negate to disable syslog logging).
Defaults to `local2'.
December 29, 2000 1.6.4 9
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
mailerpath Path to mail program used to send warning
mail. Defaults to the path to sendmail found
at configure time.
@ -566,7 +606,9 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
----tttt.
mailto Address to send warning and erorr mail to.
Defaults to `root'.
The address should be enclosed in double
quotes (`"') to protect against sudo inter­
preting the `@' sign. Defaults to `root'.
exempt_group
Users in this group are exempt from password
@ -584,20 +626,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
required when a user runs ssssuuuuddddoooo with the ----vvvv
flag. It has the following possible values:
September 6, 2000 1.6.4 9
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
all All the user's I<sudoers> entries for the
current host must have the C<NOPASSWD>
flag set to avoid entering a password.
@ -623,6 +651,19 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
current host must have the C<NOPASSWD>
flag set to avoid entering a password.
December 29, 2000 1.6.4 10
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
any At least one of the user's I<sudoers> entries
for the current host must have the
C<NOPASSWD> flag set to avoid entering a
@ -652,18 +693,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List
September 6, 2000 1.6.4 10
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
Runas_Spec ::= '(' Runas_List ')'
@ -689,6 +718,18 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
The user ddddggggbbbb may run _/_b_i_n_/_l_s, _/_b_i_n_/_k_i_l_l, and _/_u_s_r_/_b_i_n_/_l_p_r_m
-- but only as ooooppppeeeerrrraaaattttoooorrrr. Eg.
December 29, 2000 1.6.4 11
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
sudo -u operator /bin/ls.
It is also possible to override a `Runas_Spec' later on in
@ -718,18 +759,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
September 6, 2000 1.6.4 11
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
Note however, that the `PASSWD' tag has no effect on users
who are in the group specified by the exempt_group option.
@ -754,6 +783,19 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
`[...]' Matches any character in the specified range.
December 29, 2000 1.6.4 12
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
`[!...]'
Matches any character nnnnooootttt in the specified range.
@ -784,18 +826,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
it occurs in the context of a user name and is followed by
one or more digits, in which case it is treated as a uid).
Both the comment character and any text after it, up to
September 6, 2000 1.6.4 12
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
the end of the line, are ignored.
The reserved word AAAALLLLLLLL is a built in _a_l_i_a_s that always
@ -821,6 +851,17 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
syntactic characters in a _U_s_e_r _S_p_e_c_i_f_i_c_a_t_i_o_n ('=', ':',
'(', ')') is optional.
December 29, 2000 1.6.4 13
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
The following characters must be escaped with a backslash
('\') when used as part of a word (eg. a username or host­
name): '@', '!', '=', ':', ',', '(', ')', '\'.
@ -848,20 +889,6 @@ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
Host_Alias SERVERS = master, mail, www, ns
Host_Alias CDROM = orion, perseus, hercules
September 6, 2000 1.6.4 13
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
# Cmnd alias specification
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
/usr/sbin/restore, /usr/sbin/rrestore
@ -884,12 +911,23 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
make sure we log the year in each log line since the log
entries will be kept around for several years.
# Override builtin defaults
# Override built in defaults
Defaults syslog=auth
Defaults:FULLTIMERS !lecture
Defaults:millert !authenticate
Defaults@SERVERS log_year, logfile=/var/log/sudo.log
December 29, 2000 1.6.4 14
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
The _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually deter­
mines who may run what.
@ -916,18 +954,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
_C_S_N_E_T_S alias (the networks `128.138.243.0',
`128.138.204.0', and `128.138.242.0'). Of those networks,
only <128.138.204.0> has an explicit netmask (in CIDR
September 6, 2000 1.6.4 14
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
notation) indicating it is a class C network. For the
other networks in _C_S_N_E_T_S, the local machine's netmask will
be used during matching.
@ -956,6 +982,18 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
assumes _p_a_s_s_w_d(1) does not take multiple usernames on the
command line.
December 29, 2000 1.6.4 15
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
bob SPARC = (OP) ALL : SGI = (OP) ALL
The user bbbboooobbbb may run anything on the _S_P_A_R_C and _S_G_I
@ -982,18 +1020,6 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
September 6, 2000 1.6.4 15
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
On the _A_L_P_H_A machines, user jjjjoooohhhhnnnn may su to anyone except
root but he is not allowed to give _s_u(1) any flags.
@ -1022,6 +1048,18 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4)
WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
On the host www, any user in the _W_E_B_M_A_S_T_E_R_S `User_Alias'
December 29, 2000 1.6.4 16
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
(will, wendy, and wim), may run any command as user www
(which owns the web pages) or simply _s_u(1) to www.
@ -1049,17 +1087,6 @@ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY NNNNOOOOTTTTE
restrictions should be considered advisory at best (and
reinforced by policy).
September 6, 2000 1.6.4 16
sudoers(4) MAINTENANCE COMMANDS sudoers(4)
CCCCAAAAVVVVEEEEAAAATTTTSSSS
The _s_u_d_o_e_r_s file should aaaallllwwwwaaaayyyyssss be edited by the vvvviiiissssuuuuddddoooo
command which locks the file and does grammatical check­
@ -1090,33 +1117,6 @@ SSSSEEEEEEEE AAAALLLLSSSSOOOO
September 6, 2000 1.6.4 17
December 29, 2000 1.6.4 17

View File

@ -1,5 +1,5 @@
.\" Automatically generated by Pod::Man version 1.04
.\" Wed Sep 6 19:34:51 2000
.\" Fri Dec 29 20:29:02 2000
.\"
.\" Standard preamble:
.\" ======================================================================
@ -138,7 +138,7 @@
.\" ======================================================================
.\"
.IX Title "sudoers @mansectform@"
.TH sudoers @mansectform@ "1.6.4" "September 6, 2000" "MAINTENANCE COMMANDS"
.TH sudoers @mansectform@ "1.6.4" "December 29, 2000" "MAINTENANCE COMMANDS"
.UC
.SH "NAME"
sudoers \- list of which users may execute what
@ -441,7 +441,7 @@ you may not use a host alias (\f(CW\*(C`CNAME\*(C'\fR entry) due to performance
issues and the fact that there is no way to get all aliases from
\&\s-1DNS\s0. If your machine's hostname (as returned by the \f(CW\*(C`hostname\*(C'\fR
command) is already fully qualified you shouldn't need to set
\&\fIfqfn\fR. This flag is \fI@fqdn@\fR by default.
\&\fIfqdn\fR. This flag is \fI@fqdn@\fR by default.
.Ip "insults" 12
.IX Item "insults"
If set, \fBsudo\fR will insult users when they enter an incorrect
@ -485,6 +485,21 @@ to the name of the target user (usually root unless the \fB\-u\fR flag is given)
However, since some programs (including the \s-1RCS\s0 revision control system)
use \f(CW\*(C`LOGNAME\*(C'\fR to determine the real identity of the user, it may be desirable
to change this behavior. This can be done by negating the set_logname option.
.Ip "stay_setuid" 12
.IX Item "stay_setuid"
Normally, when \fBsudo\fR executes a command the real and effective
UIDs are set to the target user (root by default). This option
changes that behavior such that the real \s-1UID\s0 is left as the invoking
user's \s-1UID\s0. In other words, this makes \fBsudo\fR act as a setuid
wrapper. This can be useful on systems that disable some potentially
dangerous functionality when a program is run setuid.
.Ip "env_reset" 12
.IX Item "env_reset"
If set, \fBsudo\fR will reset the environment to only contain the
following variables: \f(CW\*(C`HOME\*(C'\fR, \f(CW\*(C`SHELL\*(C'\fR, \f(CW\*(C`LOGNAME\*(C'\fR, and \f(CW\*(C`USER\*(C'\fR
(in addition to the \f(CW\*(C`SUDO_*\*(C'\fR variables). The \f(CW\*(C`PATH\*(C'\fR environment
variable is preserved unaltered. Other specific variables
may be preserved with the i<env_keep> option.
.Ip "use_loginclass" 12
.IX Item "use_loginclass"
If set, \fBsudo\fR will apply the defaults specified for the target user's
@ -515,8 +530,8 @@ Number of minutes before the \fBsudo\fR password prompt times out.
The default is \f(CW\*(C`@password_timeout@\*(C'\fR, set this to \f(CW\*(C`0\*(C'\fR for no password timeout.
.Ip "umask" 12
.IX Item "umask"
Umask to use when running the root command. Set this to 0777 to
not override the user's umask. The default is \f(CW\*(C`@sudo_umask@\*(C'\fR.
Umask to use when running the command. Negate this option or set
it to 0777 to preserve the user's umask. The default is \f(CW\*(C`@sudo_umask@\*(C'\fR.
.PP
\&\fBStrings\fR:
.Ip "mailsub" 12
@ -550,6 +565,14 @@ Defaults to \f(CW\*(C`@goodpri@\*(C'\fR.
.IX Item "syslog_badpri"
Syslog priority to use when user authenticates unsuccessfully.
Defaults to \f(CW\*(C`@badpri@\*(C'\fR.
.Ip "env_keep" 12
.IX Item "env_keep"
A double-quoted, space-separated list of environment variables
to be preserved in the user's environment. When used in conjuction
with the \fIenv_reset\fR option, this allows fine control over the
environment \fBsudo\fR\-spawned processes will get. If the \fIenv_reset\fR
option is not used, \fIenv_keep\fR can be used to make exceptions to
the built in list of \*(L"dangerous\*(R" environment variables.
.Ip "editor" 12
.IX Item "editor"
A colon (':') separated list of editors allowed to be used with
@ -576,7 +599,9 @@ Defaults to the path to sendmail found at configure time.
Flags to use when invoking mailer. Defaults to \fB\-t\fR.
.Ip "mailto" 12
.IX Item "mailto"
Address to send warning and erorr mail to. Defaults to \f(CW\*(C`@mailto@\*(C'\fR.
Address to send warning and erorr mail to. The address should
be enclosed in double quotes (\f(CW\*(C`"\*(C'\fR) to protect against sudo
interpreting the \f(CW\*(C`@\*(C'\fR sign. Defaults to \f(CW\*(C`@mailto@\*(C'\fR.
.Ip "exempt_group" 12
.IX Item "exempt_group"
Users in this group are exempt from password and \s-1PATH\s0 requirements.
@ -842,7 +867,7 @@ local log file and make sure we log the year in each log line since
the log entries will be kept around for several years.
.PP
.Vb 5
\& # Override builtin defaults
\& # Override built in defaults
\& Defaults syslog=auth
\& Defaults:FULLTIMERS !lecture
\& Defaults:millert !authenticate

View File

@ -398,6 +398,23 @@ However, since some programs (including the RCS revision control system)
use C<LOGNAME> to determine the real identity of the user, it may be desirable
to change this behavior. This can be done by negating the set_logname option.
=item stay_setuid
Normally, when B<sudo> executes a command the real and effective
UIDs are set to the target user (root by default). This option
changes that behavior such that the real UID is left as the invoking
user's UID. In other words, this makes B<sudo> act as a setuid
wrapper. This can be useful on systems that disable some potentially
dangerous functionality when a program is run setuid.
=item env_reset
If set, B<sudo> will reset the environment to only contain the
following variables: C<HOME>, C<SHELL>, C<LOGNAME>, and C<USER>
(in addition to the C<SUDO_*> variables). The C<PATH> environment
variable is preserved unaltered. Other specific variables
may be preserved with the i<env_keep> option.
=item use_loginclass
If set, B<sudo> will apply the defaults specified for the target user's
@ -488,6 +505,15 @@ Defaults to C<@goodpri@>.
Syslog priority to use when user authenticates unsuccessfully.
Defaults to C<@badpri@>.
=item env_keep
A double-quoted, space-separated list of environment variables
to be preserved in the user's environment. When used in conjuction
with the I<env_reset> option, this allows fine control over the
environment B<sudo>-spawned processes will get. If the I<env_reset>
option is not used, I<env_keep> can be used to make exceptions to
the built in list of "dangerous" environment variables.
=item editor
A colon (':') separated list of editors allowed to be used with
@ -523,7 +549,9 @@ Flags to use when invoking mailer. Defaults to B<-t>.
=item mailto
Address to send warning and erorr mail to. Defaults to C<@mailto@>.
Address to send warning and erorr mail to. The address should
be enclosed in double quotes (C<">) to protect against sudo
interpreting the C<@> sign. Defaults to C<@mailto@>.
=item exempt_group
@ -792,7 +820,7 @@ machines in the I<SERVERS> C<Host_Alias>, we keep an additional
local log file and make sure we log the year in each log line since
the log entries will be kept around for several years.
# Override builtin defaults
# Override built in defaults
Defaults syslog=auth
Defaults:FULLTIMERS !lecture
Defaults:millert !authenticate

View File

@ -80,6 +80,14 @@
static const char rcsid[] = "$Sudo$";
#endif /* lint */
/*
* Prototypes
*/
void init_parser __P((void));
void dumpaliases __P((void));
void set_perms_dummy __P((int, int));
/*
* Globals
*/
@ -89,15 +97,10 @@ int parse_error = FALSE;
int num_interfaces;
struct interface *interfaces;
struct sudo_user sudo_user;
void (*set_perms) __P((int, int)) = set_perms_dummy;
extern int clearaliases;
extern int pedantic;
/*
* Prototypes for external functions
*/
void init_parser __P((void));
void dumpaliases __P((void));
/*
* Returns TRUE if "s" has shell meta characters in it,
* else returns FALSE.
@ -298,7 +301,7 @@ netgr_matches(netgr, host, shost, user)
}
void
set_perms(i, j)
set_perms_dummy(i, j)
int i, j;
{
return;

View File

@ -239,7 +239,7 @@ main(argc, argv)
if (UserEditor && *UserEditor == '\0')
UserEditor = NULL;
else if (UserEditor) {
if (find_path(UserEditor, &Editor) == FOUND) {
if (find_path(UserEditor, &Editor, getenv("PATH")) == FOUND) {
UserEditor = Editor;
} else {
if (def_flag(I_ENV_EDITOR)) {

View File

@ -19,7 +19,7 @@ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
later.
There is a hard-coded list of editors that vvvviiiissssuuuuddddoooo will use
set at compile time that may be overridden via the _e_d_i_t_o_r
set at compile-time that may be overridden via the _e_d_i_t_o_r
_s_u_d_o_e_r_s `Default' variable. This list defaults to the
path to _v_i(1) on your system, as determined by the _c_o_n_f_i_g_­
_u_r_e script. Normally, vvvviiiissssuuuuddddoooo does not honor the `EDITOR'
@ -34,22 +34,21 @@ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
vvvviiiissssuuuuddddoooo parses the _s_u_d_o_e_r_s file after the edit and will not
save the changes if there is a syntax error. Upon finding
an error, a message will be printed stating the line
an error, vvvviiiissssuuuuddddoooo will print a message stating the line
_n_u_m_b_e_r(s) where the error occurred and the user will
receive the "What now?" prompt. At this point the user
may enter "e" to re-edit the _s_u_d_o_e_r_s file, enter "x" to
exit without saving the changes, or "Q" to quit and save
may enter "e" to re-edit the _s_u_d_o_e_r_s file, "x" to exit
without saving the changes, or "Q" to quit and save
changes. The "Q" option should be used with extreme care
because if vvvviiiissssuuuuddddoooo believes there to be a parse error, so
will ssssuuuuddddoooo and no one will be able to execute ssssuuuuddddoooo again
until the error is fixed. Any other command at this
prompt will print a short help message. When editing the
_s_u_d_o_e_r_s file after a parse error has been detected the
cursor will be placed on the line where the error occurred
(if the editor supports this feature).
will ssssuuuuddddoooo and no one will be able to ssssuuuuddddoooo again until the
error is fixed. If "e" is typed to edit the _s_u_d_o_e_r_s file
after a parse error has been detected, the cursor will be
placed on the line where the error occurred (if the editor
supports this feature).
OOOOPPPPTTTTIIIIOOOONNNNSSSS
vvvviiiissssuuuuddddoooo accepts the following command line option:
vvvviiiissssuuuuddddoooo accepts the following command line options:
-s Enable ssssttttrrrriiiicccctttt checking of the _s_u_d_o_e_r_s file. If an
alias is used before it is defined, vvvviiiissssuuuuddddoooo will con­
@ -61,7 +60,8 @@ OOOOPPPPTTTTIIIIOOOONNNNSSSS
August 13, 2000 1.6.4 1
December 29, 2000 1.6.4 1
@ -70,7 +70,7 @@ August 13, 2000 1.6.4 1
visudo(1m) MAINTENANCE COMMANDS visudo(1m)
-V The ----VVVV (version) option causes vvvviiiissssuuuuddddoooo to print the
-V The ----VVVV (version) option causes vvvviiiissssuuuuddddoooo to print its
version number and exit.
EEEERRRRRRRROOOORRRRSSSS
@ -89,15 +89,15 @@ EEEERRRRRRRROOOORRRRSSSS
listed that consists solely of upper case letters,
digits, and the underscore ('_') character. If the
latter, you can ignore the warnings (ssssuuuuddddoooo will not
complain). In ----ssss (strict) mode these are errors not
complain). In ----ssss (strict) mode these are errors, not
warnings.
EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT
The following environment variables are used only if
vvvviiiissssuuuuddddoooo was configured with the _-_-_w_i_t_h_-_e_n_v_-_e_d_i_t_o_r option:
EDITOR Used by visudo as the editor to use
VISUAL Used by visudo if EDITOR is not set
EDITOR Invoked by visudo as the editor to use
VISUAL Used Invoked visudo if EDITOR is not set
FFFFIIIILLLLEEEESSSS
@ -106,12 +106,13 @@ FFFFIIIILLLLEEEESSSS
AAAAUUUUTTTTHHHHOOOORRRR
Many people have worked on _s_u_d_o over the years, this ver­
Many people have worked on _s_u_d_o over the years; this ver­
sion of vvvviiiissssuuuuddddoooo was written by:
Todd Miller <Todd.Miller@courtesan.com>
See the HISTORY file in the sudo distribution for more
See the HISTORY file in the sudo distribution or visit
http://www.courtesan.com/sudo/history.html for more
details.
BBBBUUUUGGGGSSSS
@ -123,11 +124,10 @@ DDDDIIIISSSSCCCCLLLLAAAAIIIIMMMMEEEERRRR
warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular
purpose are disclaimed. See the LICENSE file distributed
with ssssuuuuddddoooo for complete details.
August 13, 2000 1.6.4 2
December 29, 2000 1.6.4 2
@ -136,6 +136,8 @@ August 13, 2000 1.6.4 2
visudo(1m) MAINTENANCE COMMANDS visudo(1m)
with ssssuuuuddddoooo for complete details.
CCCCAAAAVVVVEEEEAAAATTTTSSSS
There is no easy way to prevent a user from gaining a root
shell if the editor used by vvvviiiissssuuuuddddoooo allows shell escapes.
@ -191,8 +193,6 @@ SSSSEEEEEEEE AAAALLLLSSSSOOOO
August 13, 2000 1.6.4 3
December 29, 2000 1.6.4 3

View File

@ -1,5 +1,5 @@
.\" Automatically generated by Pod::Man version 1.04
.\" Sun Aug 13 14:54:27 2000
.\" Fri Dec 29 20:16:41 2000
.\"
.\" Standard preamble:
.\" ======================================================================
@ -138,7 +138,7 @@
.\" ======================================================================
.\"
.IX Title "visudo @mansectsu@"
.TH visudo @mansectsu@ "1.6.4" "August 13, 2000" "MAINTENANCE COMMANDS"
.TH visudo @mansectsu@ "1.6.4" "December 29, 2000" "MAINTENANCE COMMANDS"
.UC
.SH "NAME"
visudo \- edit the sudoers file
@ -154,7 +154,7 @@ for parse errors. If the \fIsudoers\fR file is currently being
edited you will receive a message to try again later.
.PP
There is a hard-coded list of editors that \fBvisudo\fR will use set
at compile time that may be overridden via the \fIeditor\fR \fIsudoers\fR
at compile-time that may be overridden via the \fIeditor\fR \fIsudoers\fR
\&\f(CW\*(C`Default\*(C'\fR variable. This list defaults to the path to \fIvi\fR\|(1) on
your system, as determined by the \fIconfigure\fR script. Normally,
\&\fBvisudo\fR does not honor the \f(CW\*(C`EDITOR\*(C'\fR or \f(CW\*(C`VISUAL\*(C'\fR environment
@ -167,21 +167,20 @@ execute any program they wish simply by setting \f(CW\*(C`EDITOR\*(C'\fR or \f(C
.PP
\&\fBvisudo\fR parses the \fIsudoers\fR file after the edit and will
not save the changes if there is a syntax error. Upon finding
an error, a message will be printed stating the line \fInumber\fR\|(s)
an error, \fBvisudo\fR will print a message stating the line \fInumber\fR\|(s)
where the error occurred and the user will receive the
\&\*(L"What now?\*(R" prompt. At this point the user may enter \*(L"e\*(R"
to re-edit the \fIsudoers\fR file, enter \*(L"x\*(R" to exit without
to re-edit the \fIsudoers\fR file, \*(L"x\*(R" to exit without
saving the changes, or \*(L"Q\*(R" to quit and save changes. The
\&\*(L"Q\*(R" option should be used with extreme care because if \fBvisudo\fR
believes there to be a parse error, so will \fBsudo\fR and no one
will be able to execute \fBsudo\fR again until the error is fixed.
Any other command at this prompt will print a short help message.
When editing the \fIsudoers\fR file after a parse error has been
detected the cursor will be placed on the line where the error
occurred (if the editor supports this feature).
will be able to \fBsudo\fR again until the error is fixed.
If \*(L"e\*(R" is typed to edit the \fIsudoers\fR file after a parse error
has been detected, the cursor will be placed on the line where the
error occurred (if the editor supports this feature).
.SH "OPTIONS"
.IX Header "OPTIONS"
\&\fBvisudo\fR accepts the following command line option:
\&\fBvisudo\fR accepts the following command line options:
.Ip "\-s" 4
.IX Item "-s"
Enable \fBstrict\fR checking of the \fIsudoers\fR file. If an alias is
@ -191,7 +190,7 @@ alias and a hostname or username that consists solely of upper case
letters, digits, and the underscore ('_') character.
.Ip "\-V" 4
.IX Item "-V"
The \fB\-V\fR (version) option causes \fBvisudo\fR to print the version number
The \fB\-V\fR (version) option causes \fBvisudo\fR to print its version number
and exit.
.SH "ERRORS"
.IX Header "ERRORS"
@ -211,15 +210,15 @@ defining it or you have a user or hostname listed that
consists solely of upper case letters, digits, and the
underscore ('_') character. If the latter, you can ignore
the warnings (\fBsudo\fR will not complain). In \fB\-s\fR (strict)
mode these are errors not warnings.
mode these are errors, not warnings.
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
The following environment variables are used only if \fBvisudo\fR
was configured with the \fI\*(--with-env-editor\fR option:
.PP
.Vb 2
\& EDITOR Used by visudo as the editor to use
\& VISUAL Used by visudo if EDITOR is not set
\& EDITOR Invoked by visudo as the editor to use
\& VISUAL Used Invoked visudo if EDITOR is not set
.Ve
.SH "FILES"
.IX Header "FILES"
@ -229,13 +228,14 @@ was configured with the \fI\*(--with-env-editor\fR option:
.Ve
.SH "AUTHOR"
.IX Header "AUTHOR"
Many people have worked on \fIsudo\fR over the years, this version of
Many people have worked on \fIsudo\fR over the years; this version of
\&\fBvisudo\fR was written by:
.PP
.Vb 1
\& Todd Miller <Todd.Miller@courtesan.com>
.Ve
See the \s-1HISTORY\s0 file in the sudo distribution for more details.
See the \s-1HISTORY\s0 file in the sudo distribution or visit
http://www.courtesan.com/sudo/history.html for more details.
.SH "BUGS"
.IX Header "BUGS"
If you feel you have found a bug in sudo, please submit a bug report