From 998631b73abd193657e3c4db30bd56e2b049e078 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 30 Dec 2000 03:29:47 +0000 Subject: [PATCH] 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) --- CHANGES | 62 ++++- Makefile.in | 15 +- check.c | 2 +- compat.h | 8 + config.h.in | 9 +- configure | 646 +++++++++++++++++++++++-------------------------- configure.in | 16 +- defaults.c | 6 + defaults.h | 44 ++-- env.c | 372 ++++++++++++++++++++++++++++ find_path.c | 12 +- getspwuid.c | 12 +- set_perms.c | 319 ++++++++++++++---------- sudo.c | 291 +++++++--------------- sudo.cat | 76 +++--- sudo.h | 21 +- sudo.man.in | 22 +- sudo.pod | 12 +- sudoers.cat | 328 ++++++++++++------------- sudoers.man.in | 39 ++- sudoers.pod | 32 ++- testsudoers.c | 17 +- visudo.c | 2 +- visudo.cat | 46 ++-- visudo.man.in | 34 +-- 25 files changed, 1431 insertions(+), 1012 deletions(-) create mode 100644 env.c diff --git a/CHANGES b/CHANGES index 52358b1eb..70b49f69b 100644 --- a/CHANGES +++ b/CHANGES @@ -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. diff --git a/Makefile.in b/Makefile.in index bdfef1153..dd0372d1f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/check.c b/check.c index ada8f002c..8e4171efe 100644 --- a/check.c +++ b/check.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994-1996,1998-1999 Todd C. Miller + * Copyright (c) 1993-1996,1998-1999 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/compat.h b/compat.h index 445a5b0e2..fb3eeb728 100644 --- a/compat.h +++ b/compat.h @@ -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. */ diff --git a/config.h.in b/config.h.in index f73040772..10fa96bd6 100644 --- a/config.h.in +++ b/config.h.in @@ -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 diff --git a/configure b/configure index 8beea4933..54f814bfb 100755 --- a/configure +++ b/configure @@ -4121,6 +4121,18 @@ fi 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" @@ -4137,12 +4149,12 @@ test -n "$mansectform" || mansectform=5 if test "$CHECKSHADOW" = "true"; then echo $ac_n "checking for getspnam""... $ac_c" 1>&6 -echo "configure:4141: checking for getspnam" >&5 +echo "configure:4153: checking for getspnam" >&5 if eval "test \"`echo '$''{'ac_cv_func_getspnam'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getspnam=yes" else @@ -4190,12 +4202,12 @@ fi fi if test "$CHECKSHADOW" = "true"; then echo $ac_n "checking for getprpwnam""... $ac_c" 1>&6 -echo "configure:4194: checking for getprpwnam" >&5 +echo "configure:4206: checking for getprpwnam" >&5 if eval "test \"`echo '$''{'ac_cv_func_getprpwnam'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getprpwnam=yes" else @@ -4239,7 +4251,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 -echo "configure:4243: checking for getprpwnam in -lsec" >&5 +echo "configure:4255: checking for getprpwnam in -lsec" >&5 if test -n ""; then ac_lib_var=`echo sec'_'getprpwnam | sed 'y% ./+-%___p_%'` else @@ -4251,7 +4263,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4284,7 +4296,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:4288: checking for getprpwnam in -lsecurity" >&5 +echo "configure:4300: checking for getprpwnam in -lsecurity" >&5 if test -n ""; then ac_lib_var=`echo security'_'getprpwnam | sed 'y% ./+-%___p_%'` else @@ -4296,7 +4308,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4329,7 +4341,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6 -echo "configure:4333: checking for getprpwnam in -lprot" >&5 +echo "configure:4345: checking for getprpwnam in -lprot" >&5 if test -n ""; then ac_lib_var=`echo prot'_'getprpwnam | sed 'y% ./+-%___p_%'` else @@ -4341,7 +4353,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lprot $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4385,13 +4397,13 @@ fi if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:4389: checking whether ${CC-cc} needs -traditional" >&5 +echo "configure:4401: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP @@ -4409,7 +4421,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA @@ -4431,12 +4443,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:4435: checking for working const" >&5 +echo "configure:4447: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4501: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -4510,7 +4522,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4514: checking for $ac_word" >&5 +echo "configure:4526: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4540,7 +4552,7 @@ done test -n "$YACC" || YACC="yacc" echo $ac_n "checking for mv""... $ac_c" 1>&6 -echo "configure:4544: checking for mv" >&5 +echo "configure:4556: checking for mv" >&5 if test -f "/usr/bin/mv"; then echo "$ac_t""/usr/bin/mv" 1>&6 cat >> confdefs.h <<\EOF @@ -4570,7 +4582,7 @@ else fi echo $ac_n "checking for bourne shell""... $ac_c" 1>&6 -echo "configure:4574: checking for bourne shell" >&5 +echo "configure:4586: checking for bourne shell" >&5 if test -f "/bin/sh"; then echo "$ac_t""/bin/sh" 1>&6 cat >> confdefs.h <<\EOF @@ -4625,7 +4637,7 @@ fi if test -z "$with_sendmail"; then echo $ac_n "checking for sendmail""... $ac_c" 1>&6 -echo "configure:4629: checking for sendmail" >&5 +echo "configure:4641: checking for sendmail" >&5 if test -f "/usr/sbin/sendmail"; then echo "$ac_t""/usr/sbin/sendmail" 1>&6 cat >> confdefs.h <<\EOF @@ -4669,7 +4681,7 @@ fi fi if test -z "$with_editor"; then echo $ac_n "checking for vi""... $ac_c" 1>&6 -echo "configure:4673: checking for vi" >&5 +echo "configure:4685: checking for vi" >&5 if test -f "/usr/bin/vi"; then echo "$ac_t""/usr/bin/vi" 1>&6 cat >> confdefs.h <<\EOF @@ -4706,12 +4718,12 @@ fi fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:4710: checking for ANSI C header files" >&5 +echo "configure:4722: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4719,7 +4731,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4723: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4735: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -4736,7 +4748,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -4754,7 +4766,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -4775,7 +4787,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -4786,7 +4798,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:4790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else @@ -4814,12 +4826,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:4818: checking for $ac_hdr that defines DIR" >&5 +echo "configure:4830: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -4827,7 +4839,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:4831: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4843: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -4852,7 +4864,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:4856: checking for opendir in -ldir" >&5 +echo "configure:4868: checking for opendir in -ldir" >&5 if test -n ""; then ac_lib_var=`echo dir'_'opendir | sed 'y% ./+-%___p_%'` else @@ -4864,7 +4876,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4897,7 +4909,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:4901: checking for opendir in -lx" >&5 +echo "configure:4913: checking for opendir in -lx" >&5 if test -n ""; then ac_lib_var=`echo x'_'opendir | sed 'y% ./+-%___p_%'` else @@ -4909,7 +4921,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4946,17 +4958,17 @@ for ac_hdr in string.h strings.h unistd.h malloc.h paths.h utime.h netgroup.h sy do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4950: checking for $ac_hdr" >&5 +echo "configure:4962: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4960: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4972: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -4987,17 +4999,17 @@ if test "$OS" != "ultrix"; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4991: checking for $ac_hdr" >&5 +echo "configure:5003: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5001: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5013: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -5027,17 +5039,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5031: checking for $ac_hdr" >&5 +echo "configure:5043: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5041: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -5060,12 +5072,12 @@ EOF for ac_func in tcgetattr do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5064: checking for $ac_func" >&5 +echo "configure:5076: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5123,17 +5135,17 @@ if test "$with_logincap" = "yes"; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5127: checking for $ac_hdr" >&5 +echo "configure:5139: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -5163,17 +5175,17 @@ fi if test "$with_bsdauth" = "yes"; then ac_safe=`echo "bsd_auth.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for bsd_auth.h""... $ac_c" 1>&6 -echo "configure:5167: checking for bsd_auth.h" >&5 +echo "configure:5179: checking for bsd_auth.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5177: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5189: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -5199,12 +5211,12 @@ fi fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:5203: checking for mode_t" >&5 +echo "configure:5215: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5232,12 +5244,12 @@ EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:5236: checking for uid_t in sys/types.h" >&5 +echo "configure:5248: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -5266,12 +5278,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:5270: checking for size_t" >&5 +echo "configure:5282: checking for size_t" >&5 if eval "test \"`echo '$''{'sudo_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5301,12 +5313,12 @@ EOF fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:5305: checking for ssize_t" >&5 +echo "configure:5317: checking for ssize_t" >&5 if eval "test \"`echo '$''{'sudo_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5336,12 +5348,12 @@ EOF fi echo $ac_n "checking for dev_t""... $ac_c" 1>&6 -echo "configure:5340: checking for dev_t" >&5 +echo "configure:5352: checking for dev_t" >&5 if eval "test \"`echo '$''{'sudo_cv_type_dev_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5371,12 +5383,12 @@ EOF fi echo $ac_n "checking for ino_t""... $ac_c" 1>&6 -echo "configure:5375: checking for ino_t" >&5 +echo "configure:5387: checking for ino_t" >&5 if eval "test \"`echo '$''{'sudo_cv_type_ino_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5406,9 +5418,9 @@ EOF fi echo $ac_n "checking for full void implementation""... $ac_c" 1>&6 -echo "configure:5410: checking for full void implementation" >&5 +echo "configure:5422: checking for full void implementation" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5432: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define VOID void @@ -5436,7 +5448,7 @@ fi rm -f conftest* echo $ac_n "checking max length of uid_t""... $ac_c" 1>&6 -echo "configure:5440: checking max length of uid_t" >&5 +echo "configure:5452: checking max length of uid_t" >&5 if eval "test \"`echo '$''{'sudo_cv_uid_t_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5445,7 +5457,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < #include @@ -5466,7 +5478,7 @@ main() { exit(0); } EOF -if { (eval echo configure:5470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then sudo_cv_uid_t_len=`cat conftestdata` else @@ -5489,16 +5501,16 @@ EOF echo $ac_n "checking for long long support""... $ac_c" 1>&6 -echo "configure:5493: checking for long long support" >&5 +echo "configure:5505: checking for long long support" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_LONG_LONG 1 @@ -5508,11 +5520,11 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define LONG_IS_QUAD 1 @@ -5534,7 +5546,7 @@ else fi rm -f conftest* echo $ac_n "checking for sa_len field in struct sockaddr""... $ac_c" 1>&6 -echo "configure:5538: checking for sa_len field in struct sockaddr" >&5 +echo "configure:5550: checking for sa_len field in struct sockaddr" >&5 if eval "test \"`echo '$''{'sudo_cv_sock_sa_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5542,7 +5554,7 @@ else sudo_cv_sock_sa_len=no else cat > conftest.$ac_ext < #include @@ -5552,7 +5564,7 @@ s.sa_len = 0; exit(0); } EOF -if { (eval echo configure:5556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then sudo_cv_sock_sa_len=yes else @@ -5577,12 +5589,12 @@ fi case "$DEFS" in *"RETSIGTYPE"*) ;; *) echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:5581: checking return type of signal handlers" >&5 +echo "configure:5593: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5599,7 +5611,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:5603: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -5621,12 +5633,68 @@ esac for ac_func in strchr strrchr memchr memcpy memset sysconf sigaction tzset seteuid strftime setrlimit initgroups fstat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5625: checking for $ac_func" >&5 +echo "configure:5637: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +if test -z "$BROKEN_SETREUID"; then + for ac_func in setreuid +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5693: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5673,16 +5741,17 @@ else fi done +fi if test X"$with_interfaces" != X"no"; then for ac_func in getifaddrs do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5681: checking for $ac_func" >&5 +echo "configure:5750: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5734,12 +5803,12 @@ if test -n "$SECUREWARE"; then for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5738: checking for $ac_func" >&5 +echo "configure:5807: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5789,12 +5858,12 @@ done for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5793: checking for $ac_func" >&5 +echo "configure:5862: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5844,12 +5913,12 @@ done for ac_func in initprivs do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5848: checking for $ac_func" >&5 +echo "configure:5917: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:5945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5899,12 +5968,12 @@ done fi if test -z "$BROKEN_GETCWD"; then echo $ac_n "checking for getcwd""... $ac_c" 1>&6 -echo "configure:5903: checking for getcwd" >&5 +echo "configure:5972: checking for getcwd" >&5 if eval "test \"`echo '$''{'ac_cv_func_getcwd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6000: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getcwd=yes" else @@ -5952,12 +6021,12 @@ fi fi echo $ac_n "checking for lockf""... $ac_c" 1>&6 -echo "configure:5956: checking for lockf" >&5 +echo "configure:6025: checking for lockf" >&5 if eval "test \"`echo '$''{'ac_cv_func_lockf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_lockf=yes" else @@ -6003,12 +6072,12 @@ else for ac_func in flock do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6007: checking for $ac_func" >&5 +echo "configure:6076: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6058,12 +6127,12 @@ done fi echo $ac_n "checking for waitpid""... $ac_c" 1>&6 -echo "configure:6062: checking for waitpid" >&5 +echo "configure:6131: checking for waitpid" >&5 if eval "test \"`echo '$''{'ac_cv_func_waitpid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6159: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_waitpid=yes" else @@ -6109,12 +6178,12 @@ else for ac_func in wait3 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6113: checking for $ac_func" >&5 +echo "configure:6182: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6164,12 +6233,12 @@ done fi echo $ac_n "checking for innetgr""... $ac_c" 1>&6 -echo "configure:6168: checking for innetgr" >&5 +echo "configure:6237: checking for innetgr" >&5 if eval "test \"`echo '$''{'ac_cv_func_innetgr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_innetgr=yes" else @@ -6212,12 +6281,12 @@ EOF for ac_func in getdomainname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6216: checking for $ac_func" >&5 +echo "configure:6285: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6267,12 +6336,12 @@ done else echo "$ac_t""no" 1>&6 echo $ac_n "checking for _innetgr""... $ac_c" 1>&6 -echo "configure:6271: checking for _innetgr" >&5 +echo "configure:6340: checking for _innetgr" >&5 if eval "test \"`echo '$''{'ac_cv_func__innetgr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func__innetgr=yes" else @@ -6315,12 +6384,12 @@ EOF for ac_func in getdomainname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6319: checking for $ac_func" >&5 +echo "configure:6388: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6416: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6374,12 +6443,12 @@ fi fi echo $ac_n "checking for lsearch""... $ac_c" 1>&6 -echo "configure:6378: checking for lsearch" >&5 +echo "configure:6447: checking for lsearch" >&5 if eval "test \"`echo '$''{'ac_cv_func_lsearch'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_lsearch=yes" else @@ -6423,7 +6492,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for lsearch in -lcompat""... $ac_c" 1>&6 -echo "configure:6427: checking for lsearch in -lcompat" >&5 +echo "configure:6496: checking for lsearch in -lcompat" >&5 if test -n ""; then ac_lib_var=`echo compat'_'lsearch | sed 'y% ./+-%___p_%'` else @@ -6435,7 +6504,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcompat $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6463,17 +6532,17 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_safe=`echo "search.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for search.h""... $ac_c" 1>&6 -echo "configure:6467: checking for search.h" >&5 +echo "configure:6536: checking for search.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6477: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6546: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -6505,116 +6574,13 @@ fi fi -echo $ac_n "checking for setenv""... $ac_c" 1>&6 -echo "configure:6510: checking for setenv" >&5 -if eval "test \"`echo '$''{'ac_cv_func_setenv'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char setenv(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_setenv) || defined (__stub___setenv) -choke me -#else -setenv(); -#endif - -; return 0; } -EOF -if { (eval echo configure:6538: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_func_setenv=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_setenv=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'setenv`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_SETENV 1 -EOF - -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for putenv""... $ac_c" 1>&6 -echo "configure:6559: checking for putenv" >&5 -if eval "test \"`echo '$''{'ac_cv_func_putenv'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char putenv(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_putenv) || defined (__stub___putenv) -choke me -#else -putenv(); -#endif - -; return 0; } -EOF -if { (eval echo configure:6587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_func_putenv=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_putenv=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'putenv`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_PUTENV 1 -EOF - -else - echo "$ac_t""no" 1>&6 -LIBOBJS="$LIBOBJS putenv.o" -fi - -fi - echo $ac_n "checking for utime""... $ac_c" 1>&6 -echo "configure:6613: checking for utime" >&5 +echo "configure:6579: checking for utime" >&5 if eval "test \"`echo '$''{'ac_cv_func_utime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_utime=yes" else @@ -6656,7 +6622,7 @@ if eval "test \"`echo '$ac_cv_func_'utime`\" = yes"; then EOF echo $ac_n "checking for POSIX utime""... $ac_c" 1>&6 -echo "configure:6660: checking for POSIX utime" >&5 +echo "configure:6626: checking for POSIX utime" >&5 if eval "test \"`echo '$''{'sudo_cv_func_utime_posix'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6665,7 +6631,7 @@ if test "$cross_compiling" = yes; then sudo_cv_func_utime_posix=no else cat > conftest.$ac_ext < #include @@ -6677,7 +6643,7 @@ utime("conftestdata", &ut); exit(0); } EOF -if { (eval echo configure:6681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then sudo_cv_func_utime_posix=yes else @@ -6705,7 +6671,7 @@ LIBOBJS="$LIBOBJS utime.o" fi echo $ac_n "checking for working fnmatch with FNM_CASEFOLD""... $ac_c" 1>&6 -echo "configure:6709: checking for working fnmatch with FNM_CASEFOLD" >&5 +echo "configure:6675: checking for working fnmatch with FNM_CASEFOLD" >&5 if eval "test \"`echo '$''{'sudo_cv_func_fnmatch'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6714,13 +6680,13 @@ if test "$cross_compiling" = yes; then sudo_cv_func_fnmatch=no else cat > conftest.$ac_ext < main() { exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", FNM_CASEFOLD)); } EOF -if { (eval echo configure:6724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then sudo_cv_func_fnmatch=yes else @@ -6747,12 +6713,12 @@ fi for ac_func in strerror strcasecmp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6751: checking for $ac_func" >&5 +echo "configure:6717: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6802,12 +6768,12 @@ done echo $ac_n "checking for snprintf""... $ac_c" 1>&6 -echo "configure:6806: checking for snprintf" >&5 +echo "configure:6772: checking for snprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_snprintf=yes" else @@ -6854,12 +6820,12 @@ NEED_SNPRINTF=1 fi echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6 -echo "configure:6858: checking for vsnprintf" >&5 +echo "configure:6824: checking for vsnprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_vsnprintf=yes" else @@ -6906,12 +6872,12 @@ NEED_SNPRINTF=1 fi echo $ac_n "checking for asprintf""... $ac_c" 1>&6 -echo "configure:6910: checking for asprintf" >&5 +echo "configure:6876: checking for asprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_asprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_asprintf=yes" else @@ -6958,12 +6924,12 @@ NEED_SNPRINTF=1 fi echo $ac_n "checking for vasprintf""... $ac_c" 1>&6 -echo "configure:6962: checking for vasprintf" >&5 +echo "configure:6928: checking for vasprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vasprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:6956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_vasprintf=yes" else @@ -7014,12 +6980,12 @@ if test -n "$NEED_SNPRINTF"; then fi if test -z "$LIB_CRYPT"; then echo $ac_n "checking for crypt""... $ac_c" 1>&6 -echo "configure:7018: checking for crypt" >&5 +echo "configure:6984: checking for crypt" >&5 if eval "test \"`echo '$''{'ac_cv_func_crypt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_crypt=yes" else @@ -7060,7 +7026,7 @@ if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:7064: checking for crypt in -lcrypt" >&5 +echo "configure:7030: checking for crypt in -lcrypt" >&5 if test -n ""; then ac_lib_var=`echo crypt'_'crypt | sed 'y% ./+-%___p_%'` else @@ -7072,7 +7038,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7102,7 +7068,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for crypt in -lcrypt_d""... $ac_c" 1>&6 -echo "configure:7106: checking for crypt in -lcrypt_d" >&5 +echo "configure:7072: checking for crypt in -lcrypt_d" >&5 if test -n ""; then ac_lib_var=`echo crypt_d'_'crypt | sed 'y% ./+-%___p_%'` else @@ -7114,7 +7080,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt_d $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7144,7 +7110,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for crypt in -lufc""... $ac_c" 1>&6 -echo "configure:7148: checking for crypt in -lufc" >&5 +echo "configure:7114: checking for crypt in -lufc" >&5 if test -n ""; then ac_lib_var=`echo ufc'_'crypt | sed 'y% ./+-%___p_%'` else @@ -7156,7 +7122,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lufc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7195,12 +7161,12 @@ fi fi echo $ac_n "checking for socket""... $ac_c" 1>&6 -echo "configure:7199: checking for socket" >&5 +echo "configure:7165: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_socket=yes" else @@ -7241,7 +7207,7 @@ if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:7245: checking for socket in -lsocket" >&5 +echo "configure:7211: checking for socket in -lsocket" >&5 if test -n ""; then ac_lib_var=`echo socket'_'socket | sed 'y% ./+-%___p_%'` else @@ -7253,7 +7219,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7283,7 +7249,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 -echo "configure:7287: checking for socket in -linet" >&5 +echo "configure:7253: checking for socket in -linet" >&5 if test -n ""; then ac_lib_var=`echo inet'_'socket | sed 'y% ./+-%___p_%'` else @@ -7295,7 +7261,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7326,7 +7292,7 @@ else echo "$ac_t""no" 1>&6 echo "configure: warning: unable to find socket() trying -lsocket -lnsl" 1>&2 echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:7330: checking for socket in -lsocket" >&5 +echo "configure:7296: checking for socket in -lsocket" >&5 if test -n "-lnsl"; then ac_lib_var=`echo socket'_'socket-lnsl | sed 'y% ./+-%___p_%'` else @@ -7338,7 +7304,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket -lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7376,12 +7342,12 @@ fi fi echo $ac_n "checking for inet_addr""... $ac_c" 1>&6 -echo "configure:7380: checking for inet_addr" >&5 +echo "configure:7346: checking for inet_addr" >&5 if eval "test \"`echo '$''{'ac_cv_func_inet_addr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_inet_addr=yes" else @@ -7422,12 +7388,12 @@ if eval "test \"`echo '$ac_cv_func_'inet_addr`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __inet_addr""... $ac_c" 1>&6 -echo "configure:7426: checking for __inet_addr" >&5 +echo "configure:7392: checking for __inet_addr" >&5 if eval "test \"`echo '$''{'ac_cv_func___inet_addr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func___inet_addr=yes" else @@ -7468,7 +7434,7 @@ if eval "test \"`echo '$ac_cv_func_'__inet_addr`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for inet_addr in -lnsl""... $ac_c" 1>&6 -echo "configure:7472: checking for inet_addr in -lnsl" >&5 +echo "configure:7438: checking for inet_addr in -lnsl" >&5 if test -n ""; then ac_lib_var=`echo nsl'_'inet_addr | sed 'y% ./+-%___p_%'` else @@ -7480,7 +7446,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7510,7 +7476,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for inet_addr in -linet""... $ac_c" 1>&6 -echo "configure:7514: checking for inet_addr in -linet" >&5 +echo "configure:7480: checking for inet_addr in -linet" >&5 if test -n ""; then ac_lib_var=`echo inet'_'inet_addr | sed 'y% ./+-%___p_%'` else @@ -7522,7 +7488,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7553,7 +7519,7 @@ else echo "$ac_t""no" 1>&6 echo "configure: warning: unable to find inet_addr() trying -lsocket -lnsl" 1>&2 echo $ac_n "checking for inet_addr in -lsocket""... $ac_c" 1>&6 -echo "configure:7557: checking for inet_addr in -lsocket" >&5 +echo "configure:7523: checking for inet_addr in -lsocket" >&5 if test -n "-lnsl"; then ac_lib_var=`echo socket'_'inet_addr-lnsl | sed 'y% ./+-%___p_%'` else @@ -7565,7 +7531,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket -lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7546: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7605,12 +7571,12 @@ fi fi echo $ac_n "checking for syslog""... $ac_c" 1>&6 -echo "configure:7609: checking for syslog" >&5 +echo "configure:7575: checking for syslog" >&5 if eval "test \"`echo '$''{'ac_cv_func_syslog'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_syslog=yes" else @@ -7651,7 +7617,7 @@ if eval "test \"`echo '$ac_cv_func_'syslog`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for syslog in -lsocket""... $ac_c" 1>&6 -echo "configure:7655: checking for syslog in -lsocket" >&5 +echo "configure:7621: checking for syslog in -lsocket" >&5 if test -n ""; then ac_lib_var=`echo socket'_'syslog | sed 'y% ./+-%___p_%'` else @@ -7663,7 +7629,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7693,7 +7659,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for syslog in -lnsl""... $ac_c" 1>&6 -echo "configure:7697: checking for syslog in -lnsl" >&5 +echo "configure:7663: checking for syslog in -lnsl" >&5 if test -n ""; then ac_lib_var=`echo nsl'_'syslog | sed 'y% ./+-%___p_%'` else @@ -7705,7 +7671,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7686: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7735,7 +7701,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for syslog in -linet""... $ac_c" 1>&6 -echo "configure:7739: checking for syslog in -linet" >&5 +echo "configure:7705: checking for syslog in -linet" >&5 if test -n ""; then ac_lib_var=`echo inet'_'syslog | sed 'y% ./+-%___p_%'` else @@ -7747,7 +7713,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7788,19 +7754,19 @@ if test "$with_DCE" = "yes" -o "$ac_cv_prog_YACC" = "bison -y"; then # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:7792: checking for working alloca.h" >&5 +echo "configure:7758: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:7804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -7821,12 +7787,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:7825: checking for alloca" >&5 +echo "configure:7791: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -7881,12 +7847,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:7885: checking whether alloca needs Cray hooks" >&5 +echo "configure:7851: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7915: checking for $ac_func" >&5 +echo "configure:7881: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7966,7 +7932,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:7970: checking stack direction for C alloca" >&5 +echo "configure:7936: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7974,7 +7940,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -8051,21 +8017,21 @@ fi if test "$with_pam" = "yes"; then echo $ac_n "checking for -ldl""... $ac_c" 1>&6 -echo "configure:8055: checking for -ldl" >&5 +echo "configure:8021: checking for -ldl" >&5 if eval "test \"`echo '$''{'ac_cv_lib_dl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:8035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_lib_dl=yes else @@ -8115,21 +8081,21 @@ EOF fi echo $ac_n "checking for -ldes""... $ac_c" 1>&6 -echo "configure:8119: checking for -ldes" >&5 +echo "configure:8085: checking for -ldes" >&5 if eval "test \"`echo '$''{'ac_cv_lib_des'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldes $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:8099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_lib_des=yes else @@ -8248,7 +8214,7 @@ if test "$with_authenticate" = "yes"; then fi echo $ac_n "checking for log file location""... $ac_c" 1>&6 -echo "configure:8252: checking for log file location" >&5 +echo "configure:8218: checking for log file location" >&5 if test -n "$with_logpath"; then echo "$ac_t""$with_logpath" 1>&6 cat >> confdefs.h <&6 -echo "configure:8282: checking for timestamp file location" >&5 +echo "configure:8248: checking for timestamp file location" >&5 if test -n "$with_timedir"; then echo "$ac_t""$with_timedir" 1>&6 cat >> confdefs.h < + * 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 +#ifdef STDC_HEADERS +#include +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include +#endif /* HAVE_STRINGS_H */ +#include +#include +#include +#include +#include + +#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); +} diff --git a/find_path.c b/find_path.c index dd1609002..df33ae8bc 100644 --- a/find_path.c +++ b/find_path.c @@ -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; diff --git a/getspwuid.c b/getspwuid.c index 4d48b6083..07286d20c 100644 --- a/getspwuid.c +++ b/getspwuid.c @@ -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); } diff --git a/set_perms.c b/set_perms.c index 5376ebd8a..05ab947b5 100644 --- a/set_perms.c +++ b/set_perms.c @@ -64,161 +64,122 @@ 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); + switch (perm) { + case PERM_ROOT: + if (seteuid(0)) + fatal("seteuid(0)"); + break; + 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 (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)) + 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 +} + +/* + * 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: - TOGGLE_ROOT; + if (setuid(0)) + fatal("setuid(0)"); break; case PERM_USER: (void) setegid(user_gid); - TOGGLE_USER; + 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)) { - perror("setuid(user_uid)"); + fatal("setuid(user_uid)"); exit(1); } 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 = 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)) - 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 +188,125 @@ 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)"); + fatal("setreuid(0, 1)"); } else { if (setreuid(0, SUDOERS_UID)) - log_error(NO_MAIL|USE_ERRNO|MSG_ONLY, - "setreuid(0, SUDOERS_UID)"); + fatal("setreuid(0, SUDOERS_UID)"); } -#else + 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)) - 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; } } +#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); +} diff --git a/sudo.c b/sudo.c index 663d92b8a..c464d1112 100644 --- a/sudo.c +++ b/sudo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994-1996,1998-2000 Todd C. Miller + * Copyright (c) 1993-1996,1998-2000 Todd C. Miller * 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 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 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 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 diff --git a/sudo.cat b/sudo.cat index d96e32854..0858dcc79 100644 --- a/sudo.cat +++ b/sudo.cat @@ -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,24 +256,25 @@ 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: +December 29, 2000 1.6.4 4 -October 26, 2000 1.6.4 4 +sudo(1m) MAINTENANCE COMMANDS sudo(1m) + % sudo -u yazza ls ~yazza -sudo(1m) MAINTENANCE COMMANDS sudo(1m) + 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" @@ -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 diff --git a/sudo.h b/sudo.h index d8b34146b..330c99b51 100644 --- a/sudo.h +++ b/sudo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994-1996,1998-2000 Todd C. Miller + * Copyright (c) 1993-1996,1998-2000 Todd C. Miller * 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; diff --git a/sudo.man.in b/sudo.man.in index dfbf614d3..5783c9ef9 100644 --- a/sudo.man.in +++ b/sudo.man.in @@ -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 diff --git a/sudo.pod b/sudo.pod index e8427662d..cf3ae8605 100644 --- a/sudo.pod +++ b/sudo.pod @@ -218,9 +218,15 @@ to subvert the program that B runs. To combat this the C, C<_RLD_*>, C (HP-UX only), and C (AIX only) environment variables are removed from the environment passed on to all commands executed. B will also remove the C, -C, C, C, C, C, -C and C variables as they too can pose a -threat. +C, C, C, C, C, +C, C, C, C, +C, C, C, C and +C variables as they too can pose a threat. If the +C variable is set and is a pathname, it too is ignored. +Additionally, if the C or C variables contain the +C or C<%> characters, they are ignored. If B has been +compiled with SecurID support, the C, C and +C variables are cleared as well. To prevent command spoofing, B checks "." and "" (both denoting current directory) last when searching for a command in the user's diff --git a/sudoers.cat b/sudoers.cat index 71b1a0029..1dbf2464b 100644 --- a/sudoers.cat +++ b/sudoers.cat @@ -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 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 entries for the current host must have the C flag set to avoid entering a password. @@ -623,6 +651,19 @@ sudoers(4) MAINTENANCE COMMANDS sudoers(4) current host must have the C 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 entries for the current host must have the C 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 diff --git a/sudoers.man.in b/sudoers.man.in index 6e167cd40..d47026f54 100644 --- a/sudoers.man.in +++ b/sudoers.man.in @@ -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 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 diff --git a/sudoers.pod b/sudoers.pod index 1e807ed2b..b43d0deae 100644 --- a/sudoers.pod +++ b/sudoers.pod @@ -398,6 +398,23 @@ However, since some programs (including the RCS revision control system) use C 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 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 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 will reset the environment to only contain the +following variables: C, C, C, and C +(in addition to the C variables). The C environment +variable is preserved unaltered. Other specific variables +may be preserved with the i option. + =item use_loginclass If set, B 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 option, this allows fine control over the +environment B-spawned processes will get. If the I +option is not used, I 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 C, 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 diff --git a/testsudoers.c b/testsudoers.c index 7d00dcd73..da84ddfc8 100644 --- a/testsudoers.c +++ b/testsudoers.c @@ -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; diff --git a/visudo.c b/visudo.c index bef9f5a63..09f3a19a6 100644 --- a/visudo.c +++ b/visudo.c @@ -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)) { diff --git a/visudo.cat b/visudo.cat index 50edb4e0b..eeb237275 100644 --- a/visudo.cat +++ b/visudo.cat @@ -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 - 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 diff --git a/visudo.man.in b/visudo.man.in index b2b6ad893..b999fdb46 100644 --- a/visudo.man.in +++ b/visudo.man.in @@ -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 .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 -- 2.40.0