Merge commit 'upstream/1.7.0'
authorBdale Garbee <bdale@gag.com>
Sat, 28 Mar 2009 12:37:47 +0000 (06:37 -0600)
committerBdale Garbee <bdale@gag.com>
Sat, 28 Mar 2009 12:37:47 +0000 (06:37 -0600)
Conflicts:
Makefile.in
parse.c
parse.yacc
sudo.h
sudoers.man.in
sudoers.pod

1  2 
Makefile.in
configure
env.c
sample.sudoers
sudo.c
sudo.man.in
sudo.pod
sudoers.man.in
sudoers.pod
visudo.man.in

diff --combined Makefile.in
index 3922f69f0249df1bdf6b19e303f248655dea7c40,c097af7eee1be95871e24e93f5373c6ad1bce6c1..551fb01e8d354a6cd4c49cc669d9ce718184acab
@@@ -1,5 -1,6 +1,6 @@@
  #
- # Copyright (c) 1996, 1998-2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ # Copyright (c) 1996, 1998-2005, 2007-2008
+ #     Todd C. Miller <Todd.Miller@courtesan.com>
  #
  # Permission to use, copy, modify, and distribute this software for any
  # purpose with or without fee is hereby granted, provided that the above
  #
  # @configure_input@
  #
- # $Sudo: Makefile.in,v 1.246.2.32 2008/06/22 20:29:03 millert Exp $
+ # $Sudo: Makefile.in,v 1.326 2008/12/03 20:40:47 millert Exp $
  #
  
  #### Start of system configuration section. ####
  
  srcdir = @srcdir@
+ devdir = @devdir@
  authdir = $(srcdir)/auth
  top_builddir = .
- VPATH = @srcdir@
  
  # Compiler & tools to use
  CC = @CC@
  LEX = flex
  YACC = @YACC@
- NROFF = nroff
+ NROFF = nroff -Tascii
  LIBTOOL = @LIBTOOL@
  
  # Our install program supports extra flags...
@@@ -61,11 -62,11 +62,11 @@@ exec_prefix = @exec_prefix
  bindir = @bindir@
  sbindir = @sbindir@
  sysconfdir = @sysconfdir@
+ libexecdir = @libexecdir@
+ datarootdir = @datarootdir@
  mandir = @mandir@
  noexecfile = @NOEXECFILE@
  noexecdir = @NOEXECDIR@
- libexecdir = @libexecdir@
- datarootdir = @datarootdir@
  
  # Directory in which to install sudo.
  sudodir = $(bindir)
@@@ -93,7 -94,7 +94,7 @@@ sudoers_gid = @SUDOERS_GID
  sudoers_mode = @SUDOERS_MODE@
  
  # Pass in paths and uid/gid + OS dependent defined
- DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -D_PATH_SUDOERS_TMP=\"$(sudoersdir)/sudoers.tmp\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode)
+ DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode)
  
  #### End of system configuration section. ####
  
@@@ -101,60 -102,68 +102,68 @@@ SHELL = /bin/s
  
  PROGS = @PROGS@
  
- SRCS = alloc.c alloca.c check.c closefrom.c def_data.c defaults.c env.c err.c \
-        fileops.c find_path.c fnmatch.c getcwd.c getprogname.c getspwuid.c \
-        gettime.c glob.c goodpath.c interfaces.c ldap.c lex.yy.c lsearch.c \
-        logging.c memrchr.c mkstemp.c parse.c parse.lex parse.yacc set_perms.c \
-        sigaction.c snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c \
-        sudo.c sudo_noexec.c sudo.tab.c sudo_edit.c testsudoers.c tgetpass.c \
-        utimes.c visudo.c zero_bytes.c selinux.c sesh.c $(AUTH_SRCS)
+ SRCS = aix.c alias.c alloc.c check.c closefrom.c def_data.c defaults.c env.c \
+        error.c fileops.c find_path.c fnmatch.c getcwd.c getprogname.c \
+        getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y interfaces.c \
+        isblank.c lbuf.c ldap.c list.c logging.c match.c mkstemp.c memrchr.c \
+        parse.c pwutil.c  set_perms.c sigaction.c snprintf.c strcasecmp.c \
+        strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c sudo_edit.c \
+        sudo_nss.c testsudoers.c tgetpass.c toke.c toke.l tsgetgrpw.c utimes.c \
+        visudo.c zero_bytes.c redblack.c selinux.c sesh.c $(AUTH_SRCS)
  
  AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
            auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
            auth/secureware.c auth/securid.c auth/securid5.c auth/sia.c \
            auth/sudo_auth.c
  
- HDRS = compat.h def_data.h defaults.h ins_2001.h ins_classic.h ins_csops.h \
-        ins_goons.h insults.h interfaces.h logging.h parse.h sudo.h sudo.tab.h \
-        version.h auth/sudo_auth.h emul/err.h emul/fnmatch.h emul/search.h \
-        emul/utime.h emul/glob.h emul/timespec.h
+ HDRS = compat.h def_data.h defaults.h error.h ins_2001.h ins_classic.h \
+        ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h list.h \
+        logging.h parse.h sudo.h sudo_nss.h gram.h version.h auth/sudo_auth.h \
+        emul/charclass.h emul/fnmatch.h emul/glob.h emul/timespec.h \
+        emul/utime.h redblack.h
  
  AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
  
- PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o
+ # Note: gram.o must come first here
+ COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o list.o match.o \
+             toke.o redblack.o zero_bytes.o
  
- SUDOBJS = check.o env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \
-         interfaces.o logging.o parse.o set_perms.o sudo.o sudo_edit.o \
-         tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS)
+ SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ check.o env.o \
+           getspwuid.o gettime.o goodpath.o fileops.o find_path.o \
+           interfaces.o lbuf.o logging.o parse.o pwutil.o set_perms.o \
+           sudo.o sudo_edit.o sudo_nss.o tgetpass.o
  
- VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS)
+ VISUDO_OBJS = $(COMMON_OBJS) visudo.o fileops.o gettime.o goodpath.o \
+             find_path.o pwutil.o
  
- TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS)
+ TEST_OBJS = $(COMMON_OBJS) interfaces.o testsudoers.o tsgetgrpw.o tspwutil.o
  
- LIBOBJS = @LIBOBJS@ @ALLOCA@
+ LIB_OBJS = @LIBOBJS@
  
- VERSION = 1.6.9p17
+ VERSION = 1.7.0
  
- DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES HISTORY INSTALL INSTALL.configure \
-             LICENSE Makefile.in PORTING README README.LDAP \
-             TROUBLESHOOTING UPGRADE aclocal.m4 acsite.m4 aixcrypt.exp \
-             config.guess config.h.in config.sub configure configure.in \
-             def_data.in fnmatch.3 indent.pro install-sh ltmain.sh \
-             mkdefaults mkinstalldirs pathnames.h.in sample.pam \
-             sample.syslog.conf sample.sudoers schema.OpenLDAP \
-             schema.iPlanet sudo.cat sudo.man.in sudo.pod sudoers \
-             sudoers.cat sudoers.man.in sudoers.pod sudoers2ldif \
-             visudo.cat visudo.man.in visudo.pod auth/API
+ DISTFILES = $(SRCS) $(HDRS) ChangeLog HISTORY INSTALL INSTALL.configure \
+             LICENSE Makefile.in PORTING README README.LDAP TROUBLESHOOTING \
+           UPGRADE WHATSNEW aclocal.m4 acsite.m4 aixcrypt.exp config.guess \
+           config.h.in config.sub configure configure.in def_data.in \
+           indent.pro install-sh ltmain.sh mkdefaults mkinstalldirs \
+           pathnames.h.in sample.pam sample.syslog.conf sample.sudoers \
+           schema.ActiveDirectory schema.OpenLDAP schema.iPlanet sudo.cat \
+           sudo.man.in sudo.pod sudo.psf sudo_usage.h.in sudoers sudoers.cat \
+             sudoers.man.in sudoers.pod sudoers.ldap.cat sudoers.ldap.man.in \
+           sudoers.ldap.pod sudoers2ldif visudo.cat visudo.man.in visudo.pod \
+           auth/API
  
- BINFILES= BUGS CHANGES HISTORY LICENSE README TROUBLESHOOTING \
+ BINFILES= ChangeLog HISTORY LICENSE README TROUBLESHOOTING \
          UPGRADE install-sh mkinstalldirs sample.syslog.conf sample.sudoers \
          sudo sudo.cat sudo.man sudo.pod sudoers sudoers.cat sudoers.man \
          sudoers.pod visudo visudo.cat visudo.man visudo.pod
  
- BINSPECIAL= INSTALL.binary Makefile.binary libtool
+ BINSPECIAL= INSTALL.binary Makefile.binary.in libtool
  
  SUDODEP = $(srcdir)/sudo.h $(srcdir)/compat.h $(srcdir)/defaults.h \
-         $(srcdir)/logging.h config.h def_data.h pathnames.h
+         $(srcdir)/error.h $(srcdir)/list.h $(srcdir)/logging.h \
+         $(srcdir)/sudo_nss.h $(devdir)/def_data.h pathnames.h config.h
  
  AUTHDEP = $(SUDODEP) $(authdir)/sudo_auth.h
  
@@@ -163,7 -172,7 +172,7 @@@ INSDEP = $(srcdir)/ins_2001.h $(srcdir)
  
  all: $(PROGS)
  
- .SUFFIXES: .o .c .h .lex .yacc .man .cat .lo
+ .SUFFIXES: .o .c .h .l .y .man .cat .lo
  
  .c.o:
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $<
  
  .man.cat:
        @rm -f $(srcdir)/$@
-       $(NROFF) -man $< > $(srcdir)/$@
+       sed '1s/^/.if n .ll 78n/' $< | $(NROFF) -man > $(srcdir)/$@
  
- sudo: $(SUDOBJS) $(LIBOBJS)
-       $(CC) -o $@ $(SUDOBJS) $(LIBOBJS) $(SUDO_LDFLAGS) $(SUDO_LIBS)
+ sudo: $(SUDO_OBJS) $(LIB_OBJS)
+       $(CC) -o $@ $(SUDO_OBJS) $(LIB_OBJS) $(SUDO_LDFLAGS) $(SUDO_LIBS)
  
- visudo: $(VISUDOBJS) $(LIBOBJS)
-       $(CC) -o $@ $(VISUDOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
+ visudo: $(VISUDO_OBJS) $(LIB_OBJS)
+       $(CC) -o $@ $(VISUDO_OBJS) $(LIB_OBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
  
- testsudoers: $(TESTOBJS) $(LIBOBJS)
-       $(CC) -o $@ $(TESTOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
+ testsudoers: $(TEST_OBJS) $(LIB_OBJS)
+       $(CC) -o $@ $(TEST_OBJS) $(LIB_OBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
  
  sudo_noexec.lo: $(srcdir)/sudo_noexec.c
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_noexec.c
@@@ -191,61 -200,129 +200,129 @@@ sudo_noexec.la: sudo_noexec.l
        $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir)
  
  # Uncomment the following if you want "make distclean" to clean the parser
- @DEV@PARSESRCS = sudo.tab.h sudo.tab.c lex.yy.c def_data.c def_data.h
+ @DEV@GENERATED = gram.h gram.c toke.c def_data.c def_data.h
  
- # Uncomment the following if you intend to modify parse.yacc
- sudo.tab.c sudo.tab.h: parse.yacc
-       rm -f sudo.tab.h sudo.tab.c
-       $(YACC) -d -b sudo $(srcdir)/parse.yacc
+ # Uncomment the lines before -@true if you intend to modify gram.y
+ $(devdir)/gram.c: $(srcdir)/gram.y
+ @DEV@ $(YACC) -d $(srcdir)/gram.y
+ @DEV@ mv -f y.tab.c gram.c
+ @DEV@ if cmp -s y.tab.h gram.h; then rm -f y.tab.h; else mv -f y.tab.h gram.h; fi
+       -@true
  
- # Uncomment the following if you intend to modify parse.lex
- @DEV@lex.yy.c: parse.lex
- @DEV@ rm -f lex.yy.c
- @DEV@ $(LEX) $(srcdir)/parse.lex
+ # Uncomment the lines before -@true if you intend to modify toke.l
+ $(devdir)/toke.c: $(srcdir)/toke.l
+ @DEV@ $(LEX) $(srcdir)/toke.l
+ @DEV@ mv -f lex.yy.c toke.c
+       -@true
  
  # Uncomment the following if you intend to modify def_data.in
- @DEV@def_data.h def_data.c: def_data.in
+ @DEV@$(devdir)/def_data.h $(devdir)/def_data.c: $(srcdir)/def_data.in
  @DEV@ perl $(srcdir)/mkdefaults -o def_data $(srcdir)/def_data.in
  
  # Dependencies (not counting auth functions)
- alloc.o: alloc.c $(SUDODEP)
- check.o: check.c $(SUDODEP)
- closefrom.o: closefrom.c config.h
- env.o: env.c $(SUDODEP)
- err.o: err.c config.h compat.h emul/err.h
- fileops.o: fileops.c $(SUDODEP)
- find_path.o: find_path.c $(SUDODEP)
- getprogname.o: getprogname.c config.h
- getspwuid.o: getspwuid.c $(SUDODEP)
- goodpath.o: goodpath.c $(SUDODEP)
- logging.o: logging.c $(SUDODEP)
- set_perms.o: set_perms.c $(SUDODEP)
- tgetpass.o: tgetpass.c $(SUDODEP)
- visudo.o: visudo.c $(SUDODEP) version.h
- sudo.o: sudo.c $(SUDODEP) interfaces.h version.h
- interfaces.o: interfaces.c $(SUDODEP) interfaces.h
- testsudoers.o: testsudoers.c $(SUDODEP) parse.h interfaces.h
- parse.o: parse.c $(SUDODEP) parse.h interfaces.h
- lex.yy.o: lex.yy.c $(SUDODEP) parse.h sudo.tab.h
- sudo.tab.o: sudo.tab.c $(SUDODEP) parse.h sudo.tab.c sudo.tab.h
- defaults.o: defaults.c $(SUDODEP) def_data.c auth/sudo_auth.h
- fnmatch.o: fnmatch.c config.h compat.h emul/fnmatch.h
- getcwd.o: getcwd.c config.h compat.h
- glob.o: glob.c config.h compat.h emul/glob.h
- lsearch.o: lsearch.c config.h compat.h emul/search.h
- memrchr.o: memrchr.c config.h compat.h
- mkstemp.o: mkstemp.c config.h compat.h
- selinux.o: selinux.c $(SUDODEP)
- snprintf.o: snprintf.c config.h compat.h
- strcasecmp.o: strcasecmp.c config.h
- strlcat.o: strlcat.c config.h
- strlcpy.o: strlcpy.c config.h
- strerror.o: strerror.c config.h
- utime.o: utime.c config.h pathnames.h compat.h emul/utime.h
- ldap.o: ldap.c $(SUDODEP) parse.h
- sudo_edit.o: sudo_edit.c $(SUDODEP)
- # Authentication functions live in "auth" dir and so need extra care
+ aix.o: $(srcdir)/aix.c
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/aix.c
+ alias.o: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/redblack.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alias.c
+ alloc.o: $(srcdir)/alloc.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alloc.c
+ check.o: $(srcdir)/check.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/check.c
+ closefrom.o: $(srcdir)/closefrom.c config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/closefrom.c
+ defaults.o: $(srcdir)/defaults.c $(SUDODEP) $(srcdir)/def_data.c $(authdir)/sudo_auth.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/defaults.c
+ env.o: $(srcdir)/env.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/env.c
+ error.o: $(srcdir)/error.c $(srcdir)/compat.h $(srcdir)/error.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/error.c
+ fileops.o: $(srcdir)/fileops.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/fileops.c
+ find_path.o: $(srcdir)/find_path.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/find_path.c
+ fnmatch.o: $(srcdir)/fnmatch.c $(srcdir)/emul/fnmatch.h $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/fnmatch.c
+ getcwd.o: $(srcdir)/getcwd.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/getcwd.c
+ getprogname.o: $(srcdir)/getprogname.c config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/getprogname.c
+ getspwuid.o: $(srcdir)/getspwuid.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/getspwuid.c
+ gettime.o: $(srcdir)/gettime.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/gettime.c
+ glob.o: $(srcdir)/glob.c $(srcdir)/emul/glob.h $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/glob.c
+ goodpath.o: $(srcdir)/goodpath.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/goodpath.c
+ gram.o: $(devdir)/gram.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/gram.c
+ interfaces.o: $(srcdir)/interfaces.c $(SUDODEP) $(srcdir)/interfaces.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/interfaces.c
+ isblank.o: $(srcdir)/isblank.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/isblank.c
+ lbuf.o: $(srcdir)/lbuf.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/lbuf.c
+ ldap.o: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/ldap.c
+ list.o: $(srcdir)/list.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/list.c
+ logging.o: $(srcdir)/logging.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/logging.c
+ match.o: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/match.c
+ memrchr.o: $(srcdir)/memrchr.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/memrchr.c
+ mkstemp.o: $(srcdir)/mkstemp.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/mkstemp.c
+ parse.o: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/parse.c
+ pwutil.o: $(srcdir)/pwutil.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/pwutil.c
+ redblack.o: $(srcdir)/redblack.c $(SUDODEP) $(srcdir)/redblack.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/redblack.c
+ set_perms.o: $(srcdir)/set_perms.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/set_perms.c
+ sigaction.o: $(srcdir)/sigaction.c $(srcdir)/compat.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sigaction.c
+ snprintf.o: $(srcdir)/snprintf.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/snprintf.c
+ strcasecmp.o: $(srcdir)/strcasecmp.c $(srcdir)/compat.h  config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/strcasecmp.c
+ strerror.o: $(srcdir)/strerror.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/strerror.c
+ strlcat.o: $(srcdir)/strlcat.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/strlcat.c
+ strlcpy.o: $(srcdir)/strlcpy.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/strlcpy.c
+ selinux.o: $(srcdir)/selinux.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/selinux.c
+ sudo.o: $(srcdir)/sudo.c $(SUDODEP) sudo_usage.h $(srcdir)/interfaces.h $(srcdir)/version.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo.c
+ sudo_edit.o: $(srcdir)/sudo_edit.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_edit.c
+ sudo_noexec.o: $(srcdir)/sudo_noexec.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_noexec.c
+ sudo_nss.o: $(srcdir)/sudo_nss.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_nss.c
+ testsudoers.o: $(srcdir)/testsudoers.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/testsudoers.c
+ tgetpass.o: $(srcdir)/tgetpass.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tgetpass.c
+ toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke.c
+ tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tsgetgrpw.c
+ utimes.o: $(srcdir)/utimes.c $(srcdir)/compat.h $(srcdir)/emul/utime.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/utimes.c
+ visudo.o: $(srcdir)/visudo.c $(SUDODEP) $(srcdir)/version.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/visudo.c
+ zero_bytes.o: $(srcdir)/zero_bytes.c $(srcdir)/compat.h config.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/zero_bytes.c
+ # Private copy of pwutil.o with MYPW defined for testsudoers
+ tspwutil.o: $(srcdir)/pwutil.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) -DMYPW -o tspwutil.o $(srcdir)/pwutil.c
  sudo_auth.o: $(authdir)/sudo_auth.c $(AUTHDEP) $(INSDEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/sudo_auth.c
  afs.o: $(authdir)/afs.c $(AUTHDEP)
@@@ -304,6 -381,24 +381,24 @@@ sudoers.man:: sudoers.man.i
  
  sudoers.cat: sudoers.man
  
+ sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.pod
+       @rm -f $(srcdir)/$@
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudoers.ldap.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.ldap.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+ sudoers.ldap.man:: sudoers.ldap.man.in
+       CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
+ sudoers.ldap.cat: sudoers.ldap.man
+ @DEV@HISTORY: history.pod
+ @DEV@ pod2text -l -i0 $> > $@
+ @DEV@
+ @DEV@LICENSE: license.pod
+ @DEV@ pod2text -l -i0 $> | sed '1,2d' > $@
+ ChangeLog:
+       cvs2cl --follow-only trunk
  install: install-dirs install-binaries @INSTALL_NOEXEC@ install-sudoers install-man
  
  install-dirs:
@@@ -327,33 -422,28 +422,28 @@@ install-sudoers
            $(INSTALL) -O $(sudoers_uid) -G $(sudoers_gid) -M $(sudoers_mode) \
                $(srcdir)/sudoers $(DESTDIR)$(sudoersdir)/sudoers
  
 -install-man:
 +install-man: sudo.$(mantype) visudo.$(mantype) sudoers.$(mantype)
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(mansectsu)
        @rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)
        ln $(DESTDIR)$(mandirsu)/sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu)
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform)
+       @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
  @MAN_POSTINSTALL@
  
  check:
        @echo nothing to check
  
- tags: $(SRCS)
-       ctags $(SRCS)
- TAGS: $(SRCS)
-       etags $(SRCS)
  clean:
-       -rm -f *.o $(PROGS) testsudoers core sudo.core visudo.core \
-              testsudoers.core
+       -rm -f *.o *.lo stamp-* $(PROGS) testsudoers core *.core core.*
  
  mostlyclean: clean
  
  distclean: clean
        -rm -rf Makefile pathnames.h config.h config.status config.cache \
-               config.log libtool sudo_noexec.lo .libs $(PARSESRCS) \
-               sudo.man sudoers.man visudo.man
+               config.log libtool sudo_noexec.lo .libs $(GENERATED) \
+               sudo.man sudoers.man sudoers.ldap.man visudo.man sudo_usage.h \
+               Makefile.binary
  
  clobber: distclean
  
@@@ -394,7 -484,43 +484,41 @@@ bindist
          fi ; \
          cp $(srcdir)/INSTALL.binary $$tdir/INSTALL ; \
          sh ./config.status --file=Makefile.binary && cp Makefile.binary $$tdir/Makefile ; \
 -        strip $$tdir/sudo ; \
 -        strip $$tdir/visudo ; \
          cd tmp.$$ARCH && tar Ocf ../sudo-$(VERSION)-$$ARCH.tar sudo-$(VERSION) && cd .. ; \
-         gzip --best sudo-$(VERSION)-$$ARCH.tar ; \
+         gzip -f --best sudo-$(VERSION)-$$ARCH.tar ; \
          rm -rf tmp.$$ARCH ; \
        )
+ depot:
+       ( \
+         tdir=tmp.depot ; \
+         mkdir $$tdir ; \
+         for i in sudo visudo sudo.man visudo.man sudoers.man sudoers ChangeLog HISTORY LICENSE README TROUBLESHOOTING UPGRADE sample.syslog.conf sample.sudoers; do \
+           if [ -f $$i ]; then \
+             cp $$i $$tdir ; \
+           elif [ -f $(srcdir)/$$i ]; then \
+             cp $(srcdir)/$$i $$tdir ; \
+           else \
+             echo cannot find $$i ; \
+             exit 1 ; \
+           fi ; \
+         done ; \
+         if [ -f sudo_noexec.la ]; then \
+           cp libtool $$tdir ; \
+           $(LIBTOOL) --mode=install $(INSTALL) sudo_noexec.la `pwd`/$$tdir ; \
+         fi ; \
+         sed 's/@VERSION@/$(VERSION)/g' <$(srcdir)/sudo.psf >$$tdir/sudo.psf ; \
+         printf '#!/sbin/sh\nrm -f /usr/local/bin/sudoedit\nln /usr/local/bin/sudo /usr/local/bin/sudoedit\n' > $$tdir/sudo-exec.postinstall ; \
+         printf '#!/sbin/sh\nrm -f /usr/local/man/man1m/sudoedit.1m\nln /usr/local/man/man1m/sudo.1m /usr/local/man/man1m/sudoedit.1m\n' > $$tdir/sudo-man.postinstall ; \
+         printf '#!/sbin/sh\nif [ ! -s /etc/sudoers ]; then\n\techo installing /usr/local/doc/sudo/sudoers as /etc/sudoers\n\techo use /usr/local/sbin/visudo to configure sudo\n\tcp /usr/local/doc/sudo/sudoers /etc/sudoers\n\tchmod 440 /etc/sudoers\n\tchown root:root /etc/sudoers\nfi\n' > $$tdir/sudo-config.postinstall ; \
+         chmod 755 $$tdir/sudo-exec.postinstall $$tdir/sudo-man.postinstall $$tdir/sudo-config.postinstall ; \
+         strip $$tdir/sudo ; \
+         strip $$tdir/visudo ; \
+         cd $$tdir ; \
+         swpackage -x target_type=tape -d ../sudo-$(VERSION).depot -s sudo.psf ; \
+         cd .. ; \
+         gzip -f --best sudo-$(VERSION).depot; \
+         rm -rf tmp.depot ; \
+       )
+ .PHONY:       ChangeLog
diff --combined configure
index d0ae7da11d7ce5f34ad52b995dd99fdc8c5d3cdf,0bf4e23cf85afae991b60ba2825d13955efdb1ca..8188da6dcf885991b27e3856e1d6f94d33d72076
+++ b/configure
@@@ -1,6 -1,6 +1,6 @@@
  #! /bin/sh
  # Guess values for system-dependent variables and create Makefiles.
- # Generated by GNU Autoconf 2.61 for sudo 1.6.9.
+ # Generated by GNU Autoconf 2.61 for sudo 1.7.
  #
  # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
  # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@@ -722,8 -722,8 +722,8 @@@ SHELL=${CONFIG_SHELL-/bin/sh
  # Identity of this package.
  PACKAGE_NAME='sudo'
  PACKAGE_TARNAME='sudo'
- PACKAGE_VERSION='1.6.9'
- PACKAGE_STRING='sudo 1.6.9'
+ PACKAGE_VERSION='1.7'
+ PACKAGE_STRING='sudo 1.7'
  PACKAGE_BUGREPORT=''
  
  # Factoring default headers for most tests.
@@@ -822,6 -822,7 +822,7 @@@ SELINU
  BAMAN
  LCMAN
  SEMAN
+ devdir
  mansectsu
  mansectform
  mansrcdir
@@@ -830,6 -831,10 +831,10 @@@ NOEXECDI
  noexec_file
  INSTALL_NOEXEC
  DONT_LEAK_PATH_INFO
+ BSDAUTH_USAGE
+ SELINUX_USAGE
+ LDAP
+ LOGINCAP_USAGE
  timedir
  timeout
  password_timeout
@@@ -856,6 -861,9 +861,9 @@@ tty_ticket
  insults
  root_sudo
  path_info
+ ldap_conf
+ ldap_secret
+ nsswitch_conf
  EGREPPROG
  CC
  ac_ct_CC
@@@ -890,7 -898,6 +898,6 @@@ NROFFPRO
  YACC
  YFLAGS
  LIBOBJS
- ALLOCA
  KRB5CONFIG
  LTLIBOBJS'
  ac_subst_files=''
@@@ -1407,7 -1414,7 +1414,7 @@@ if test "$ac_init_help" = "long"; the
    # Omit some internal or obsolete options to make the list less imposing.
    # This message is too long to be a string in the A/UX 3.1 sh.
    cat <<_ACEOF
- \`configure' configures sudo 1.6.9 to adapt to many kinds of systems.
+ \`configure' configures sudo 1.7 to adapt to many kinds of systems.
  
  Usage: $0 [OPTION]... [VAR=VALUE]...
  
@@@ -1444,7 -1451,7 +1451,7 @@@ Fine tuning of the installation directo
    --bindir=DIR           user executables [EPREFIX/bin]
    --sbindir=DIR          system admin executables [EPREFIX/sbin]
    --libexecdir=DIR       program executables [EPREFIX/libexec]
 -  --sysconfdir=DIR       read-only single-machine data [etc]
 +  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
    --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
    --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
    --libdir=DIR           object code libraries [EPREFIX/lib]
  
  if test -n "$ac_init_help"; then
    case $ac_init_help in
-      short | recursive ) echo "Configuration of sudo 1.6.9:";;
+      short | recursive ) echo "Configuration of sudo 1.7:";;
     esac
    cat <<\_ACEOF
  
@@@ -1490,8 -1497,10 +1497,10 @@@ Optional Features
    --enable-log-host       Log the hostname in the log file
    --enable-noargs-shell   If sudo is given no arguments run a shell
    --enable-shell-sets-home
-                           set $HOME to target user in shell mode
+                           Set $HOME to target user in shell mode
    --disable-path-info     Print 'command not allowed' not 'command not found'
+   --enable-gss-krb5-ccache-name
+                           Use GSS-API to set the Kerberos V cred cache name
    --enable-static[=PKGS]  build static libraries [default=no]
    --enable-shared[=PKGS]  build shared libraries [default=yes]
    --enable-fast-install[=PKGS]
@@@ -1567,6 -1576,7 +1576,7 @@@ Optional Packages
    --with-csops-insults    include CSOps insults
    --with-hal-insults      include 2001-like insults
    --with-goons-insults    include the insults from the "Goon Show"
+   --with-nsswitch[=PATH]  path to nsswitch.conf
    --with-ldap[=DIR]       enable LDAP support
    --with-ldap-conf-file   path to LDAP configuration file
    --with-ldap-secret-file path to LDAP secret password file
    --with-secure-path      override the user's path with a built-in one
    --without-interfaces    don't try to read the ip addr of ether interfaces
    --with-stow             properly handle GNU stow packaging
+   --with-askpass=PATH     Fully qualified pathname of askpass helper
    --with-selinux          enable SELinux support
    --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
    --with-pic              try to use only PIC/non-PIC objects [default=use
  test -n "$ac_init_help" && exit $ac_status
  if $ac_init_version; then
    cat <<\_ACEOF
- sudo configure 1.6.9
+ sudo configure 1.7
  generated by GNU Autoconf 2.61
  
  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@@ -1672,7 -1683,7 +1683,7 @@@ cat >config.log <<_ACEO
  This file contains any messages produced by compilers while
  running configure, to aid debugging if configure makes a mistake.
  
- It was created by sudo $as_me 1.6.9, which was
+ It was created by sudo $as_me 1.7, which was
  generated by GNU Autoconf 2.61.  Invocation command line was
  
    $ $0 $@
@@@ -2027,8 -2038,16 +2038,16 @@@ ac_compiler_gnu=$ac_cv_c_compiler_gn
  
  ac_config_headers="$ac_config_headers config.h pathnames.h"
  
- { echo "$as_me:$LINENO: Configuring Sudo version 1.6.9" >&5
- echo "$as_me: Configuring Sudo version 1.6.9" >&6;}
+ { echo "$as_me:$LINENO: Configuring Sudo version 1.7" >&5
+ echo "$as_me: Configuring Sudo version 1.7" >&6;}
  
  
  
@@@ -2112,6 -2131,7 +2131,7 @@@ insults=of
  root_sudo=on
  path_info=on
  INSTALL_NOEXEC=
+ devdir='$(srcdir)'
  PROGS="sudo visudo"
  : ${MANTYPE='man'}
  : ${mansrcdir='.'}
  : ${SUDOERS_UID='0'}
  : ${SUDOERS_GID='0'}
  DEV="#"
+ LDAP="#"
  SELINUX="#"
  BAMAN='.\" '
  LCMAN='.\" '
@@@ -2282,6 -2303,7 +2303,7 @@@ echo "$as_me: Setting up for developmen
                PROGS="${PROGS} testsudoers"
                OSDEFS="${OSDEFS} -DSUDO_DEVEL"
                DEV=""
+               devdir=.
                ;;
      no)               ;;
      *)                { echo "$as_me:$LINENO: WARNING: Ignoring unknown argument to --with-devel: $with_devel" >&5
  
  
  
+ # Check whether --with-nsswitch was given.
+ if test "${with_nsswitch+set}" = set; then
+   withval=$with_nsswitch; case $with_nsswitch in
+     no)               ;;
+     yes)      with_nsswitch="/etc/nsswitch.conf"
+               ;;
+     *)                ;;
+ esac
+ fi
+ if test ${with_nsswitch-"yes"} != "no"; then
+     cat >>confdefs.h <<EOF
+ #define _PATH_NSSWITCH_CONF "${with_nsswitch-/etc/nsswitch.conf}"
+ EOF
+     nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
+ else
+     nsswitch_conf='/etc/nsswitch.conf'
+ fi
  # Check whether --with-ldap was given.
  if test "${with_ldap+set}" = set; then
    withval=$with_ldap; case $with_ldap in
  fi
  
  
  # Check whether --with-ldap-conf-file was given.
  if test "${with_ldap_conf_file+set}" = set; then
    withval=$with_ldap_conf_file;
- cat >>confdefs.h <<_ACEOF
- #define _PATH_LDAP_CONF "$with_ldap_conf_file"
- _ACEOF
  fi
  
+ cat >>confdefs.h <<EOF
+ #define _PATH_LDAP_CONF "${with_ldap_conf_file-/etc/ldap.conf}"
+ EOF
+ ldap_conf=${with_ldap_conf_file-'/etc/ldap.conf'}
  
  # Check whether --with-ldap-secret-file was given.
  if test "${with_ldap_secret_file+set}" = set; then
    withval=$with_ldap_secret_file;
- cat >>confdefs.h <<_ACEOF
- #define _PATH_LDAP_SECRET "$with_ldap_secret_file"
- _ACEOF
  fi
  
+ cat >>confdefs.h <<EOF
+ #define _PATH_LDAP_SECRET "${with_ldap_secret_file-/etc/ldap.secret}"
+ EOF
+ ldap_secret=${with_ldap_secret_file-'/etc/ldap.secret'}
  
  
  # Check whether --with-pc-insults was given.
@@@ -3698,6 -3745,30 +3745,30 @@@ echo "${ECHO_T}no" >&6; 
  fi
  
  
+ { echo "$as_me:$LINENO: checking whether to use an askpass helper" >&5
+ echo $ECHO_N "checking whether to use an askpass helper... $ECHO_C" >&6; }
+ # Check whether --with-askpass was given.
+ if test "${with_askpass+set}" = set; then
+   withval=$with_askpass; case $with_askpass in
+     yes)      { { echo "$as_me:$LINENO: error: \"--with-askpass takes a path as an argument.\"" >&5
+ echo "$as_me: error: \"--with-askpass takes a path as an argument.\"" >&2;}
+    { (exit 1); exit 1; }; }
+               ;;
+     no)               ;;
+     *)
+ cat >>confdefs.h <<_ACEOF
+ #define _PATH_SUDO_ASKPASS "$with_askpass"
+ _ACEOF
+               ;;
+ esac
+ else
+   { echo "$as_me:$LINENO: result: no" >&5
+ echo "${ECHO_T}no" >&6; }
+ fi
  
  { echo "$as_me:$LINENO: checking whether to do user authentication by default" >&5
  echo $ECHO_N "checking whether to do user authentication by default... $ECHO_C" >&6; }
  # Check whether --with-selinux was given.
  if test "${with_selinux+set}" = set; then
    withval=$with_selinux; case $with_selinux in
-     yes)      cat >>confdefs.h <<\_ACEOF
+     yes)      SELINUX_USAGE="[-r role] [-t type] "
+               cat >>confdefs.h <<\_ACEOF
  #define HAVE_SELINUX 1
  _ACEOF
  
  fi
  
  
+ # Check whether --enable-gss_krb5_ccache_name was given.
+ if test "${enable_gss_krb5_ccache_name+set}" = set; then
+   enableval=$enable_gss_krb5_ccache_name; check_gss_krb5_ccache_name=$enableval
+ else
+   check_gss_krb5_ccache_name=no
+ fi
  # Extract the first word of "egrep", so it can be a program name with args.
  set dummy egrep; ac_word=$2
  { echo "$as_me:$LINENO: checking for $ac_word" >&5
@@@ -6129,7 -6209,7 +6209,7 @@@ ia64-*-hpux*
    ;;
  *-*-irix6*)
    # Find out which ABI we are using.
-   echo '#line 6132 "configure"' > conftest.$ac_ext
+   echo '#line 6212 "configure"' > conftest.$ac_ext
    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
    (eval $ac_compile) 2>&5
    ac_status=$?
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
-    (eval echo "\"\$as_me:7991: $lt_compile\"" >&5)
+    (eval echo "\"\$as_me:8071: $lt_compile\"" >&5)
     (eval "$lt_compile" 2>conftest.err)
     ac_status=$?
     cat conftest.err >&5
-    echo "$as_me:7995: \$? = $ac_status" >&5
+    echo "$as_me:8075: \$? = $ac_status" >&5
     if (exit $ac_status) && test -s "$ac_outfile"; then
       # The compiler can only warn and ignore the option if not recognized
       # So say no if there are warnings other than the usual output.
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
-    (eval echo "\"\$as_me:8281: $lt_compile\"" >&5)
+    (eval echo "\"\$as_me:8361: $lt_compile\"" >&5)
     (eval "$lt_compile" 2>conftest.err)
     ac_status=$?
     cat conftest.err >&5
-    echo "$as_me:8285: \$? = $ac_status" >&5
+    echo "$as_me:8365: \$? = $ac_status" >&5
     if (exit $ac_status) && test -s "$ac_outfile"; then
       # The compiler can only warn and ignore the option if not recognized
       # So say no if there are warnings other than the usual output.
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
-    (eval echo "\"\$as_me:8385: $lt_compile\"" >&5)
+    (eval echo "\"\$as_me:8465: $lt_compile\"" >&5)
     (eval "$lt_compile" 2>out/conftest.err)
     ac_status=$?
     cat out/conftest.err >&5
-    echo "$as_me:8389: \$? = $ac_status" >&5
+    echo "$as_me:8469: \$? = $ac_status" >&5
     if (exit $ac_status) && test -s out/conftest2.$ac_objext
     then
       # The compiler can only warn and ignore the option if not recognized
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<EOF
- #line 10745 "configure"
+ #line 10825 "configure"
  #include "confdefs.h"
  
  #if HAVE_DLFCN_H
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<EOF
- #line 10845 "configure"
+ #line 10925 "configure"
  #include "confdefs.h"
  
  #if HAVE_DLFCN_H
  done
  
                fi
+               # AIX-specific functions
+ for ac_func in getuserattr
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $ac_func innocuous_$ac_func
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ #undef $ac_func
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char $ac_func ();
+ /* 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
+ #endif
+ int
+ main ()
+ {
+ return $ac_func ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   eval "$as_ac_var=yes"
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       eval "$as_ac_var=no"
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ fi
+ ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ if test `eval echo '${'$as_ac_var'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+ fi
+ done
+               SUDO_OBJS="$SUDO_OBJS aix.o"
                ;;
      *-*-hiuxmpp*)
                : ${mansectsu='1m'}
                : ${mansectsu='1m'}
                : ${mansectform='4'}
  
+               # HP-UX bundled compiler can't generate shared objects
+               if test "x$ac_cv_prog_cc_c89" = "xno"; then
+                   with_noexec=no
+               fi
                case "$host" in
                        *-*-hpux1-8.*)
                            cat >>confdefs.h <<\_ACEOF
  
  done
  
+ if test "$OS" != "ultrix"; then
+     { echo "$as_me:$LINENO: checking POSIX termios" >&5
+ echo $ECHO_N "checking POSIX termios... $ECHO_C" >&6; }
+ if test "${ac_cv_sys_posix_termios+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <termios.h>
+ int
+ main ()
+ {
+ /* SunOS 4.0.3 has termios.h but not the library calls.  */
+    tcgetattr(0, 0);
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   ac_cv_sys_posix_termios=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_cv_sys_posix_termios=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_sys_posix_termios" >&5
+ echo "${ECHO_T}$ac_cv_sys_posix_termios" >&6; }
+     if test "$ac_cv_sys_posix_termios" = "yes"; then
+       cat >>confdefs.h <<\_ACEOF
+ #define HAVE_TERMIOS_H 1
+ _ACEOF
+     else
  
- for ac_header in err.h
+ for ac_header in termio.h
  do
  as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
  if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@@ -13703,248 -13947,38 +13947,38 @@@ if test `eval echo '${'$as_ac_Header'}'
  #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
  _ACEOF
  
- else
-   case " $LIBOBJS " in
-   *" err.$ac_objext "* ) ;;
-   *) LIBOBJS="$LIBOBJS err.$ac_objext"
-  ;;
- esac
  fi
  
  done
  
- if test "$OS" != "ultrix"; then
-     { echo "$as_me:$LINENO: checking POSIX termios" >&5
- echo $ECHO_N "checking POSIX termios... $ECHO_C" >&6; }
- if test "${ac_cv_sys_posix_termios+set}" = set; then
+     fi
+ fi
+ if test ${with_logincap-'no'} != "no"; then
+ for ac_header in login_cap.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
  else
-   cat >conftest.$ac_ext <<_ACEOF
+   # Is the header compilable?
+ { echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- #include <sys/types.h>
- #include <unistd.h>
- #include <termios.h>
- int
- main ()
- {
- /* SunOS 4.0.3 has termios.h but not the library calls.  */
-    tcgetattr(0, 0);
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   ac_cv_sys_posix_termios=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       ac_cv_sys_posix_termios=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_sys_posix_termios" >&5
- echo "${ECHO_T}$ac_cv_sys_posix_termios" >&6; }
-     if test "$ac_cv_sys_posix_termios" = "yes"; then
-       cat >>confdefs.h <<\_ACEOF
- #define HAVE_TERMIOS_H 1
- _ACEOF
-     else
- for ac_header in termio.h
- do
- as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
- if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-   { echo "$as_me:$LINENO: checking for $ac_header" >&5
- echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
- if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- fi
- ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- else
-   # Is the header compilable?
- { echo "$as_me:$LINENO: checking $ac_header usability" >&5
- echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- $ac_includes_default
- #include <$ac_header>
- _ACEOF
- rm -f conftest.$ac_objext
- if { (ac_try="$ac_compile"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_compile") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest.$ac_objext; then
-   ac_header_compiler=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       ac_header_compiler=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
- echo "${ECHO_T}$ac_header_compiler" >&6; }
- # Is the header present?
- { echo "$as_me:$LINENO: checking $ac_header presence" >&5
- echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #include <$ac_header>
- _ACEOF
- if { (ac_try="$ac_cpp conftest.$ac_ext"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } >/dev/null && {
-        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        }; then
-   ac_header_preproc=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-   ac_header_preproc=no
- fi
- rm -f conftest.err conftest.$ac_ext
- { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
- echo "${ECHO_T}$ac_header_preproc" >&6; }
- # So?  What about this header?
- case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-   yes:no: )
-     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
- echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
- echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-     ac_header_preproc=yes
-     ;;
-   no:yes:* )
-     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
- echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
- echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
- echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
- echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
- echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
- echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-     ;;
- esac
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
- echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
- if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   eval "$as_ac_Header=\$ac_header_preproc"
- fi
- ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- fi
- if test `eval echo '${'$as_ac_Header'}'` = yes; then
-   cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
- _ACEOF
- fi
- done
-     fi
- fi
- if test ${with_logincap-'no'} != "no"; then
- for ac_header in login_cap.h
- do
- as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
- if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-   { echo "$as_me:$LINENO: checking for $ac_header" >&5
- echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
- if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- fi
- ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- else
-   # Is the header compilable?
- { echo "$as_me:$LINENO: checking $ac_header usability" >&5
- echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- $ac_includes_default
- #include <$ac_header>
+ $ac_includes_default
+ #include <$ac_header>
  _ACEOF
  rm -f conftest.$ac_objext
  if { (ac_try="$ac_compile"
@@@ -14055,7 -14089,7 +14089,7 @@@ if test `eval echo '${'$as_ac_Header'}'
    cat >>confdefs.h <<_ACEOF
  #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
  _ACEOF
-  LCMAN=""
+  LOGINCAP_USAGE='[-c class|-] '; LCMAN=""
        case "$OS" in
            freebsd|netbsd)     SUDO_LIBS="${SUDO_LIBS} -lutil"
            ;;
@@@ -14305,9 -14339,9 +14339,9 @@@ _ACEO
  
  fi
  
- { echo "$as_me:$LINENO: checking for sig_atomic_t" >&5
- echo $ECHO_N "checking for sig_atomic_t... $ECHO_C" >&6; }
- if test "${ac_cv_type_sig_atomic_t+set}" = set; then
+ { echo "$as_me:$LINENO: checking for __signed char" >&5
+ echo $ECHO_N "checking for __signed char... $ECHO_C" >&6; }
+ if test "${ac_cv_type___signed_char+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    cat >conftest.$ac_ext <<_ACEOF
@@@ -14316,10 -14350,8 +14350,8 @@@ _ACEO
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- #include <sys/types.h>
- #include <signal.h>
- typedef sig_atomic_t ac__type_new_;
+ $ac_includes_default
+ typedef __signed char ac__type_new_;
  int
  main ()
  {
@@@ -14348,35 -14380,24 +14380,24 @@@ eval "echo \"\$as_me:$LINENO: $ac_try_e
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
         } && test -s conftest.$ac_objext; then
-   ac_cv_type_sig_atomic_t=yes
+   ac_cv_type___signed_char=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       ac_cv_type_sig_atomic_t=no
+       ac_cv_type___signed_char=no
  fi
  
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  fi
- { echo "$as_me:$LINENO: result: $ac_cv_type_sig_atomic_t" >&5
- echo "${ECHO_T}$ac_cv_type_sig_atomic_t" >&6; }
- if test $ac_cv_type_sig_atomic_t = yes; then
- cat >>confdefs.h <<_ACEOF
- #define HAVE_SIG_ATOMIC_T 1
- _ACEOF
+ { echo "$as_me:$LINENO: result: $ac_cv_type___signed_char" >&5
+ echo "${ECHO_T}$ac_cv_type___signed_char" >&6; }
+ if test $ac_cv_type___signed_char = yes; then
+   :
  else
-   cat >>confdefs.h <<\_ACEOF
- #define sig_atomic_t int
- _ACEOF
- fi
- { echo "$as_me:$LINENO: checking for sigaction_t" >&5
- echo $ECHO_N "checking for sigaction_t... $ECHO_C" >&6; }
- if test "${ac_cv_type_sigaction_t+set}" = set; then
+   { echo "$as_me:$LINENO: checking for signed char" >&5
+ echo $ECHO_N "checking for signed char... $ECHO_C" >&6; }
+ if test "${ac_cv_type_signed_char+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    cat >conftest.$ac_ext <<_ACEOF
@@@ -14385,10 -14406,8 +14406,8 @@@ _ACEO
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- #include <sys/types.h>
- #include <signal.h>
- typedef sigaction_t ac__type_new_;
+ $ac_includes_default
+ typedef signed char ac__type_new_;
  int
  main ()
  {
@@@ -14417,33 -14436,166 +14436,166 @@@ eval "echo \"\$as_me:$LINENO: $ac_try_e
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
         } && test -s conftest.$ac_objext; then
-   ac_cv_type_sigaction_t=yes
+   ac_cv_type_signed_char=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       ac_cv_type_sigaction_t=no
+       ac_cv_type_signed_char=no
  fi
  
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  fi
- { echo "$as_me:$LINENO: result: $ac_cv_type_sigaction_t" >&5
- echo "${ECHO_T}$ac_cv_type_sigaction_t" >&6; }
- if test $ac_cv_type_sigaction_t = yes; then
- cat >>confdefs.h <<_ACEOF
- #define HAVE_SIGACTION_T 1
+ { echo "$as_me:$LINENO: result: $ac_cv_type_signed_char" >&5
+ echo "${ECHO_T}$ac_cv_type_signed_char" >&6; }
+ if test $ac_cv_type_signed_char = yes; then
+   cat >>confdefs.h <<\_ACEOF
+ #define __signed signed
  _ACEOF
  
- cat >>confdefs.h <<\_ACEOF
- #define HAVE_SIGACTION_T 1
+ else
+   cat >>confdefs.h <<\_ACEOF
+ #define __signed
  _ACEOF
  
  fi
  
- { echo "$as_me:$LINENO: checking for struct timespec" >&5
- echo $ECHO_N "checking for struct timespec... $ECHO_C" >&6; }
- if test "${ac_cv_type_struct_timespec+set}" = set; then
+ fi
+ { echo "$as_me:$LINENO: checking for sig_atomic_t" >&5
+ echo $ECHO_N "checking for sig_atomic_t... $ECHO_C" >&6; }
+ if test "${ac_cv_type_sig_atomic_t+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <sys/types.h>
+ #include <signal.h>
+ typedef sig_atomic_t ac__type_new_;
+ int
+ main ()
+ {
+ if ((ac__type_new_ *) 0)
+   return 0;
+ if (sizeof (ac__type_new_))
+   return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   ac_cv_type_sig_atomic_t=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_cv_type_sig_atomic_t=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_type_sig_atomic_t" >&5
+ echo "${ECHO_T}$ac_cv_type_sig_atomic_t" >&6; }
+ if test $ac_cv_type_sig_atomic_t = yes; then
+   :
+ else
+   cat >>confdefs.h <<\_ACEOF
+ #define sig_atomic_t int
+ _ACEOF
+ fi
+ { echo "$as_me:$LINENO: checking for sigaction_t" >&5
+ echo $ECHO_N "checking for sigaction_t... $ECHO_C" >&6; }
+ if test "${ac_cv_type_sigaction_t+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <sys/types.h>
+ #include <signal.h>
+ typedef sigaction_t ac__type_new_;
+ int
+ main ()
+ {
+ if ((ac__type_new_ *) 0)
+   return 0;
+ if (sizeof (ac__type_new_))
+   return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   ac_cv_type_sigaction_t=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_cv_type_sigaction_t=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_type_sigaction_t" >&5
+ echo "${ECHO_T}$ac_cv_type_sigaction_t" >&6; }
+ if test $ac_cv_type_sigaction_t = yes; then
+ cat >>confdefs.h <<_ACEOF
+ #define HAVE_SIGACTION_T 1
+ _ACEOF
+ cat >>confdefs.h <<\_ACEOF
+ #define HAVE_SIGACTION_T 1
+ _ACEOF
+ fi
+ { echo "$as_me:$LINENO: checking for struct timespec" >&5
+ echo $ECHO_N "checking for struct timespec... $ECHO_C" >&6; }
+ if test "${ac_cv_type_struct_timespec+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    cat >conftest.$ac_ext <<_ACEOF
@@@ -14729,61 -14881,6 +14881,6 @@@ _ACEO
  
  fi
  
- { echo "$as_me:$LINENO: checking for full void implementation" >&5
- echo $ECHO_N "checking for full void implementation... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- int
- main ()
- {
- void *foo;
- foo = (void *)0; (void *)"test";
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext
- if { (ac_try="$ac_compile"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_compile") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest.$ac_objext; then
- cat >>confdefs.h <<\_ACEOF
- #define VOID void
- _ACEOF
- { echo "$as_me:$LINENO: result: yes" >&5
- echo "${ECHO_T}yes" >&6; }
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       cat >>confdefs.h <<\_ACEOF
- #define VOID char
- _ACEOF
- { echo "$as_me:$LINENO: result: no" >&5
- echo "${ECHO_T}no" >&6; }
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  
  { echo "$as_me:$LINENO: checking max length of uid_t" >&5
  echo $ECHO_N "checking max length of uid_t... $ECHO_C" >&6; }
  done
  
  
- for ac_func in lsearch
+ for ac_func in utimes
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
  { echo "$as_me:$LINENO: checking for $ac_func" >&5
@@@ -16832,20 -16929,37 +16929,37 @@@ if test `eval echo '${'$as_ac_var'}'` 
  #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
  _ACEOF
  
- else
-   { echo "$as_me:$LINENO: checking for lsearch in -lcompat" >&5
- echo $ECHO_N "checking for lsearch in -lcompat... $ECHO_C" >&6; }
- if test "${ac_cv_lib_compat_lsearch+set}" = set; then
+ for ac_func in futimes futimesat
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
-   ac_check_lib_save_LIBS=$LIBS
- LIBS="-lcompat  $LIBS"
- cat >conftest.$ac_ext <<_ACEOF
+   cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
+ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $ac_func innocuous_$ac_func
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ #undef $ac_func
  
  /* Override any GCC internal prototype to avoid an error.
     Use char because int might match the return type of a GCC
  #ifdef __cplusplus
  extern "C"
  #endif
- char lsearch ();
+ char $ac_func ();
+ /* 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
+ #endif
  int
  main ()
  {
- return lsearch ();
+ return $ac_func ();
    ;
    return 0;
  }
@@@ -16880,282 -17001,36 +17001,36 @@@ eval "echo \"\$as_me:$LINENO: $ac_try_e
         test ! -s conftest.err
         } && test -s conftest$ac_exeext &&
         $as_test_x conftest$ac_exeext; then
-   ac_cv_lib_compat_lsearch=yes
+   eval "$as_ac_var=yes"
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       ac_cv_lib_compat_lsearch=no
+       eval "$as_ac_var=no"
  fi
  
  rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
        conftest$ac_exeext conftest.$ac_ext
- LIBS=$ac_check_lib_save_LIBS
  fi
- { echo "$as_me:$LINENO: result: $ac_cv_lib_compat_lsearch" >&5
- echo "${ECHO_T}$ac_cv_lib_compat_lsearch" >&6; }
- if test $ac_cv_lib_compat_lsearch = yes; then
-   { echo "$as_me:$LINENO: checking for search.h" >&5
- echo $ECHO_N "checking for search.h... $ECHO_C" >&6; }
- if test "${ac_cv_header_search_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #include <search.h>
- _ACEOF
- if { (ac_try="$ac_cpp conftest.$ac_ext"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } >/dev/null && {
-        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        }; then
-   ac_cv_header_search_h=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-   ac_cv_header_search_h=no
- fi
- rm -f conftest.err conftest.$ac_ext
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_header_search_h" >&5
- echo "${ECHO_T}$ac_cv_header_search_h" >&6; }
- if test $ac_cv_header_search_h = yes; then
-   cat >>confdefs.h <<\_ACEOF
- #define HAVE_LSEARCH 1
- _ACEOF
-  LIBS="${LIBS} -lcompat"
- else
-   case " $LIBOBJS " in
-   *" lsearch.$ac_objext "* ) ;;
-   *) LIBOBJS="$LIBOBJS lsearch.$ac_objext"
-  ;;
- esac
- fi
- else
-   case " $LIBOBJS " in
-   *" lsearch.$ac_objext "* ) ;;
-   *) LIBOBJS="$LIBOBJS lsearch.$ac_objext"
-  ;;
- esac
- fi
- fi
- done
- for ac_func in utimes
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $ac_func innocuous_$ac_func
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $ac_func (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- #undef $ac_func
- /* Override any GCC internal prototype to avoid an error.
-    Use char because int might match the return type of a GCC
-    builtin and then its argument prototype would still apply.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- char $ac_func ();
- /* 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
- #endif
- int
- main ()
- {
- return $ac_func ();
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   eval "$as_ac_var=yes"
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       eval "$as_ac_var=no"
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- if test `eval echo '${'$as_ac_var'}'` = yes; then
-   cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
- _ACEOF
- for ac_func in futimes futimesat
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $ac_func innocuous_$ac_func
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $ac_func (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- #undef $ac_func
- /* Override any GCC internal prototype to avoid an error.
-    Use char because int might match the return type of a GCC
-    builtin and then its argument prototype would still apply.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- char $ac_func ();
- /* 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
- #endif
- int
- main ()
- {
- return $ac_func ();
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   eval "$as_ac_var=yes"
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       eval "$as_ac_var=no"
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- if test `eval echo '${'$as_ac_var'}'` = yes; then
-   cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
- _ACEOF
-  break
- fi
- done
- else
- for ac_func in futime
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ if test `eval echo '${'$as_ac_var'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+  break
+ fi
+ done
+ else
+ for ac_func in futime
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    cat >conftest.$ac_ext <<_ACEOF
@@@ -17379,6 -17254,13 +17254,13 @@@ cat >>confdefs.h <<\_ACEO
  #define HAVE_ISBLANK 1
  _ACEOF
  
+   else
+     case " $LIBOBJS " in
+   *" isblank.$ac_objext "* ) ;;
+   *) LIBOBJS="$LIBOBJS isblank.$ac_objext"
+  ;;
+ esac
    fi
  
  
  
  fi
  
- 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 "$as_me:$LINENO: checking for working alloca.h" >&5
- echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; }
- if test "${ac_cv_working_alloca_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #include <alloca.h>
- int
- main ()
- {
- char *p = (char *) alloca (2 * sizeof (int));
-                         if (p) return 0;
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   ac_cv_working_alloca_h=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       ac_cv_working_alloca_h=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
- echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; }
- if test $ac_cv_working_alloca_h = yes; then
- cat >>confdefs.h <<\_ACEOF
- #define HAVE_ALLOCA_H 1
- _ACEOF
- fi
- { echo "$as_me:$LINENO: checking for alloca" >&5
- echo $ECHO_N "checking for alloca... $ECHO_C" >&6; }
- if test "${ac_cv_func_alloca_works+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #ifdef __GNUC__
- # define alloca __builtin_alloca
- #else
- # ifdef _MSC_VER
- #  include <malloc.h>
- #  define alloca _alloca
- # else
- #  ifdef HAVE_ALLOCA_H
- #   include <alloca.h>
- #  else
- #   ifdef _AIX
-  #pragma alloca
- #   else
- #    ifndef alloca /* predefined by HP cc +Olibcalls */
- char *alloca ();
- #    endif
- #   endif
- #  endif
- # endif
- #endif
- int
- main ()
- {
- char *p = (char *) alloca (1);
-                                   if (p) return 0;
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   ac_cv_func_alloca_works=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       ac_cv_func_alloca_works=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
- echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; }
- if test $ac_cv_func_alloca_works = yes; then
- cat >>confdefs.h <<\_ACEOF
- #define HAVE_ALLOCA 1
- _ACEOF
- else
-   # The SVR3 libPW and SVR4 libucb both contain incompatible functions
- # that cause trouble.  Some versions do not even contain alloca or
- # contain a buggy version.  If you still want to use their alloca,
- # use ar to extract alloca.o from them instead of compiling alloca.c.
- ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
- cat >>confdefs.h <<\_ACEOF
- #define C_ALLOCA 1
- _ACEOF
- { echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
- echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; }
- if test "${ac_cv_os_cray+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #if defined CRAY && ! defined CRAY2
- webecray
- #else
- wenotbecray
- #endif
- _ACEOF
- if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-   $EGREP "webecray" >/dev/null 2>&1; then
-   ac_cv_os_cray=yes
- else
-   ac_cv_os_cray=no
- fi
- rm -f conftest*
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
- echo "${ECHO_T}$ac_cv_os_cray" >&6; }
- if test $ac_cv_os_cray = yes; then
-   for ac_func in _getb67 GETB67 getb67; do
-     as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ for ac_func in getprogname
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    cat >conftest.$ac_ext <<_ACEOF
@@@ -19610,147 -19309,115 +19309,115 @@@ ac_res=`eval echo '${'$as_ac_var'}'
               { echo "$as_me:$LINENO: result: $ac_res" >&5
  echo "${ECHO_T}$ac_res" >&6; }
  if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
- #define CRAY_STACKSEG_END $ac_func
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
  _ACEOF
  
-     break
- fi
-   done
- fi
+ else
  
{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
- echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; }
if test "${ac_cv_c_stack_direction+set}" = set; then
    { echo "$as_me:$LINENO: checking for __progname" >&5
+ echo $ECHO_N "checking for __progname... $ECHO_C" >&6; }
    if test "${sudo_cv___progname+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
-   if test "$cross_compiling" = yes; then
-   ac_cv_c_stack_direction=0
- else
-   cat >conftest.$ac_ext <<_ACEOF
+     cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- $ac_includes_default
- int
- find_stack_direction ()
- {
-   static char *addr = 0;
-   auto char dummy;
-   if (addr == 0)
-     {
-       addr = &dummy;
-       return find_stack_direction ();
-     }
-   else
-     return (&dummy > addr) ? 1 : -1;
- }
  
  int
  main ()
  {
-   return find_stack_direction () < 0;
+ extern char *__progname; (void)puts(__progname);
+   ;
+   return 0;
  }
  _ACEOF
- rm -f conftest$ac_exeext
+ rm -f conftest.$ac_objext conftest$ac_exeext
  if { (ac_try="$ac_link"
  case "(($ac_try" in
    *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
    *) ac_try_echo=$ac_try;;
  esac
  eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-   { (case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_try") 2>&5
+   (eval "$ac_link") 2>conftest.er1
    ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; }; then
-   ac_cv_c_stack_direction=1
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   sudo_cv___progname=yes
  else
-   echo "$as_me: program exited with status $ac_status" >&5
- echo "$as_me: failed program was:" >&5
+   echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
- ( exit $ac_status )
- ac_cv_c_stack_direction=-1
- fi
- rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+       sudo_cv___progname=no
  fi
  
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
  fi
- { echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
- echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; }
  
- cat >>confdefs.h <<_ACEOF
- #define STACK_DIRECTION $ac_cv_c_stack_direction
+     if test "$sudo_cv___progname" = "yes"; then
+       cat >>confdefs.h <<\_ACEOF
+ #define HAVE___PROGNAME 1
  _ACEOF
  
+     else
+       case " $LIBOBJS " in
+   *" getprogname.$ac_objext "* ) ;;
+   *) LIBOBJS="$LIBOBJS getprogname.$ac_objext"
+  ;;
+ esac
+     fi
+     { echo "$as_me:$LINENO: result: $sudo_cv___progname" >&5
+ echo "${ECHO_T}$sudo_cv___progname" >&6; }
  
  fi
+ done
  
+ if test -z "${AUTH_EXCL}${AUTH_REG}" -a -n "$AUTH_EXCL_DEF"; then
+     for auth in $AUTH_EXCL_DEF; do
+       case $auth in
+           AIX_AUTH)   with_aixauth=maybe;;
+           BSD_AUTH)   with_bsdauth=maybe;;
+           PAM)        with_pam=maybe;;
+           SIA)        CHECKSIA=true;;
+       esac
+     done
  fi
  
- for ac_func in getprogname
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ if test ${with_pam-"no"} != "no"; then
+                 { echo "$as_me:$LINENO: checking for main in -ldl" >&5
+ echo $ECHO_N "checking for main in -ldl... $ECHO_C" >&6; }
+ if test "${ac_cv_lib_dl_main+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
-   cat >conftest.$ac_ext <<_ACEOF
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-ldl  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $ac_func innocuous_$ac_func
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $ac_func (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- #undef $ac_func
  
- /* Override any GCC internal prototype to avoid an error.
-    Use char because int might match the return type of a GCC
-    builtin and then its argument prototype would still apply.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- char $ac_func ();
- /* 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
- #endif
  
  int
  main ()
  {
- return $ac_func ();
+ return main ();
    ;
    return 0;
  }
@@@ -19773,163 -19440,17 +19440,17 @@@ eval "echo \"\$as_me:$LINENO: $ac_try_e
         test ! -s conftest.err
         } && test -s conftest$ac_exeext &&
         $as_test_x conftest$ac_exeext; then
-   eval "$as_ac_var=yes"
+   ac_cv_lib_dl_main=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       eval "$as_ac_var=no"
+       ac_cv_lib_dl_main=no
  fi
  
  rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
        conftest$ac_exeext conftest.$ac_ext
- fi
- ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
- echo "${ECHO_T}$ac_res" >&6; }
- if test `eval echo '${'$as_ac_var'}'` = yes; then
-   cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
- _ACEOF
- else
-     { echo "$as_me:$LINENO: checking for __progname" >&5
- echo $ECHO_N "checking for __progname... $ECHO_C" >&6; }
-     if test "${sudo_cv___progname+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-     cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- int
- main ()
- {
- extern char *__progname; (void)puts(__progname);
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   sudo_cv___progname=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       sudo_cv___progname=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- fi
-     if test "$sudo_cv___progname" = "yes"; then
-       cat >>confdefs.h <<\_ACEOF
- #define HAVE___PROGNAME 1
- _ACEOF
-     else
-       case " $LIBOBJS " in
-   *" getprogname.$ac_objext "* ) ;;
-   *) LIBOBJS="$LIBOBJS getprogname.$ac_objext"
-  ;;
- esac
-     fi
-     { echo "$as_me:$LINENO: result: $sudo_cv___progname" >&5
- echo "${ECHO_T}$sudo_cv___progname" >&6; }
- fi
- done
- if test -z "${AUTH_EXCL}${AUTH_REG}" -a -n "$AUTH_EXCL_DEF"; then
-     for auth in $AUTH_EXCL_DEF; do
-       case $auth in
-           AIX_AUTH)   with_aixauth=maybe;;
-           BSD_AUTH)   with_bsdauth=maybe;;
-           PAM)        with_pam=maybe;;
-           SIA)        CHECKSIA=true;;
-       esac
-     done
- fi
- if test ${with_pam-"no"} != "no"; then
-                 { echo "$as_me:$LINENO: checking for main in -ldl" >&5
- echo $ECHO_N "checking for main in -ldl... $ECHO_C" >&6; }
- if test "${ac_cv_lib_dl_main+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   ac_check_lib_save_LIBS=$LIBS
- LIBS="-ldl  $LIBS"
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- int
- main ()
- {
- return main ();
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
- case "(($ac_try" in
-   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-   *) ac_try_echo=$ac_try;;
- esac
- eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   ac_cv_lib_dl_main=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
-       ac_cv_lib_dl_main=no
- fi
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
- LIBS=$ac_check_lib_save_LIBS
+ LIBS=$ac_check_lib_save_LIBS
  fi
  { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_main" >&5
  echo "${ECHO_T}$ac_cv_lib_dl_main" >&6; }
@@@ -20099,8 -19620,9 +19620,9 @@@ echo "${ECHO_T}yes" >&6; 
                        ;;
                no)             { echo "$as_me:$LINENO: result: no" >&5
  echo "${ECHO_T}no" >&6; }
-                           cat >>confdefs.h <<\_ACEOF
- #define NO_PAM_SESSION 1
+ cat >>confdefs.h <<\_ACEOF
+ #define NO_PAM_SESSION
  _ACEOF
  
                            ;;
@@@ -20385,6 -19907,7 +19907,7 @@@ if test $ac_cv_header_bsd_auth_h = yes
  _ACEOF
  
        AUTH_OBJS="$AUTH_OBJS bsdauth.o"
+       BSDAUTH_USAGE='[-a auth_type] '
        AUTH_EXCL=BSD_AUTH; BAMAN=""
  else
    { { echo "$as_me:$LINENO: error: BSD authentication was specified but bsd_auth.h could not be found" >&5
@@@ -21423,6 -20946,7 +20946,7 @@@ echo "${ECHO_T}yes" >&6; 
  #define HAVE_HEIMDAL 1
  _ACEOF
  
+           # XXX - need to check whether -lcrypo is needed!
            SUDO_LIBS="${SUDO_LIBS} -lkrb5 -lcrypto -ldes -lcom_err -lasn1"
            { echo "$as_me:$LINENO: checking for main in -lroken" >&5
  echo $ECHO_N "checking for main in -lroken... $ECHO_C" >&6; }
@@@ -21560,7 -21084,8 +21084,8 @@@ rm -f core conftest.err conftest.$ac_ob
      LIBS="${LIBS} ${SUDO_LIBS}"
  
  
- for ac_func in krb5_verify_user krb5_init_secure_context
+ for ac_func in krb5_verify_user krb5_init_secure_context krb5_get_init_creds_opt_alloc
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
  { echo "$as_me:$LINENO: checking for $ac_func" >&5
  fi
  done
  
+     { echo "$as_me:$LINENO: checking whether krb5_get_init_creds_opt_free takes a two argument2" >&5
+ echo $ECHO_N "checking whether krb5_get_init_creds_opt_free takes a two argument2... $ECHO_C" >&6; }
+ if test "${sudo_cv_krb5_get_init_creds_opt_free_two_args+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+           cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <krb5.h>
+ int
+ main ()
+ {
+                   krb5_context context = NULL;
+                   krb5_get_init_creds_opt *opts = NULL;
+                   krb5_get_init_creds_opt_free(context, opts);
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   sudo_cv_krb5_get_init_creds_opt_free_two_args=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       sudo_cv_krb5_get_init_creds_opt_free_two_args=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ { echo "$as_me:$LINENO: result: $sudo_cv_krb5_get_init_creds_opt_free_two_args" >&5
+ echo "${ECHO_T}$sudo_cv_krb5_get_init_creds_opt_free_two_args" >&6; }
+     if test X"$sudo_cv_krb5_get_init_creds_opt_free_two_args" = X"yes"; then
+       cat >>confdefs.h <<\_ACEOF
+ #define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS 1
+ _ACEOF
+     fi
      LIBS="$_LIBS"
  fi
  
@@@ -22748,6 -22336,7 +22336,7 @@@ if test ${with_ldap-'no'} != "no"; the
  
        CPPFLAGS="${CPPFLAGS} -I${with_ldap}/include"
        with_ldap=yes
+       LDAP=""
      fi
      SUDO_OBJS="${SUDO_OBJS} ldap.o"
  
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-     { echo "$as_me:$LINENO: result: yes" >&5
- echo "${ECHO_T}yes" >&6; }
-     cat >>confdefs.h <<\_ACEOF
- #define HAVE_LBER_H 1
- _ACEOF
+     { echo "$as_me:$LINENO: result: yes" >&5
+ echo "${ECHO_T}yes" >&6; }
+     cat >>confdefs.h <<\_ACEOF
+ #define HAVE_LBER_H 1
+ _ACEOF
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ for ac_func in ldap_initialize ldap_start_tls_s ldap_sasl_interactive_bind_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $ac_func innocuous_$ac_func
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ #undef $ac_func
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char $ac_func ();
+ /* 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
+ #endif
+ int
+ main ()
+ {
+ return $ac_func ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   eval "$as_ac_var=yes"
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       eval "$as_ac_var=no"
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ fi
+ ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ if test `eval echo '${'$as_ac_var'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+ fi
+ done
+ for ac_header in sasl/sasl.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ else
+   # Is the header compilable?
+ { echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ $ac_includes_default
+ #include <$ac_header>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   ac_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_header_compiler=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6; }
+ # Is the header present?
+ { echo "$as_me:$LINENO: checking $ac_header presence" >&5
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <$ac_header>
+ _ACEOF
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        }; then
+   ac_header_preproc=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+   ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6; }
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+     ;;
+ esac
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   eval "$as_ac_Header=\$ac_header_preproc"
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ fi
+ if test `eval echo '${'$as_ac_Header'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+ _ACEOF
+ fi
+ done
+ for ac_header in ldap_ssl.h mps/ldap_ssl.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <ldap.h>
+ #include <$ac_header>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   eval "$as_ac_Header=yes"
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       eval "$as_ac_Header=no"
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ if test `eval echo '${'$as_ac_Header'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+ _ACEOF
+  break
+ fi
+ done
+     if test X"$check_gss_krb5_ccache_name" = X"yes"; then
+       { echo "$as_me:$LINENO: checking for gss_krb5_ccache_name in -lgssapi" >&5
+ echo $ECHO_N "checking for gss_krb5_ccache_name in -lgssapi... $ECHO_C" >&6; }
+ if test "${ac_cv_lib_gssapi_gss_krb5_ccache_name+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lgssapi  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char gss_krb5_ccache_name ();
+ int
+ main ()
+ {
+ return gss_krb5_ccache_name ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   ac_cv_lib_gssapi_gss_krb5_ccache_name=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_cv_lib_gssapi_gss_krb5_ccache_name=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_krb5_ccache_name" >&5
+ echo "${ECHO_T}$ac_cv_lib_gssapi_gss_krb5_ccache_name" >&6; }
+ if test $ac_cv_lib_gssapi_gss_krb5_ccache_name = yes; then
+   cat >>confdefs.h <<\_ACEOF
+ #define HAVE_GSS_KRB5_CCACHE_NAME 1
+ _ACEOF
+           LDAP_LIBS="${LDAP_LIBS} -lgssapi"
+ else
+   { echo "$as_me:$LINENO: checking for gss_krb5_ccache_name in -lgssapi_krb5" >&5
+ echo $ECHO_N "checking for gss_krb5_ccache_name in -lgssapi_krb5... $ECHO_C" >&6; }
+ if test "${ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lgssapi_krb5  $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char gss_krb5_ccache_name ();
+ int
+ main ()
+ {
+ return gss_krb5_ccache_name ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name" >&5
+ echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name" >&6; }
+ if test $ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name = yes; then
+   cat >>confdefs.h <<\_ACEOF
+ #define HAVE_GSS_KRB5_CCACHE_NAME 1
+ _ACEOF
+               LDAP_LIBS="${LDAP_LIBS} -lgssapi_krb5"
+ fi
+ fi
+       # gssapi headers may be separate or part of Kerberos V
+       found=no
+       O_CPPFLAGS="$CPPFLAGS"
+       for dir in "" "kerberosV" "krb5" "kerberos5" "kerberosv5"; do
+           test X"$dir" != X"" && CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
+           cat >conftest.$ac_ext <<_ACEOF
+ #include <gssapi/gssapi.h>
+ _ACEOF
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        }; then
+   found="gssapi/gssapi.h"; break
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+   cat >conftest.$ac_ext <<_ACEOF
+ #include <gssapi.h>
+ _ACEOF
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        }; then
+   found="gssapi.h"; break
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+ rm -f conftest.err conftest.$ac_ext
+ fi
+ rm -f conftest.err conftest.$ac_ext
+       done
+       if test X"$found" != X"no"; then
+ for ac_header in $found
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ else
+   # Is the header compilable?
+ { echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ $ac_includes_default
+ #include <$ac_header>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   ac_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+       ac_header_compiler=no
  fi
  
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6; }
  
- for ac_func in ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
- if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   cat >conftest.$ac_ext <<_ACEOF
+ # Is the header present?
+ { echo "$as_me:$LINENO: checking $ac_header presence" >&5
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $ac_func innocuous_$ac_func
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $ac_func (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- #undef $ac_func
- /* Override any GCC internal prototype to avoid an error.
-    Use char because int might match the return type of a GCC
-    builtin and then its argument prototype would still apply.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- char $ac_func ();
- /* 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
- #endif
- int
- main ()
- {
- return $ac_func ();
-   ;
-   return 0;
- }
+ #include <$ac_header>
  _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (ac_try="$ac_link"
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
  case "(($ac_try" in
    *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
    *) ac_try_echo=$ac_try;;
  esac
  eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-   (eval "$ac_link") 2>conftest.er1
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
    ac_status=$?
    grep -v '^ *+' conftest.er1 >conftest.err
    rm -f conftest.er1
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
+   (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
-        } && test -s conftest$ac_exeext &&
-        $as_test_x conftest$ac_exeext; then
-   eval "$as_ac_var=yes"
+        }; then
+   ac_header_preproc=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       eval "$as_ac_var=no"
+   ac_header_preproc=no
  fi
  
- rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-       conftest$ac_exeext conftest.$ac_ext
+ rm -f conftest.err conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6; }
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+     ;;
+ esac
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   eval "$as_ac_Header=\$ac_header_preproc"
  fi
- ac_res=`eval echo '${'$as_ac_var'}'`
+ ac_res=`eval echo '${'$as_ac_Header'}'`
               { echo "$as_me:$LINENO: result: $ac_res" >&5
  echo "${ECHO_T}$ac_res" >&6; }
- if test `eval echo '${'$as_ac_var'}'` = yes; then
+ fi
+ if test `eval echo '${'$as_ac_Header'}'` = yes; then
    cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
  _ACEOF
  
  fi
- done
  
+ done
  
+           if test X"$found" = X"gssapi/gssapi.h"; then
  
- for ac_header in ldap_ssl.h mps/ldap_ssl.h
+ for ac_header in gssapi/gssapi_krb5.h
  do
  as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   { echo "$as_me:$LINENO: checking for $ac_header" >&5
  echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
  if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
  else
-   cat >conftest.$ac_ext <<_ACEOF
+   # Is the header compilable?
+ { echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- #include <ldap.h>
+ $ac_includes_default
  #include <$ac_header>
  _ACEOF
  rm -f conftest.$ac_objext
@@@ -23091,34 -23237,114 +23237,114 @@@ eval "echo \"\$as_me:$LINENO: $ac_try_e
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
         } && test -s conftest.$ac_objext; then
-   eval "$as_ac_Header=yes"
+   ac_header_compiler=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
-       eval "$as_ac_Header=no"
+       ac_header_compiler=no
  fi
  
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6; }
+ # Is the header present?
+ { echo "$as_me:$LINENO: checking $ac_header presence" >&5
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <$ac_header>
+ _ACEOF
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+        }; then
+   ac_header_preproc=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+   ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6; }
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+     ;;
+ esac
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   eval "$as_ac_Header=\$ac_header_preproc"
  fi
  ac_res=`eval echo '${'$as_ac_Header'}'`
               { echo "$as_me:$LINENO: result: $ac_res" >&5
  echo "${ECHO_T}$ac_res" >&6; }
+ fi
  if test `eval echo '${'$as_ac_Header'}'` = yes; then
    cat >>confdefs.h <<_ACEOF
  #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
  _ACEOF
-  break
  fi
  
  done
  
+           fi
+       else
+           CPPFLAGS="$O_CPPFLAGS"
+           { echo "$as_me:$LINENO: WARNING: Unable to locate gssapi.h, you will have to edit the Makefile and add -I/path/to/gssapi/includes to CPPFLAGS" >&5
+ echo "$as_me: WARNING: Unable to locate gssapi.h, you will have to edit the Makefile and add -I/path/to/gssapi/includes to CPPFLAGS" >&2;}
+       fi
+     fi
  
      SUDO_LIBS="${SUDO_LIBS} ${LDAP_LIBS}"
      LIBS="$_LIBS"
      LDFLAGS="$_LDFLAGS"
-     # XXX - OpenLDAP has deprecated ldap_get_values()
-     CPPFLAGS="${CPPFLAGS} -DLDAP_DEPRECATED"
  fi
  
  if test -n "$blibpath"; then
@@@ -23267,7 -23493,7 +23493,7 @@@ _ACEO
      exec_prefix="$oexec_prefix"
  fi
  
- ac_config_files="$ac_config_files Makefile sudo.man visudo.man sudoers.man"
+ ac_config_files="$ac_config_files Makefile sudo.man visudo.man sudoers.man sudoers.ldap.man sudo_usage.h"
  
  cat >confcache <<\_ACEOF
  # This file is a shell script that caches the results of configure
@@@ -23665,7 -23891,7 +23891,7 @@@ exec 6>&
  # report actual input values of CONFIG_FILES etc. instead of their
  # values after options handling.
  ac_log="
- This file was extended by sudo $as_me 1.6.9, which was
+ This file was extended by sudo $as_me 1.7, which was
  generated by GNU Autoconf 2.61.  Invocation command line was
  
    CONFIG_FILES    = $CONFIG_FILES
@@@ -23714,7 -23940,7 +23940,7 @@@ Report bugs to <bug-autoconf@gnu.org>.
  _ACEOF
  cat >>$CONFIG_STATUS <<_ACEOF
  ac_cs_version="\\
- sudo config.status 1.6.9
+ sudo config.status 1.7
  configured by $0, generated by GNU Autoconf 2.61,
    with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
  
      "sudo.man") CONFIG_FILES="$CONFIG_FILES sudo.man" ;;
      "visudo.man") CONFIG_FILES="$CONFIG_FILES visudo.man" ;;
      "sudoers.man") CONFIG_FILES="$CONFIG_FILES sudoers.man" ;;
+     "sudoers.ldap.man") CONFIG_FILES="$CONFIG_FILES sudoers.ldap.man" ;;
+     "sudo_usage.h") CONFIG_FILES="$CONFIG_FILES sudo_usage.h" ;;
  
    *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
  echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@@ -23948,6 -24176,7 +24176,7 @@@ SELINUX!$SELINUX$ac_deli
  BAMAN!$BAMAN$ac_delim
  LCMAN!$LCMAN$ac_delim
  SEMAN!$SEMAN$ac_delim
+ devdir!$devdir$ac_delim
  mansectsu!$mansectsu$ac_delim
  mansectform!$mansectform$ac_delim
  mansrcdir!$mansrcdir$ac_delim
@@@ -23956,6 -24185,10 +24185,10 @@@ NOEXECDIR!$NOEXECDIR$ac_deli
  noexec_file!$noexec_file$ac_delim
  INSTALL_NOEXEC!$INSTALL_NOEXEC$ac_delim
  DONT_LEAK_PATH_INFO!$DONT_LEAK_PATH_INFO$ac_delim
+ BSDAUTH_USAGE!$BSDAUTH_USAGE$ac_delim
+ SELINUX_USAGE!$SELINUX_USAGE$ac_delim
+ LDAP!$LDAP$ac_delim
+ LOGINCAP_USAGE!$LOGINCAP_USAGE$ac_delim
  timedir!$timedir$ac_delim
  timeout!$timeout$ac_delim
  password_timeout!$password_timeout$ac_delim
@@@ -23980,11 -24213,6 +24213,6 @@@ env_editor!$env_editor$ac_deli
  passwd_tries!$passwd_tries$ac_delim
  tty_tickets!$tty_tickets$ac_delim
  insults!$insults$ac_delim
- root_sudo!$root_sudo$ac_delim
- path_info!$path_info$ac_delim
- EGREPPROG!$EGREPPROG$ac_delim
- CC!$CC$ac_delim
- ac_ct_CC!$ac_ct_CC$ac_delim
  _ACEOF
  
    if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
  ac_delim='%!_!# '
  for ac_last_try in false false false false false :; do
    cat >conf$$subs.sed <<_ACEOF
+ root_sudo!$root_sudo$ac_delim
+ path_info!$path_info$ac_delim
+ ldap_conf!$ldap_conf$ac_delim
+ ldap_secret!$ldap_secret$ac_delim
+ nsswitch_conf!$nsswitch_conf$ac_delim
+ EGREPPROG!$EGREPPROG$ac_delim
+ CC!$CC$ac_delim
+ ac_ct_CC!$ac_ct_CC$ac_delim
  EXEEXT!$EXEEXT$ac_delim
  OBJEXT!$OBJEXT$ac_delim
  CPP!$CPP$ac_delim
@@@ -24057,12 -24293,11 +24293,11 @@@ NROFFPROG!$NROFFPROG$ac_deli
  YACC!$YACC$ac_delim
  YFLAGS!$YFLAGS$ac_delim
  LIBOBJS!$LIBOBJS$ac_delim
- ALLOCA!$ALLOCA$ac_delim
  KRB5CONFIG!$KRB5CONFIG$ac_delim
  LTLIBOBJS!$LTLIBOBJS$ac_delim
  _ACEOF
  
-   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 34; then
+   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 41; then
      break
    elif $ac_last_try; then
      { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
  
  
  
  
  
  
diff --combined env.c
index d04186c2ee3b73035a61c62abed4c87681cac2c3,af6d53554d5b83afa1af1ed30cc7926420207356..029cd6d4ae1e449c7774d89981c16973b0a34a36
--- 1/env.c
--- 2/env.c
+++ b/env.c
@@@ -1,5 -1,6 +1,6 @@@
  /*
-  * Copyright (c) 2000-2007 Todd C. Miller <Todd.Miller@courtesan.com>
+  * Copyright (c) 2000-2005, 2007-2008
+  *    Todd C. Miller <Todd.Miller@courtesan.com>
   *
   * Permission to use, copy, modify, and distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
  #ifdef HAVE_UNISTD_H
  # include <unistd.h>
  #endif /* HAVE_UNISTD_H */
- #ifdef HAVE_ERR_H
- # include <err.h>
- #else
- # include "emul/err.h"
- #endif /* HAVE_ERR_H */
  #include <pwd.h>
  
  #include "sudo.h"
  
  #ifndef lint
- __unused static const char rcsid[] = "$Sudo: env.c,v 1.39.2.19 2008/06/21 19:04:07 millert Exp $";
+ __unused static const char rcsid[] = "$Sudo: env.c,v 1.94 2008/11/09 14:13:12 millert Exp $";
  #endif /* lint */
  
  /*
@@@ -93,7 -89,7 +89,7 @@@
  #define KEPT_MAX      0xff00
  
  #undef VNULL
- #define       VNULL   (VOID *)NULL
+ #define       VNULL   (void *)NULL
  
  struct environment {
      char **envp;              /* pointer to the new environment */
  /*
   * Prototypes
   */
- char **rebuild_env            __P((char **, int, int));
- static void insert_env                __P((char *, struct environment *, int));
- static char *format_env               __P((char *, ...));
+ void rebuild_env              __P((int, int));
+ void sudo_setenv              __P((const char *, const char *, int));
+ void sudo_unsetenv            __P((const char *));
+ static void _sudo_setenv      __P((const char *, const char *, int));
+ static void insert_env                __P((char *, int, int));
+ static void sync_env          __P((void));
+ extern char **environ;                /* global environment */
  
  /*
   * Copy of the sudo-managed environment.
@@@ -120,8 -121,6 +121,8 @@@ static struct environment env
  static const char *initial_badenv_table[] = {
      "IFS",
      "CDPATH",
 +    "SHELLOPTS",
 +    "PS4",
      "LOCALDOMAIN",
      "RES_OPTIONS",
      "HOSTALIASES",
  #ifdef _AIX
      "LDR_*",
      "LIBPATH",
+     "AUTHSTATE",
  #endif
  #ifdef __APPLE__
      "DYLD_*",
@@@ -215,86 -215,150 +217,150 @@@ static const char *initial_keepenv_tabl
  };
  
  /*
-  * Given a variable and value, allocate and format an environment string.
+  * Syncronize our private copy of the environment with what is
+  * in environ.
   */
- static char *
- #ifdef __STDC__
- format_env(char *var, ...)
- #else
- format_env(var, va_alist)
-     char *var;
-     va_dcl
- #endif
+ static void
+ sync_env()
+ {
+     size_t evlen;
+     char **ep;
+     for (ep = environ; *ep != NULL; ep++)
+       continue;
+     evlen = ep - environ;
+     if (evlen + 1 > env.env_size) {
+       efree(env.envp);
+       env.env_size = evlen + 1 + 128;
+       env.envp = emalloc2(env.env_size, sizeof(char *));
+     }
+     memcpy(env.envp, environ, (evlen + 1) * sizeof(char *));
+     env.env_len = evlen;
+     environ = env.envp;
+ }
+ /*
+  * Similar to setenv(3) but operates on sudo's private copy of the environment
+  * and it always overwrites.  The dupcheck param determines whether we need
+  * to verify that the variable is not already set.
+  */
+ static void
+ _sudo_setenv(var, val, dupcheck)
+     const char *var;
+     const char *val;
+     int dupcheck;
  {
      char *estring;
-     char *val;
      size_t esize;
-     va_list ap;
  
- #ifdef __STDC__
-     va_start(ap, var);
- #else
-     va_start(ap);
- #endif
-     esize = strlen(var) + 2;
-     while ((val = va_arg(ap, char *)) != NULL)
-       esize += strlen(val);
-     va_end(ap);
-     estring = (char *) emalloc(esize);
+     esize = strlen(var) + 1 + strlen(val) + 1;
+     estring = emalloc(esize);
  
-     /* Store variable name and the '=' separator.  */
+     /* Build environment string and insert it. */
      if (strlcpy(estring, var, esize) >= esize ||
-       strlcat(estring, "=", esize) >= esize) {
+       strlcat(estring, "=", esize) >= esize ||
+       strlcat(estring, val, esize) >= esize) {
  
-       errx(1, "internal error, format_env() overflow");
+       errorx(1, "internal error, sudo_setenv() overflow");
      }
+     insert_env(estring, dupcheck, FALSE);
+ }
  
-     /* Now store the variable's value (if any) */
- #ifdef __STDC__
-     va_start(ap, var);
- #else
-     va_start(ap);
- #endif
-     while ((val = va_arg(ap, char *)) != NULL) {
-       if (strlcat(estring, val, esize) >= esize)
-           errx(1, "internal error, format_env() overflow");
+ #ifdef HAVE_LDAP
+ /*
+  * External version of sudo_setenv() that keeps things in sync with
+  * the environ pointer.
+  */
+ void
+ sudo_setenv(var, val, dupcheck)
+     const char *var;
+     const char *val;
+     int dupcheck;
+ {
+     char *estring;
+     size_t esize;
+     /* Make sure we are operating on the current environment. */
+     if (env.envp != environ)
+       sync_env();
+     esize = strlen(var) + 1 + strlen(val) + 1;
+     estring = emalloc(esize);
+     /* Build environment string and insert it. */
+     if (strlcpy(estring, var, esize) >= esize ||
+       strlcat(estring, "=", esize) >= esize ||
+       strlcat(estring, val, esize) >= esize) {
+       errorx(1, "internal error, sudo_setenv() overflow");
      }
-     va_end(ap);
+     insert_env(estring, dupcheck, TRUE);
+ }
+ #endif /* HAVE_LDAP */
+ #if defined(HAVE_LDAP) || defined(HAVE_AIXAUTH)
+ /*
+  * Similar to unsetenv(3) but operates on sudo's private copy of the
+  * environment.
+  */
+ void
+ sudo_unsetenv(var)
+     const char *var;
+ {
+     char **nep;
+     size_t varlen;
  
-     return(estring);
+     /* Make sure we are operating on the current environment. */
+     if (env.envp != environ)
+       sync_env();
+     varlen = strlen(var);
+     for (nep = env.envp; *nep; nep++) {
+       if (strncmp(var, *nep, varlen) == 0 && (*nep)[varlen] == '=') {
+           /* Found it; move everything over by one and update len. */
+           memmove(nep, nep + 1,
+               (env.env_len - (nep - env.envp)) * sizeof(char *));
+           env.env_len--;
+           return;
+       }
+     }
  }
+ #endif /* HAVE_LDAP || HAVE_AIXAUTH */
  
  /*
-  * Insert str into e->envp, assumes str has an '=' in it.
+  * Insert str into env.envp, assumes str has an '=' in it.
   */
  static void
- insert_env(str, e, dupcheck)
+ insert_env(str, dupcheck, dosync)
      char *str;
-     struct environment *e;
      int dupcheck;
+     int dosync;
  {
      char **nep;
      size_t varlen;
  
      /* Make sure there is room for the new entry plus a NULL. */
-     if (e->env_len + 2 > e->env_size) {
-       e->env_size += 128;
-       e->envp = erealloc3(e->envp, e->env_size, sizeof(char *));
+     if (env.env_len + 2 > env.env_size) {
+       env.env_size += 128;
+       env.envp = erealloc3(env.envp, env.env_size, sizeof(char *));
+       if (dosync)
+           environ = env.envp;
      }
  
      if (dupcheck) {
            varlen = (strchr(str, '=') - str) + 1;
  
-           for (nep = e->envp; *nep; nep++) {
+           for (nep = env.envp; *nep; nep++) {
                if (strncmp(str, *nep, varlen) == 0) {
-                   *nep = str;
+                   if (dupcheck != -1)
+                       *nep = str;
                    return;
                }
            }
      } else
-       nep = e->envp + e->env_len;
+       nep = env.envp + env.env_len;
  
-     e->env_len++;
+     env.env_len++;
      *nep++ = str;
      *nep = NULL;
  }
@@@ -393,13 -457,13 +459,13 @@@ matches_env_keep(var
   * variables from the old one or start with a clean slate.
   * Also adds sudo-specific variables (SUDO_*).
   */
- char **
- rebuild_env(envp, sudo_mode, noexec)
-     char **envp;
+ void
+ rebuild_env(sudo_mode, noexec)
      int sudo_mode;
      int noexec;
  {
-     char **ep, *cp, *ps1;
+     char **old_envp, **ep, *cp, *ps1;
+     char idbuf[MAX_UID_T_LEN];
      unsigned int didvar;
  
      /*
       */
      ps1 = NULL;
      didvar = 0;
-     memset(&env, 0, sizeof(env));
+     env.env_len = 0;
+     env.env_size = 128;
+     old_envp = env.envp;
+     env.envp = emalloc2(env.env_size, sizeof(char *));
      if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
        /* Pull in vars we want to keep from the old environment. */
-       for (ep = envp; *ep; ep++) {
+       for (ep = environ; *ep; ep++) {
            int keepit;
  
            /* Skip variables with values beginning with () (bash functions) */
            if (keepit == -1)
                keepit = matches_env_keep(*ep);
  
 +          if (!strncmp (*ep, "DISPLAY=",8)
 +              || !strncmp (*ep, "XAUTHORITY=", 11)
 +              || !strncmp (*ep, "XAUTHORIZATION=", 15)
 +              || !strncmp (*ep, "XAPPLRESDIR=", 12)
 +              || !strncmp (*ep, "XFILESEARCHPATH=", 16)
 +              || !strncmp (*ep, "XUSERFILESEARCHPATH=", 20)
 +              || !strncmp (*ep, "LANG=", 5)
 +              || !strncmp (*ep, "LANGUAGE=", 9)
 +              || !strncmp (*ep, "LC_", 3))
 +            keepit = 1;
 +
            /* For SUDO_PS1 -> PS1 conversion. */
            if (strncmp(*ep, "SUDO_PS1=", 8) == 0)
                ps1 = *ep + 5;
                            SET(didvar, DID_USERNAME);
                        break;
                }
-               insert_env(*ep, &env, 0);
+               insert_env(*ep, FALSE, FALSE);
            }
        }
        didvar |= didvar << 8;          /* convert DID_* to KEPT_* */
         * on sudoers options).
         */
        if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
-           insert_env(format_env("HOME", runas_pw->pw_dir, VNULL), &env,
-               ISSET(didvar, DID_HOME));
-           insert_env(format_env("SHELL", runas_pw->pw_shell, VNULL), &env,
-               ISSET(didvar, DID_SHELL));
-           insert_env(format_env("LOGNAME", runas_pw->pw_name, VNULL), &env,
+           _sudo_setenv("HOME", runas_pw->pw_dir, ISSET(didvar, DID_HOME));
+           _sudo_setenv("SHELL", runas_pw->pw_shell, ISSET(didvar, DID_SHELL));
+           _sudo_setenv("LOGNAME", runas_pw->pw_name,
                ISSET(didvar, DID_LOGNAME));
-           insert_env(format_env("USER", runas_pw->pw_name, VNULL), &env,
-               ISSET(didvar, DID_USER));
-           insert_env(format_env("USERNAME", runas_pw->pw_name, VNULL), &env,
+           _sudo_setenv("USER", runas_pw->pw_name, ISSET(didvar, DID_USER));
+           _sudo_setenv("USERNAME", runas_pw->pw_name,
                ISSET(didvar, DID_USERNAME));
        } else {
            if (!ISSET(didvar, DID_HOME))
-               insert_env(format_env("HOME", user_dir, VNULL), &env, 0);
+               _sudo_setenv("HOME", user_dir, FALSE);
            if (!ISSET(didvar, DID_SHELL))
-               insert_env(format_env("SHELL", sudo_user.pw->pw_shell, VNULL),
-                   &env, 0);
+               _sudo_setenv("SHELL", sudo_user.pw->pw_shell, FALSE);
            if (!ISSET(didvar, DID_LOGNAME))
-               insert_env(format_env("LOGNAME", user_name, VNULL), &env, 0);
+               _sudo_setenv("LOGNAME", user_name, FALSE);
            if (!ISSET(didvar, DID_USER))
-               insert_env(format_env("USER", user_name, VNULL), &env, 0);
+               _sudo_setenv("USER", user_name, FALSE);
            if (!ISSET(didvar, DID_USERNAME))
-               insert_env(format_env("USERNAME", user_name, VNULL), &env, 0);
+               _sudo_setenv("USERNAME", user_name, FALSE);
        }
      } else {
        /*
-        * Copy envp entries as long as they don't match env_delete or
+        * Copy environ entries as long as they don't match env_delete or
         * env_check.
         */
-       for (ep = envp; *ep; ep++) {
+       for (ep = environ; *ep; ep++) {
            int okvar;
  
            /* Skip variables with values beginning with () (bash functions) */
                    SET(didvar, DID_PATH);
                else if (strncmp(*ep, "TERM=", 5) == 0)
                    SET(didvar, DID_TERM);
-               insert_env(*ep, &env, 0);
+               insert_env(*ep, FALSE, FALSE);
            }
        }
      }
- #ifdef SECURE_PATH
-     /* Replace the PATH envariable with a secure one. */
-     if (!user_is_exempt()) {
-       insert_env(format_env("PATH", SECURE_PATH, VNULL), &env, 1);
+     /* Replace the PATH envariable with a secure one? */
+     if (def_secure_path && !user_is_exempt()) {
+       _sudo_setenv("PATH", def_secure_path, TRUE);
        SET(didvar, DID_PATH);
      }
- #endif
  
      /* Set $USER, $LOGNAME and $USERNAME to target if "set_logname" is true. */
      /* XXX - not needed for MODE_LOGIN_SHELL */
      if (def_set_logname && runas_pw->pw_name) {
        if (!ISSET(didvar, KEPT_LOGNAME))
-           insert_env(format_env("LOGNAME", runas_pw->pw_name, VNULL), &env, 1);
+           _sudo_setenv("LOGNAME", runas_pw->pw_name, TRUE);
        if (!ISSET(didvar, KEPT_USER))
-           insert_env(format_env("USER", runas_pw->pw_name, VNULL), &env, 1);
+           _sudo_setenv("USER", runas_pw->pw_name, TRUE);
        if (!ISSET(didvar, KEPT_USERNAME))
-           insert_env(format_env("USERNAME", runas_pw->pw_name, VNULL), &env, 1);
+           _sudo_setenv("USERNAME", runas_pw->pw_name, TRUE);
      }
  
      /* Set $HOME for `sudo -H'.  Only valid at PERM_FULL_RUNAS. */
        if (ISSET(sudo_mode, MODE_RESET_HOME) ||
            (ISSET(sudo_mode, MODE_RUN) && (def_always_set_home ||
            (ISSET(sudo_mode, MODE_SHELL) && def_set_home))))
-           insert_env(format_env("HOME", runas_pw->pw_dir, VNULL), &env, 1);
+           _sudo_setenv("HOME", runas_pw->pw_dir, TRUE);
      }
  
      /* Provide default values for $TERM and $PATH if they are not set. */
      if (!ISSET(didvar, DID_TERM))
-       insert_env("TERM=unknown", &env, 0);
+       insert_env("TERM=unknown", FALSE, FALSE);
      if (!ISSET(didvar, DID_PATH))
-       insert_env(format_env("PATH", _PATH_DEFPATH, VNULL), &env, 0);
+       _sudo_setenv("PATH", _PATH_DEFPATH, FALSE);
  
      /*
       * Preload a noexec file?  For a list of LD_PRELOAD-alikes, see
       */
      if (noexec && def_noexec_file != NULL) {
  #if defined(__darwin__) || defined(__APPLE__)
-       insert_env(format_env("DYLD_INSERT_LIBRARIES", def_noexec_file, VNULL),
-           &env, 1);
-       insert_env(format_env("DYLD_FORCE_FLAT_NAMESPACE", VNULL), &env, 1);
+       _sudo_setenv("DYLD_INSERT_LIBRARIES", def_noexec_file, TRUE);
+       _sudo_setenv("DYLD_FORCE_FLAT_NAMESPACE", "", TRUE);
  #else
  # if defined(__osf__) || defined(__sgi)
-       insert_env(format_env("_RLD_LIST", def_noexec_file, ":DEFAULT", VNULL),
-           &env, 1);
+       easprintf(&cp, "%s:DEFAULT", def_noexec_file);
+       _sudo_setenv("_RLD_LIST", cp, TRUE);
+       efree(cp);
  # else
  #  ifdef _AIX
-       insert_env(format_env("LDR_PRELOAD", def_noexec_file, VNULL), &env, 1);
+       _sudo_setenv("LDR_PRELOAD", def_noexec_file, TRUE);
  #  else
-       insert_env(format_env("LD_PRELOAD", def_noexec_file, VNULL), &env, 1);
+       _sudo_setenv("LD_PRELOAD", def_noexec_file, TRUE);
  #  endif /* _AIX */
  # endif /* __osf__ || __sgi */
  #endif /* __darwin__ || __APPLE__ */
      }
  
      /* Set PS1 if SUDO_PS1 is set. */
-     if (ps1)
-       insert_env(ps1, &env, 1);
+     if (ps1 != NULL)
+       insert_env(ps1, TRUE, FALSE);
  
      /* Add the SUDO_COMMAND envariable (cmnd + args). */
-     if (user_args)
-       insert_env(format_env("SUDO_COMMAND", user_cmnd, " ", user_args, VNULL),
-           &env, 1);
-     else
-       insert_env(format_env("SUDO_COMMAND", user_cmnd, VNULL), &env, 1);
+     if (user_args) {
+       easprintf(&cp, "%s %s", user_cmnd, user_args);
+       _sudo_setenv("SUDO_COMMAND", cp, TRUE);
+       efree(cp);
+     } else
+       _sudo_setenv("SUDO_COMMAND", user_cmnd, TRUE);
  
      /* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
-     insert_env(format_env("SUDO_USER", user_name, VNULL), &env, 1);
-     easprintf(&cp, "SUDO_UID=%lu", (unsigned long) user_uid);
-     insert_env(cp, &env, 1);
-     easprintf(&cp, "SUDO_GID=%lu", (unsigned long) user_gid);
-     insert_env(cp, &env, 1);
-     return(env.envp);
+     _sudo_setenv("SUDO_USER", user_name, TRUE);
+     snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_uid);
+     _sudo_setenv("SUDO_UID", idbuf, TRUE);
+     snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_gid);
+     _sudo_setenv("SUDO_GID", idbuf, TRUE);
+     /* Install new environment. */
+     environ = env.envp;
+     efree(old_envp);
  }
  
- char **
- insert_env_vars(envp, env_vars)
-     char **envp;
+ void
+ insert_env_vars(env_vars)
      struct list_member *env_vars;
  {
      struct list_member *cur;
  
      if (env_vars == NULL)
-       return (envp);
+       return;
  
-     /*
-      * Make sure we still own the environment and steal it back if not.
-      */
-     if (env.envp != envp) {
-       size_t evlen;
-       char **ep;
-       for (ep = envp; *ep != NULL; ep++)
-           continue;
-       evlen = ep - envp;
-       if (evlen + 1 > env.env_size) {
-           efree(env.envp);
-           env.env_size = evlen + 1 + 128;
-           env.envp = emalloc2(env.env_size, sizeof(char *));
-       }
-       memcpy(env.envp, envp, (evlen + 1) * sizeof(char *));
-       env.env_len = evlen;
-     }
+     /* Make sure we are operating on the current environment. */
+     if (env.envp != environ)
+       sync_env();
  
      /* Add user-specified environment variables. */
      for (cur = env_vars; cur != NULL; cur = cur->next)
-       insert_env(cur->value, &env, 1);
-     return(env.envp);
+       insert_env(cur->value, TRUE, TRUE);
  }
  
  /*
@@@ -671,12 -705,10 +718,10 @@@ validate_env_vars(env_vars
      int okvar;
  
      for (var = env_vars; var != NULL; var = var->next) {
- #ifdef SECURE_PATH
-       if (!user_is_exempt() && strncmp(var->value, "PATH=", 5) == 0) {
+       if (def_secure_path && !user_is_exempt() &&
+           strncmp(var->value, "PATH=", 5) == 0) {
            okvar = FALSE;
-       } else
- #endif
-       if (def_env_reset) {
+       } else if (def_env_reset) {
            okvar = matches_env_check(var->value);
            if (okvar == -1)
                okvar = matches_env_keep(var->value);
      }
  }
  
+ /*
+  * Read in /etc/environment ala AIX and Linux.
+  * Lines are in the form of NAME=VALUE
+  * Invalid lines, blank lines, or lines consisting solely of a comment
+  * character are skipped.
+  */
+ void
+ read_env_file(path, replace)
+     const char *path;
+     int replace;
+ {
+     FILE *fp;
+     char *cp;
+     if ((fp = fopen(path, "r")) == NULL)
+       return;
+     /* Make sure we are operating on the current environment. */
+     if (env.envp != environ)
+       sync_env();
+     while ((cp = sudo_parseln(fp)) != NULL) {
+       /* Skip blank or comment lines */
+       if (*cp == '\0')
+           continue;
+       /* Must be of the form name=value */
+       if (strchr(cp, '=') == NULL)
+           continue;
+       insert_env(estrdup(cp), replace ? TRUE : -1, TRUE);
+     }
+     fclose(fp);
+ }
  void
  init_envtables()
  {
diff --combined sample.sudoers
index 29d88c97775b4f933388cc5e689a93fa9f67782a,220df7fa8da9f78b35b53c182703904df5cfe615..cc35506d3673f453418c15ae9b65ad18015b6686
@@@ -5,6 -5,17 +5,17 @@@
  #
  # See the sudoers man page for the details on how to write a sudoers file.
  #
+ # $Sudo: sample.sudoers,v 1.29 2008/10/03 19:55:57 millert Exp $
+ ##
+ # Override built-in defaults
+ ##
+ Defaults              syslog=auth
+ Defaults>root         !set_logname
+ Defaults:FULLTIMERS   !lecture
+ Defaults:millert      !authenticate
+ Defaults@SERVERS      log_year, logfile=/var/log/sudo.log
+ Defaults!PAGERS               noexec
  
  ##
  # User alias specification
@@@ -35,8 -46,8 +46,8 @@@ Host_Alias    CDROM = orion, perseus, herc
  # Cmnd alias specification
  ##
  Cmnd_Alias    DUMPS = /usr/sbin/dump, /usr/sbin/rdump, /usr/sbin/restore, \
 -                      /usr/sbin/rrestore, /usr/bin/mt
 -Cmnd_Alias    KILL = /usr/bin/kill
 +                      /usr/sbin/rrestore, /bin/mt
 +Cmnd_Alias    KILL = /bin/kill
  Cmnd_Alias    PRINTING = /usr/sbin/lpc, /usr/bin/lprm
  Cmnd_Alias    SHUTDOWN = /usr/sbin/shutdown
  Cmnd_Alias    HALT = /usr/sbin/halt
@@@ -47,15 -58,7 +58,7 @@@ Cmnd_Alias   SHELLS = /sbin/sh, /usr/bin/
  Cmnd_Alias    SU = /usr/bin/su
  Cmnd_Alias    VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, \
                       /usr/bin/chfn
- ##
- # Override built-in defaults
- ##
- Defaults               syslog=auth
- Defaults>root          !set_logname
- Defaults:FULLTIMERS    !lecture
- Defaults:millert       !authenticate
- Defaults@SERVERS       log_year, logfile=/var/log/sudo.log
+ Cmnd_Alias    PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
  
  ##
  # User specification
@@@ -82,10 -85,10 +85,10 @@@ operator   ALL = DUMPS, KILL, SHUTDOWN, H
                sudoedit /etc/printcap, /usr/oper/bin/
  
  # joe may su only to operator
 -joe           ALL = /usr/bin/su operator
 +joe           ALL = /bin/su operator
  
  # pete may change passwords for anyone but root on the hp snakes
- pete          HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
+ pete          HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
  
  # bob may run anything on the sparc and sgi machines as any user
  # listed in the Runas_Alias "OP" (ie: root and operator)
@@@ -96,13 -99,13 +99,13 @@@ jim                +biglab = AL
  
  # users in the secretaries netgroup need to help manage the printers
  # as well as add and remove users
 -+secretaries  ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
 ++secretaries  ALL = PRINTING, /usr/sbin/adduser, /usr/bin/rmuser
  
  # fred can run commands as oracle or sybase without a password
  fred          ALL = (DB) NOPASSWD: ALL
  
  # on the alphas, john may su to anyone but root and flags are not allowed
 -john          ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
 +john          ALPHA = /bin/su [!-]*, !/bin/su *root*
  
  # jen can run anything on all machines except the ones
  # in the "SERVERS" Host_Alias
diff --combined sudo.c
index e630059d269414ef6536e3408c277c910129918b,7191ee14a68ecfb5f57d02bf3d72557cd4a06856..a842fc3951a0244d8c7b83d3ba5a26eca65b6bc6
--- 1/sudo.c
--- 2/sudo.c
+++ b/sudo.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Copyright (c) 1993-1996,1998-2007 Todd C. Miller <Todd.Miller@courtesan.com>
+  * Copyright (c) 1993-1996, 1998-2008 Todd C. Miller <Todd.Miller@courtesan.com>
   *
   * Permission to use, copy, modify, and distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
  #ifdef HAVE_UNISTD_H
  # include <unistd.h>
  #endif /* HAVE_UNISTD_H */
- #ifdef HAVE_ERR_H
- # include <err.h>
- #else
- # include "emul/err.h"
- #endif /* HAVE_ERR_H */
  #include <pwd.h>
  #include <errno.h>
  #include <fcntl.h>
  #endif
  
  #include "sudo.h"
+ #include "sudo_usage.h"
+ #include "lbuf.h"
  #include "interfaces.h"
  #include "version.h"
  
  #ifndef lint
- __unused __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.369.2.41 2008/06/21 19:04:07 millert Exp $";
+ __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.500 2008/11/18 15:57:09 millert Exp $";
  #endif /* lint */
  
  /*
   * Prototypes
   */
- static int init_vars                  __P((int, char **));
+ static void init_vars                 __P((int, char **));
+ static int set_cmnd                   __P((int));
  static int parse_args                 __P((int, char **));
- static void check_sudoers             __P((void));
  static void initial_setup             __P((void));
  static void set_loginclass            __P((struct passwd *));
  static void set_project                       __P((struct passwd *));
+ static void set_runasgr                       __P((char *));
+ static void set_runaspw                       __P((char *));
+ static void show_version              __P((void));
  static void usage                     __P((int))
                                            __attribute__((__noreturn__));
  static void usage_excl                        __P((int))
                                            __attribute__((__noreturn__));
- static void usage_excl                        __P((int));
  static struct passwd *get_authpw      __P((void));
  extern int sudo_edit                  __P((int, char **, char **));
- extern void list_matches              __P((void));
- extern char **rebuild_env             __P((char **, int, int));
- extern void validate_env_vars         __P((struct list_member *));
- extern char **insert_env_vars         __P((char **, struct list_member *));
- extern struct passwd *sudo_getpwnam   __P((const char *));
- extern struct passwd *sudo_getpwuid   __P((uid_t));
- extern struct passwd *sudo_pwdup      __P((const struct passwd *));
+ extern void rebuild_env                       __P((int, int));
+ void validate_env_vars                        __P((struct list_member *));
+ void insert_env_vars                  __P((struct list_member *));
  
  /*
   * Globals
  int Argc, NewArgc;
  char **Argv, **NewArgv;
  char *prev_user;
+ static int user_closefrom = -1;
  struct sudo_user sudo_user;
- struct passwd *auth_pw;
- FILE *sudoers_fp;
+ struct passwd *auth_pw, *list_pw;
  struct interface *interfaces;
  int num_interfaces;
  int tgetpass_flags;
+ int long_list;
  uid_t timestamp_uid;
  extern int errorlineno;
+ extern int parse_error;
+ extern char *errorfile;
  #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
  static struct rlimit corelimit;
  #endif /* RLIMIT_CORE && !SUDO_DEVEL */
@@@ -156,7 -154,13 +154,13 @@@ login_cap_t *lc
  char *login_style;
  #endif /* HAVE_BSD_AUTH_H */
  sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
+ static char *runas_user;
+ static char *runas_group;
+ static struct sudo_nss_list *snl;
  
+ /* For getopt(3) */
+ extern char *optarg;
+ extern int optind;
  
  int
  main(argc, argv, envp)
      char **argv;
      char **envp;
  {
-     int validated;
-     int fd;
-     int cmnd_status;
-     int sudo_mode;
-     int pwflag;
+     int sources = 0, validated;
+     int fd, cmnd_status, sudo_mode, pwflag, rc = 0;
      sigaction_t sa;
-     extern int printmatches;
-     extern char **environ;
+     struct sudo_nss *nss;
+ #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+     extern char *malloc_options;
+     malloc_options = "AFGJPR";
+ #endif
  
  #ifdef HAVE_SETLOCALE
      setlocale(LC_ALL, "");
  #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
  
      if (geteuid() != 0)
-       errx(1, "must be setuid root");
+       errorx(1, "must be setuid root");
  
      /*
       * Signal setup:
       *  us at some point and avoid the logging.
       *  Install handler to wait for children when they exit.
       */
+     zero_bytes(&sa, sizeof(sa));
      sigemptyset(&sa.sa_mask);
      sa.sa_flags = SA_RESTART;
      sa.sa_handler = SIG_IGN;
      (void) sigaction(SIGTSTP, &sa, &saved_sa_tstp);
  
      /*
-      * Turn off core dumps and close open files.
+      * Turn off core dumps and make sure fds 0-2 are open.
       */
      initial_setup();
-     setpwent();
+     sudo_setpwent();
+     sudo_setgrent();
  
      /* Parse our arguments. */
      sudo_mode = parse_args(Argc, Argv);
      else
        switch (sudo_mode) {
            case MODE_VERSION:
-               (void) printf("Sudo version %s\n", version);
-               if (getuid() == 0) {
-                   putchar('\n');
-                   (void) printf("Sudoers path: %s\n", _PATH_SUDOERS);
-                   dump_auth_methods();
-                   dump_defaults();
-                   dump_interfaces();
-               }
-               exit(0);
+               show_version();
                break;
            case MODE_HELP:
                usage(0);
            case MODE_LIST:
                user_cmnd = "list";
                pwflag = I_LISTPW;
-               printmatches = 1;
+               break;
+           case MODE_CHECK:
+               pwflag = I_LISTPW;
                break;
        }
  
      if (user_cmnd == NULL && NewArgc == 0)
        usage(1);
  
-     cmnd_status = init_vars(sudo_mode, environ);
+     init_vars(sudo_mode, envp);               /* XXX - move this later? */
  
- #ifdef HAVE_LDAP
-     validated = sudo_ldap_check(pwflag);
+     /* Parse nsswitch.conf for sudoers order. */
+     snl = sudo_read_nss();
+     /* Open and parse sudoers, set global defaults */
+     tq_foreach_fwd(snl, nss) {
+       if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
+           sources++;
+           nss->setdefs(nss);
+       }
+     }
+     if (sources == 0)
+       log_error(0, "no valid sudoers sources found, quitting");
+     /* XXX - collect post-sudoers parse settings into a function */
+     /*
+      * Set runas passwd/group entries based on command line or sudoers.
+      * Note that if runas_group was specified without runas_user we
+      * defer setting runas_pw so the match routines know to ignore it.
+      */
+     if (runas_group != NULL) {
+       set_runasgr(runas_group);
+       if (runas_user != NULL)
+           set_runaspw(runas_user);
+     } else
+       set_runaspw(runas_user ? runas_user : def_runas_default);
+     if (!update_defaults(SETDEF_RUNAS))
+       log_error(NO_STDERR|NO_EXIT, "problem with defaults entries");
  
-     /* Skip reading /etc/sudoers if LDAP told us to */
-     if (!def_ignore_local_sudoers) {
-       int v;
+     /* Set login class if applicable. */
+     set_loginclass(sudo_user.pw);
  
-       check_sudoers();        /* check mode/owner on _PATH_SUDOERS */
+     /* Update initial shell now that runas is set. */
+     if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
+       NewArgv[0] = runas_pw->pw_shell;
  
-       /* Local sudoers file overrides LDAP if we have a match. */
-       v = sudoers_lookup(pwflag);
-       if (validated == VALIDATE_ERROR || ISSET(v, VALIDATE_OK))
-           validated = v;
+     /* This goes after sudoers is parsed since it may have timestamp options. */
+     if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
+       remove_timestamp((sudo_mode == MODE_KILL));
+       cleanup(0);
+       exit(0);
      }
- #else
-     check_sudoers();  /* check mode/owner on _PATH_SUDOERS */
  
-     /* Validate the user but don't search for pseudo-commands. */
-     validated = sudoers_lookup(pwflag);
+     /* Is root even allowed to run sudo? */
+     if (user_uid == 0 && !def_root_sudo) {
+       (void) fprintf(stderr,
+           "Sorry, %s has been configured to not allow root to run it.\n",
+           getprogname());
+       exit(1);
+     }
+     /* Check for -C overriding def_closefrom. */
+     if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
+       if (!def_closefrom_override)
+           errorx(1, "you are not permitted to use the -C option");
+       else
+           def_closefrom = user_closefrom;
+     }
+     cmnd_status = set_cmnd(sudo_mode);
+ #ifdef HAVE_SETLOCALE
+     if (!setlocale(LC_ALL, def_sudoers_locale)) {
+       warningx("unable to set locale to \"%s\", using \"C\"",
+           def_sudoers_locale);
+       setlocale(LC_ALL, "C");
+     }
  #endif
+     validated = FLAG_NO_USER | FLAG_NO_HOST;
+     tq_foreach_fwd(snl, nss) {
+       validated = nss->lookup(nss, validated, pwflag);
+       /* Handle [NOTFOUND=return] */
+       if (!ISSET(validated, VALIDATE_OK) && nss->ret_notfound)
+           break;
+     }
      if (safe_cmnd == NULL)
        safe_cmnd = estrdup(user_cmnd);
  
+ #ifdef HAVE_SETLOCALE
+     setlocale(LC_ALL, "");
+ #endif
+     /* If only a group was specified, set runas_pw based on invoking user. */
+     if (runas_pw == NULL)
+       set_runaspw(user_name);
      /*
       * Look up the timestamp dir owner if one is specified.
       */
        struct passwd *pw;
  
        if (*def_timestampowner == '#')
-           pw = getpwuid(atoi(def_timestampowner + 1));
+           pw = sudo_getpwuid(atoi(def_timestampowner + 1));
        else
-           pw = getpwnam(def_timestampowner);
+           pw = sudo_getpwnam(def_timestampowner);
        if (!pw)
            log_error(0, "timestamp owner (%s): No such user",
                def_timestampowner);
        timestamp_uid = pw->pw_uid;
      }
  
-     /* 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));
-       exit(0);
-     }
-     if (ISSET(validated, VALIDATE_ERROR))
-       log_error(0, "parse error in %s near line %d", _PATH_SUDOERS,
-           errorlineno);
-     /* Is root even allowed to run sudo? */
-     if (user_uid == 0 && !def_root_sudo) {
-       (void) fprintf(stderr,
-           "Sorry, %s has been configured to not allow root to run it.\n",
-           getprogname());
-       exit(1);
-     }
      /* If given the -P option, set the "preserve_groups" flag. */
      if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
        def_preserve_groups = TRUE;
            (void) close(fd);
      }
  
-     /* User may have overriden environment resetting via the -E flag. */
-     if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && ISSET(validated, FLAG_SETENV))
+     /* Use askpass value from sudoers unless user specified their own. */
+     if (def_askpass && !user_askpass)
+       user_askpass = def_askpass;
+     /* User may have overridden environment resetting via the -E flag. */
+     if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)
        def_env_reset = FALSE;
  
      /* Build a new environment that avoids any nasty bits. */
-     environ = rebuild_env(environ, sudo_mode, ISSET(validated, FLAG_NOEXEC));
+     rebuild_env(sudo_mode, def_noexec);
  
      /* Fill in passwd struct based on user we are authenticating as.  */
      auth_pw = get_authpw();
  
      /* Require a password if sudoers says so.  */
-     if (!ISSET(validated, FLAG_NOPASS))
-       check_user(validated);
+     if (def_authenticate)
+       check_user(validated, !ISSET(sudo_mode, MODE_NONINTERACTIVE));
  
      /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
-     if (user_uid == 0 && prev_user != NULL && strcmp(prev_user, "root") != 0) {
+     /* XXX - causes confusion when root is not listed in sudoers */
+     if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) {
+       if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
            struct passwd *pw;
  
-           if ((pw = sudo_getpwnam(prev_user)) != NULL) {
-                   efree(sudo_user.pw);
+           if ((pw = sudo_getpwnam(prev_user)) != NULL)
                    sudo_user.pw = pw;
-           }
+       }
      }
  
      if (ISSET(validated, VALIDATE_OK)) {
        /* Finally tell the user if the command did not exist. */
-       if (cmnd_status == NOT_FOUND_DOT) {
-           warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd);
-           exit(1);
-       } else if (cmnd_status == NOT_FOUND) {
-           warnx("%s: command not found", user_cmnd);
-           exit(1);
-       }
+       if (cmnd_status == NOT_FOUND_DOT)
+           errorx(1, "ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd);
+       else if (cmnd_status == NOT_FOUND)
+           errorx(1, "%s: command not found", user_cmnd);
  
        /* If user specified env vars make sure sudoers allows it. */
-       if (ISSET(sudo_mode, MODE_RUN) && !ISSET(validated, FLAG_SETENV)) {
+       if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
            if (ISSET(sudo_mode, MODE_PRESERVE_ENV))
                log_error(NO_MAIL,
                    "sorry, you are not allowed to preserve the environment");
                validate_env_vars(sudo_user.env_vars);
        }
  
-       log_auth(validated, 1);
-       if (sudo_mode == MODE_VALIDATE)
-           exit(0);
-       else if (sudo_mode == MODE_LIST) {
-           list_matches();
- #ifdef HAVE_LDAP
-           sudo_ldap_list_matches();
- #endif
-           exit(0);
-       }
+       log_allowed(validated);
+       if (sudo_mode == MODE_CHECK)
+           rc = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
+       else if (sudo_mode == MODE_LIST)
+           display_privs(snl, list_pw ? list_pw : sudo_user.pw);
+       /* Cleanup sudoers sources */
+       tq_foreach_fwd(snl, nss)
+           nss->close(nss);
+       /* Deferred exit due to sudo_ldap_close() */
+       if (sudo_mode == MODE_VALIDATE || sudo_mode == MODE_CHECK ||
+           sudo_mode == MODE_LIST)
+           exit(rc);
  
-       /* Override user's umask if configured to do so. */
-       if (def_umask != 0777)
-           (void) umask(def_umask);
+       /*
+        * Override user's umask if configured to do so.
+        * If user's umask is more restrictive, OR in those bits too.
+        */
+       if (def_umask != 0777) {
+           mode_t mask = umask(def_umask);
+           mask |= def_umask;
+           if (mask != def_umask)
+               umask(mask);
+       }
  
        /* Restore coredumpsize resource limit. */
  #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
        if (ISSET(sudo_mode, MODE_RUN))
            set_perms(PERM_FULL_RUNAS);
  
-       /* Close the password and group files */
-       endpwent();
-       endgrent();
        if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
            char *p;
  
  
            /* Change to target user's homedir. */
            if (chdir(runas_pw->pw_dir) == -1)
-               warn("unable to change directory to %s", runas_pw->pw_dir);
+               warning("unable to change directory to %s", runas_pw->pw_dir);
+ #if defined(__linux__) || defined(_AIX)
+           /* Insert system-wide environment variables. */
+           read_env_file(_PATH_ENVIRONMENT, TRUE);
+ #endif
        }
  
        if (ISSET(sudo_mode, MODE_EDIT))
            exit(sudo_edit(NewArgc, NewArgv, envp));
  
+       /* Insert system-wide environment variables. */
+       if (def_env_file)
+           read_env_file(def_env_file, FALSE);
        /* Insert user-specified environment variables. */
-       environ = insert_env_vars(environ, sudo_user.env_vars);
+       insert_env_vars(sudo_user.env_vars);
  
        /* Restore signal handlers before we exec. */
        (void) sigaction(SIGINT, &saved_sa_int, NULL);
        (void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
        (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL);
  
+       /* Close the password and group files and free up memory. */
+       sudo_endpwent();
+       sudo_endgrent();
+       closefrom(def_closefrom + 1);
  #ifndef PROFILING
        if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
            exit(0);
        else {
  #ifdef HAVE_SELINUX
            if (is_selinux_enabled() > 0 && user_role != NULL)
-               selinux_exec(user_role, user_type, NewArgv, environ,
+               selinux_exec(user_role, user_type, NewArgv,
                    ISSET(sudo_mode, MODE_LOGIN_SHELL));
  #endif
-           execve(safe_cmnd, NewArgv, environ);
+           execv(safe_cmnd, NewArgv);
        }
  #else
        exit(0);
  #endif /* PROFILING */
        /*
-        * If we got here then the exec() failed...
+        * If we got here then execve() failed...
         */
        if (errno == ENOEXEC) {
            NewArgv--;                  /* at least one extra slot... */
            NewArgv[0] = "sh";
            NewArgv[1] = safe_cmnd;
-           execve(_PATH_BSHELL, NewArgv, environ);
-       }
-       warn("unable to execute %s", safe_cmnd);
+           execv(_PATH_BSHELL, NewArgv);
+       } warning("unable to execute %s", safe_cmnd);
        exit(127);
-     } else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) {
-       log_auth(validated, 1);
+     } else if (ISSET(validated, FLAG_NO_USER | FLAG_NO_HOST)) {
+       log_denial(validated, 1);
        exit(1);
-     } else if (ISSET(validated, VALIDATE_NOT_OK)) {
+     } else {
        if (def_path_info) {
            /*
             * We'd like to not leak path info at all here, but that can
             * is just "no foo in path" since the user can trivially set
             * their path to just contain a single dir.
             */
-           log_auth(validated,
+           log_denial(validated,
                !(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND));
            if (cmnd_status == NOT_FOUND)
-               warnx("%s: command not found", user_cmnd);
+               warningx("%s: command not found", user_cmnd);
            else if (cmnd_status == NOT_FOUND_DOT)
-               warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd);
+               warningx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd);
        } else {
            /* Just tell the user they are not allowed to run foo. */
-           log_auth(validated, 1);
+           log_denial(validated, 1);
        }
        exit(1);
-     } else {
-       /* should never get here */
-       log_auth(validated, 1);
-       exit(1);
      }
      exit(0);  /* not reached */
  }
   * Initialize timezone, set umask, fill in ``sudo_user'' struct and
   * load the ``interfaces'' array.
   */
- static int
+ static void
  init_vars(sudo_mode, envp)
      int sudo_mode;
      char **envp;
  {
-     char *p, **ep, thost[MAXHOSTNAMELEN];
-     int nohostname, rval;
+     char *p, **ep, thost[MAXHOSTNAMELEN + 1];
+     int nohostname;
  
      /* Sanity check command from user. */
      if (user_cmnd == NULL && strlen(NewArgv[0]) >= PATH_MAX)
-       errx(1, "%s: File name too long", NewArgv[0]);
+       errorx(1, "%s: File name too long", NewArgv[0]);
  
  #ifdef HAVE_TZSET
      (void) tzset();           /* set the timezone if applicable */
       * "host" is the (possibly fully-qualified) hostname and
       * "shost" is the unqualified form of the hostname.
       */
 +    sudo_user.host_fqdn_queried = FALSE;
      nohostname = gethostname(thost, sizeof(thost));
      if (nohostname)
        user_host = user_shost = "localhost";
      else {
+       thost[sizeof(thost) - 1] = '\0';
        user_host = estrdup(thost);
        if (def_fqdn) {
            /* Defer call to set_fqdn() until log_error() is safe. */
            user_shost = user_host;
        } else {
 -          if ((p = strchr(user_host, '.'))) {
 -              *p = '\0';
 -              user_shost = estrdup(user_host);
 -              *p = '.';
 -          } else {
 -              user_shost = user_host;
 -          }
 +          user_shost = user_host;
        }
      }
  
        user_tty = "unknown";
  
      for (ep = envp; *ep; ep++) {
+       /* XXX - don't fill in if empty string */
        switch (**ep) {
+           case 'D':
+               if (strncmp("DISPLAY=", *ep, 8) == 0)
+                   user_display = *ep + 8;
+               break;
+           case 'K':
+               if (strncmp("KRB5CCNAME=", *ep, 11) == 0)
+                   user_ccname = *ep + 11;
+               break;
            case 'P':
                if (strncmp("PATH=", *ep, 5) == 0)
                    user_path = *ep + 5;
                    user_prompt = *ep + 12;
                else if (strncmp("SUDO_USER=", *ep, 10) == 0)
                    prev_user = *ep + 10;
+               else if (strncmp("SUDO_ASKPASS=", *ep, 13) == 0)
+                   user_askpass = *ep + 13;
                break;
            }
      }
  
         * be run during reboot after the YP/NIS/NIS+/LDAP/etc daemon has died.
         */
        if (sudo_mode & (MODE_INVALIDATE|MODE_KILL))
-           errx(1, "uid %s does not exist in the passwd file!", pw_name);
-       log_error(0, "uid %s does not exist in the passwd file!", pw_name);
+           errorx(1, "unknown uid: %s", pw_name);
+       log_error(0, "unknown uid: %s", pw_name);
      }
      if (user_shell == NULL || *user_shell == '\0')
-       user_shell = sudo_user.pw->pw_shell;
+       user_shell = estrdup(sudo_user.pw->pw_shell);
  
      /* It is now safe to use log_error() and set_perms() */
  
      if (nohostname)
        log_error(USE_ERRNO|MSG_ONLY, "can't get hostname");
  
-     set_runaspw(*user_runas);         /* may call log_error() */
-     if (*user_runas[0] == '#' && runas_pw->pw_name && runas_pw->pw_name[0])
-       *user_runas = estrdup(runas_pw->pw_name);
      /*
       * Get current working directory.  Try as user, fall back to root.
       */
      if (!getcwd(user_cwd, sizeof(user_cwd))) {
        set_perms(PERM_ROOT);
        if (!getcwd(user_cwd, sizeof(user_cwd))) {
-           warnx("cannot get working directory");
+           warningx("cannot get working directory");
            (void) strlcpy(user_cwd, "unknown", sizeof(user_cwd));
        }
      } else
       * If we were given the '-e', '-i' or '-s' options we need to redo
       * NewArgv and NewArgc.
       */
-     if ((sudo_mode & (MODE_SHELL | MODE_EDIT))) {
-       char **dst, **src = NewArgv;
+     if (ISSET(sudo_mode, MODE_EDIT)) {
+       NewArgv--;
+       NewArgc++;
+       NewArgv[0] = "sudoedit";
+     } else if (ISSET(sudo_mode, MODE_SHELL)) {
+       char **av;
  
        /* Allocate an extra slot for execve() failure (ENOEXEC). */
-       NewArgv = (char **) emalloc2((++NewArgc + 2), sizeof(char *));
-       NewArgv++;
-       if (ISSET(sudo_mode, MODE_EDIT))
-           NewArgv[0] = "sudoedit";
-       else if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
-           NewArgv[0] = runas_pw->pw_shell;
-       else if (user_shell && *user_shell)
-           NewArgv[0] = user_shell;
-       else
-           errx(1, "unable to determine shell");
-       /* copy the args from NewArgv */
-       for (dst = NewArgv + 1; (*dst = *src) != NULL; ++src, ++dst)
-           continue;
+       av = (char **) emalloc2(5, sizeof(char *));
+       av++;
+       av[0] = user_shell;     /* may be updated later */
+       if (NewArgc > 0) {
+           size_t size;
+           char *cmnd, *src, *dst, *end;
+           size = (size_t) (NewArgv[NewArgc - 1] - NewArgv[0]) +
+                   strlen(NewArgv[NewArgc - 1]) + 1;
+           cmnd = emalloc(size);
+           src = NewArgv[0];
+           dst = cmnd;
+           for (end = src + size - 1; src < end; src++, dst++)
+               *dst = *src == 0 ? ' ' : *src;
+           *dst = '\0';
+           av[1] = "-c";
+           av[2] = cmnd;
+           NewArgc = 2;
+       }
+       av[++NewArgc] = NULL;
+       NewArgv = av;
      }
+ }
  
-     /* Set login class if applicable. */
-     set_loginclass(sudo_user.pw);
+ /*
+  * Fill in user_cmnd, user_args, user_base and user_stat variables
+  * and apply any command-specific defaults entries.
+  */
+ static int
+ set_cmnd(sudo_mode)
+     int sudo_mode;
+ {
+     int rval;
  
      /* Set project if applicable. */
      set_project(runas_pw);
      /* Resolve the path and return. */
      rval = FOUND;
      user_stat = emalloc(sizeof(struct stat));
-     if (sudo_mode & (MODE_RUN | MODE_EDIT)) {
-       if (ISSET(sudo_mode, MODE_RUN)) {
-           /* XXX - default_runas may be modified during parsing of sudoers */
+     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
+       if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
            set_perms(PERM_RUNAS);
            rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path);
            set_perms(PERM_ROOT);
            size_t size, n;
  
            /* If we didn't realloc NewArgv it is contiguous so just count. */
-           if (!(sudo_mode & (MODE_SHELL | MODE_EDIT))) {
+           if (!ISSET(sudo_mode, MODE_SHELL)) {
                size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
                        strlen(NewArgv[NewArgc-1]) + 1;
            } else {
            for (to = user_args, from = NewArgv + 1; *from; from++) {
                n = strlcpy(to, *from, size - (to - user_args));
                if (n >= size - (to - user_args))
-                   errx(1, "internal error, init_vars() overflow");
+                   errorx(1, "internal error, init_vars() overflow");
                to += n;
                *to++ = ' ';
            }
      else
        user_base = user_cmnd;
  
+     if (!update_defaults(SETDEF_CMND))
+       log_error(NO_STDERR|NO_EXIT, "problem with defaults entries");
      return(rval);
  }
  
  /*
-  * Command line argument parsing, can't use getopt(3).
+  * Command line argument parsing.
+  * Sets NewArgc and NewArgv which corresponds to the argc/argv we'll use
+  * for the command to be run (if we are running one).
   */
  static int
  parse_args(argc, argv)
      int argc;
      char **argv;
  {
-     int rval = MODE_RUN;              /* what mode is sudo to be run in? */
-     int excl = 0;                     /* exclusive arg, no others allowed */
-     NewArgv = argv + 1;
-     NewArgc = argc - 1;
+     int mode = 0;             /* what mode is sudo to be run in? */
+     int flags = 0;            /* mode flags */
+     int ch;
  
      /* First, check to see if we were invoked as "sudoedit". */
-     if (strcmp(getprogname(), "sudoedit") == 0) {
-       rval = MODE_EDIT;
-       excl = 'e';
-     } else
-       rval = MODE_RUN;
-     while (NewArgc > 0) {
-       if (NewArgv[0][0] == '-') {
-           if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') {
-               warnx("please use single character options");
-               usage(1);
-           }
-           switch (NewArgv[0][1]) {
-               case 'p':
-                   /* Must have an associated prompt. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
+     if (strcmp(getprogname(), "sudoedit") == 0)
+       mode = MODE_EDIT;
  
-                   user_prompt = NewArgv[1];
-                   def_passprompt_override = TRUE;
+     /* Returns true if the last option string was "--" */
+ #define got_end_of_args       (optind > 1 && argv[optind - 1][0] == '-' && \
+           argv[optind - 1][1] == '-' && argv[optind - 1][2] == '\0')
  
-                   NewArgc--;
-                   NewArgv++;
-                   break;
-               case 'u':
-                   /* Must have an associated runas user. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
+     /* Returns true if next option is an environment variable */
+ #define is_envar (optind < argc && argv[optind][0] != '/' && \
+           strchr(argv[optind], '=') != NULL)
  
-                   user_runas = &NewArgv[1];
-                   NewArgc--;
-                   NewArgv++;
+     for (;;) {
+       /*
+        * We disable arg permutation for GNU getopt().
+        * Some trickiness is required to allow environment variables
+        * to be interspersed with command line options.
+        */
+       if ((ch = getopt(argc, argv, "+Aa:bC:c:Eeg:HhiKkLlnPp:r:Sst:U:u:Vv")) != -1) {
+           switch (ch) {
+               case 'A':
+                   SET(tgetpass_flags, TGP_ASKPASS);
                    break;
  #ifdef HAVE_BSD_AUTH_H
                case 'a':
-                   /* Must have an associated authentication style. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
-                   login_style = NewArgv[1];
-                   NewArgc--;
-                   NewArgv++;
+                   login_style = optarg;
                    break;
  #endif
+               case 'b':
+                   SET(flags, MODE_BACKGROUND);
+                   break;
+               case 'C':
+                   if ((user_closefrom = atoi(optarg)) < 3) {
+                       warningx("the argument to -C must be at least 3");
+                       usage(1);
+                   }
+                   break;
  #ifdef HAVE_LOGIN_CAP_H
                case 'c':
-                   /* Must have an associated login class. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
-                   login_class = NewArgv[1];
+                   login_class = optarg;
                    def_use_loginclass = TRUE;
-                   NewArgc--;
-                   NewArgv++;
                    break;
  #endif
-               case 'b':
-                   SET(rval, MODE_BACKGROUND);
+               case 'E':
+                   SET(flags, MODE_PRESERVE_ENV);
                    break;
                case 'e':
-                   rval = MODE_EDIT;
-                   if (excl && excl != 'e')
+                   if (mode && mode != MODE_EDIT)
                        usage_excl(1);
-                   excl = 'e';
+                   mode = MODE_EDIT;
                    break;
-               case 'v':
-                   rval = MODE_VALIDATE;
-                   if (excl && excl != 'v')
+               case 'g':
+                   runas_group = optarg;
+                   break;
+               case 'H':
+                   SET(flags, MODE_RESET_HOME);
+                   break;
+               case 'h':
+                   if (mode && mode != MODE_HELP)
                        usage_excl(1);
-                   excl = 'v';
+                   mode = MODE_HELP;
                    break;
                case 'i':
-                   SET(rval, (MODE_LOGIN_SHELL | MODE_SHELL));
+                   SET(flags, MODE_LOGIN_SHELL);
                    def_env_reset = TRUE;
-                   if (excl && excl != 'i')
-                       usage_excl(1);
-                   excl = 'i';
                    break;
                case 'k':
-                   rval = MODE_INVALIDATE;
-                   if (excl && excl != 'k')
+                   if (mode && mode != MODE_INVALIDATE)
                        usage_excl(1);
-                   excl = 'k';
+                   mode = MODE_INVALIDATE;
                    break;
                case 'K':
-                   rval = MODE_KILL;
-                   if (excl && excl != 'K')
+                   if (mode && mode != MODE_KILL)
                        usage_excl(1);
-                   excl = 'K';
+                   mode = MODE_KILL;
                    break;
                case 'L':
-                   rval = MODE_LISTDEFS;
-                   if (excl && excl != 'L')
+                   if (mode && mode != MODE_LISTDEFS)
                        usage_excl(1);
-                   excl = 'L';
+                   mode = MODE_LISTDEFS;
                    break;
                case 'l':
-                   rval = MODE_LIST;
-                   if (excl && excl != 'l')
-                       usage_excl(1);
-                   excl = 'l';
+                   if (mode) {
+                       if (mode == MODE_LIST)
+                           long_list = 1;
+                       else
+                           usage_excl(1);
+                   }
+                   mode = MODE_LIST;
                    break;
-               case 'V':
-                   rval = MODE_VERSION;
-                   if (excl && excl != 'V')
-                       usage_excl(1);
-                   excl = 'V';
+               case 'n':
+                   SET(flags, MODE_NONINTERACTIVE);
                    break;
-               case 'h':
-                   rval = MODE_HELP;
-                   if (excl && excl != 'h')
-                       usage_excl(1);
-                   excl = 'h';
+               case 'P':
+                   SET(flags, MODE_PRESERVE_GROUPS);
                    break;
-               case 's':
-                   SET(rval, MODE_SHELL);
-                   if (excl && excl != 's')
-                       usage_excl(1);
-                   excl = 's';
+               case 'p':
+                   user_prompt = optarg;
+                   def_passprompt_override = TRUE;
                    break;
-               case 'H':
-                   SET(rval, MODE_RESET_HOME);
+ #ifdef HAVE_SELINUX
+               case 'r':
+                   user_role = optarg;
                    break;
-               case 'P':
-                   SET(rval, MODE_PRESERVE_GROUPS);
+               case 't':
+                   user_type = optarg;
                    break;
+ #endif
                case 'S':
                    SET(tgetpass_flags, TGP_STDIN);
                    break;
-               case 'E':
-                   SET(rval, MODE_PRESERVE_ENV);
+               case 's':
+                   SET(flags, MODE_SHELL);
                    break;
- #ifdef HAVE_SELINUX
-               case 'r':
-                   /* Must have an associated SELinux role. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
-                   user_role = NewArgv[1];
-                   NewArgc--;
-                   NewArgv++;
+               case 'U':
+                   if ((list_pw = sudo_getpwnam(optarg)) == NULL)
+                       errorx(1, "unknown user: %s", optarg);
                    break;
-               case 't':
-                   /* Must have an associated SELinux type. */
-                   if (NewArgv[1] == NULL)
-                       usage(1);
-                   user_type = NewArgv[1];
-                   NewArgc--;
-                   NewArgv++;
+               case 'u':
+                   runas_user = optarg;
+                   break;
+               case 'v':
+                   if (mode && mode != MODE_VALIDATE)
+                       usage_excl(1);
+                   mode = MODE_VALIDATE;
+                   break;
+               case 'V':
+                   if (mode && mode != MODE_VERSION)
+                       usage_excl(1);
+                   mode = MODE_VERSION;
                    break;
- #endif
-               case '-':
-                   NewArgc--;
-                   NewArgv++;
-                   goto args_done;
-               case '\0':
-                   warnx("'-' requires an argument");
-                   usage(1);
                default:
-                   warnx("illegal option `%s'", NewArgv[0]);
                    usage(1);
            }
-       } else if (NewArgv[0][0] != '/' && strchr(NewArgv[0], '=') != NULL) {
-           /* Could be an environment variable. */
+       } else if (!got_end_of_args && is_envar) {
            struct list_member *ev;
+           /* Store environment variable. */
            ev = emalloc(sizeof(*ev));
-           ev->value = NewArgv[0];
+           ev->value = argv[optind];
            ev->next = sudo_user.env_vars;
            sudo_user.env_vars = ev;
+           /* Crank optind and resume getopt. */
+           optind++;
        } else {
-           /* Not an arg */
+           /* Not an option or an environment variable -- we're done. */
            break;
        }
-       NewArgc--;
-       NewArgv++;
      }
- args_done:
  
-     if (ISSET(rval, MODE_EDIT) &&
-       (ISSET(rval, MODE_PRESERVE_ENV) || sudo_user.env_vars != NULL)) {
-       if (ISSET(rval, MODE_PRESERVE_ENV))
-           warnx("the `-E' option is not valid in edit mode");
+     NewArgc = argc - optind;
+     NewArgv = argv + optind;
+     if (!mode)
+       mode = MODE_RUN;
+     if (NewArgc > 0 && mode == MODE_LIST)
+       mode = MODE_CHECK;
+     if (ISSET(flags, MODE_LOGIN_SHELL)) {
+       if (ISSET(flags, MODE_SHELL)) {
+           warningx("you may not specify both the `-i' and `-s' options");
+           usage(1);
+       }
+       if (ISSET(flags, MODE_PRESERVE_ENV)) {
+           warningx("you may not specify both the `-i' and `-E' options");
+           usage(1);
+       }
+       SET(flags, MODE_SHELL);
+     }
+     if (mode == MODE_EDIT &&
+        (ISSET(flags, MODE_PRESERVE_ENV) || sudo_user.env_vars != NULL)) {
+       if (ISSET(mode, MODE_PRESERVE_ENV))
+           warningx("the `-E' option is not valid in edit mode");
        if (sudo_user.env_vars != NULL)
-           warnx("you may not specify environment variables in edit mode");
+           warningx("you may not specify environment variables in edit mode");
+       usage(1);
+     }
+     if ((runas_user != NULL || runas_group != NULL) &&
+       !ISSET(mode, MODE_EDIT | MODE_RUN | MODE_CHECK)) {
        usage(1);
      }
-     if (ISSET(rval, MODE_PRESERVE_ENV) && ISSET(rval, MODE_LOGIN_SHELL)) {
-       warnx("you may not specify both the `-i' and `-E' options");
+     if (list_pw != NULL && mode != MODE_LIST && mode != MODE_CHECK) {
+       warningx("the `-U' option may only be used with the `-l' option");
        usage(1);
      }
-     if (user_runas != NULL && !ISSET(rval, (MODE_EDIT|MODE_RUN))) {
-       if (excl != '\0')
-           warnx("the `-u' and '-%c' options may not be used together", excl);
+     if (ISSET(tgetpass_flags, TGP_STDIN) && ISSET(tgetpass_flags, TGP_ASKPASS)) {
+       warningx("the `-A' and `-S' options may not be used together");
        usage(1);
      }
-     if ((NewArgc == 0 && (rval & MODE_EDIT)) ||
-       (NewArgc > 0 && !(rval & (MODE_RUN | MODE_EDIT))))
+     if ((NewArgc == 0 && mode == MODE_EDIT) ||
+       (NewArgc > 0 && !ISSET(mode, MODE_RUN | MODE_EDIT | MODE_CHECK)))
        usage(1);
-     if (NewArgc == 0 && rval == MODE_RUN)
-       SET(rval, (MODE_IMPLIED_SHELL | MODE_SHELL));
+     if (NewArgc == 0 && mode == MODE_RUN && !ISSET(flags, MODE_SHELL))
+       SET(flags, (MODE_IMPLIED_SHELL | MODE_SHELL));
  
-     return(rval);
+     return(mode | flags);
  }
  
  /*
-  * Sanity check sudoers mode/owner/type.
-  * Leaves a file pointer to the sudoers file open in ``fp''.
+  * Open sudoers and sanity check mode/owner/type.
+  * Returns a handle to the sudoers file or NULL on error.
   */
- static void
- check_sudoers()
+ FILE *
+ open_sudoers(sudoers, keepopen)
+     const char *sudoers;
+     int *keepopen;
  {
      struct stat statbuf;
-     int rootstat, i;
+     FILE *fp = NULL;
+     int rootstat;
  
      /*
       * Fix the mode and group on sudoers file from old default.
       * Only works if file system is readable/writable by root.
       */
-     if ((rootstat = stat_sudoers(_PATH_SUDOERS, &statbuf)) == 0 &&
+     if ((rootstat = stat_sudoers(sudoers, &statbuf)) == 0 &&
        SUDOERS_UID == statbuf.st_uid && SUDOERS_MODE != 0400 &&
        (statbuf.st_mode & 0007777) == 0400) {
  
-       if (chmod(_PATH_SUDOERS, SUDOERS_MODE) == 0) {
-           warnx("fixed mode on %s", _PATH_SUDOERS);
+       if (chmod(sudoers, SUDOERS_MODE) == 0) {
+           warningx("fixed mode on %s", sudoers);
            SET(statbuf.st_mode, SUDOERS_MODE);
            if (statbuf.st_gid != SUDOERS_GID) {
-               if (!chown(_PATH_SUDOERS,(uid_t) -1,SUDOERS_GID)) {
-                   warnx("set group on %s", _PATH_SUDOERS);
+               if (chown(sudoers, (uid_t) -1, SUDOERS_GID) == 0) {
+                   warningx("set group on %s", sudoers);
                    statbuf.st_gid = SUDOERS_GID;
                } else
-                   warn("unable to set group on %s", _PATH_SUDOERS);
+                   warning("unable to set group on %s", sudoers);
            }
        } else
-           warn("unable to fix mode on %s", _PATH_SUDOERS);
+           warning("unable to fix mode on %s", sudoers);
      }
  
      /*
       */
      set_perms(PERM_SUDOERS);
  
-     if (rootstat != 0 && stat_sudoers(_PATH_SUDOERS, &statbuf) != 0)
-       log_error(USE_ERRNO, "can't stat %s", _PATH_SUDOERS);
+     if (rootstat != 0 && stat_sudoers(sudoers, &statbuf) != 0)
+       log_error(USE_ERRNO|NO_EXIT, "can't stat %s", 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);
+       log_error(NO_EXIT, "%s is not a regular file", sudoers);
      else if ((statbuf.st_mode & 07777) != SUDOERS_MODE)
-       log_error(0, "%s is mode 0%o, should be 0%o", _PATH_SUDOERS,
+       log_error(NO_EXIT, "%s is mode 0%o, should be 0%o", sudoers,
            (unsigned int) (statbuf.st_mode & 07777),
            (unsigned int) SUDOERS_MODE);
      else if (statbuf.st_uid != SUDOERS_UID)
-       log_error(0, "%s is owned by uid %lu, should be %lu", _PATH_SUDOERS,
+       log_error(NO_EXIT, "%s is owned by uid %lu, should be %lu", sudoers,
            (unsigned long) statbuf.st_uid, (unsigned long) SUDOERS_UID);
      else if (statbuf.st_gid != SUDOERS_GID)
-       log_error(0, "%s is owned by gid %lu, should be %lu", _PATH_SUDOERS,
+       log_error(NO_EXIT, "%s is owned by gid %lu, should be %lu", sudoers,
            (unsigned long) statbuf.st_gid, (unsigned long) SUDOERS_GID);
-     else {
-       /* Solaris sometimes returns EAGAIN so try 10 times */
-       for (i = 0; i < 10 ; i++) {
-           errno = 0;
-           if ((sudoers_fp = fopen(_PATH_SUDOERS, "r")) == NULL ||
-               fgetc(sudoers_fp) == EOF) {
-               if (sudoers_fp != NULL)
-                   fclose(sudoers_fp);
-               sudoers_fp = NULL;
-               if (errno != EAGAIN && errno != EWOULDBLOCK)
-                   break;
-           } else
-               break;
-           sleep(1);
-       }
-       if (sudoers_fp == NULL)
-           log_error(USE_ERRNO, "can't open %s", _PATH_SUDOERS);
+     else if ((fp = fopen(sudoers, "r")) == NULL)
+       log_error(USE_ERRNO, "can't open %s", sudoers);
+     else if (statbuf.st_size != 0) {
+       /*
+        * Make sure we can actually read sudoers so we can present the
+        * user with a reasonable error message.
+        */
+       if (fgetc(fp) == EOF)
+           log_error(USE_ERRNO, "can't read %s", sudoers);
+       rewind(fp);
      }
+     (void) fcntl(fileno(fp), F_SETFD, 1);
  
      set_perms(PERM_ROOT);             /* change back to root */
+     return(fp);
  }
  
  /*
   * 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()
                (void) dup2(devnull, STDOUT_FILENO);
            if (miss[STDERR_FILENO])
                (void) dup2(devnull, STDERR_FILENO);
+           if (devnull > STDERR_FILENO)
+               close(devnull);
        }
      }
-     closefrom(STDERR_FILENO + 1);
  }
  
  #ifdef HAVE_LOGIN_CAP_H
@@@ -1081,8 -1167,9 +1162,9 @@@ set_loginclass(pw
        errflags = NO_MAIL|MSG_ONLY|NO_EXIT;
  
      if (login_class && strcmp(login_class, "-") != 0) {
-       if (strcmp(*user_runas, "root") != 0 && user_uid != 0)
-           errx(1, "only root can use -c %s", login_class);
+       if (user_uid != 0 &&
+           strcmp(runas_user ? runas_user : def_runas_default, "root") != 0)
+           errorx(1, "only root can use -c %s", login_class);
      } else {
        login_class = pw->pw_class;
        if (!login_class || !*login_class)
@@@ -1185,7 -1272,7 +1267,7 @@@ set_fqdn(
      char *p;
  
  #ifdef HAVE_GETADDRINFO
-     memset(&hint, 0, sizeof(hint));
+     zero_bytes(&hint, sizeof(hint));
      hint.ai_family = PF_UNSPEC;
      hint.ai_flags = AI_CANONNAME;
      if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
      } else {
        user_shost = user_host;
      }
 +    sudo_user.host_fqdn_queried = TRUE;
  }
  
  /*
   * Get passwd entry for the user we are going to run commands as.
   * By default, this is "root".  Updates runas_pw as a side effect.
   */
- int
+ static void
  set_runaspw(user)
      char *user;
  {
-     if (runas_pw != NULL) {
-       if (user_runas != &def_runas_default)
-           return(TRUE);               /* don't override -u option */
-       efree(runas_pw);
-     }
      if (*user == '#') {
-       runas_pw = sudo_getpwuid(atoi(user + 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 + 1);
-       }
+       if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
+           runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
      } else {
-       runas_pw = sudo_getpwnam(user);
-       if (runas_pw == NULL)
-           log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", user);
+       if ((runas_pw = sudo_getpwnam(user)) == NULL)
+           log_error(NO_MAIL|MSG_ONLY, "unknown user: %s", user);
+     }
+ }
+ /*
+  * Get group entry for the group we are going to run commands as.
+  * Updates runas_pw as a side effect.
+  */
+ static void
+ set_runasgr(group)
+     char *group;
+ {
+     if (*group == '#') {
+       if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
+           runas_gr = sudo_fakegrnam(group);
+     } else {
+       if ((runas_gr = sudo_getgrnam(group)) == NULL)
+           log_error(NO_MAIL|MSG_ONLY, "unknown group: %s", group);
      }
-     return(TRUE);
  }
  
  /*
@@@ -1254,19 -1346,14 +1342,14 @@@ get_authpw(
      struct passwd *pw;
  
      if (def_rootpw) {
-       if (runas_pw->pw_uid == 0)
-           pw = runas_pw;
-       else if ((pw = sudo_getpwuid(0)) == NULL)
-           log_error(0, "uid 0 does not exist in the passwd file!");
+       if ((pw = sudo_getpwuid(0)) == NULL)
+           log_error(0, "unknown uid: 0");
      } else if (def_runaspw) {
-       if (strcmp(def_runas_default, *user_runas) == 0)
-           pw = runas_pw;
-       else if ((pw = sudo_getpwnam(def_runas_default)) == NULL)
-           log_error(0, "user %s does not exist in the passwd file!",
-               def_runas_default);
+       if ((pw = sudo_getpwnam(def_runas_default)) == NULL)
+           log_error(0, "unknown user: %s", def_runas_default);
      } else if (def_targetpw) {
        if (runas_pw->pw_name == NULL)
-           log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %lu!",
+           log_error(NO_MAIL|MSG_ONLY, "unknown uid: %lu",
                (unsigned long) runas_pw->pw_uid);
        pw = runas_pw;
      } else
      return(pw);
  }
  
+ /*
+  * Cleanup hook for error()/errorx()
+  */
+ void
+ cleanup(gotsignal)
+     int gotsignal;
+ {
+     struct sudo_nss *nss;
+     if (!gotsignal) {
+       if (snl != NULL) {
+           tq_foreach_fwd(snl, nss)
+               nss->close(nss);
+       }
+       sudo_endpwent();
+       sudo_endgrent();
+     }
+ }
+ static void
+ show_version()
+ {
+     (void) printf("Sudo version %s\n", version);
+     if (getuid() == 0) {
+       putchar('\n');
+       (void) printf("Sudoers path: %s\n", _PATH_SUDOERS);
+ #ifdef HAVE_LDAP
+ # ifdef _PATH_NSSWITCH_CONF
+       (void) printf("nsswitch path: %s\n", _PATH_NSSWITCH_CONF);
+ # endif
+       (void) printf("ldap.conf path: %s\n", _PATH_LDAP_CONF);
+       (void) printf("ldap.secret path: %s\n", _PATH_LDAP_SECRET);
+ #endif
+       dump_auth_methods();
+       dump_defaults();
+       dump_interfaces();
+     }
+     exit(0);
+ }
  /*
   * Tell which options are mutually exclusive and exit.
   */
@@@ -1282,98 -1409,46 +1405,46 @@@ static voi
  usage_excl(exit_val)
      int exit_val;
  {
-     warnx("Only one of the -e, -h, i, -k, -K, -l, -s, -v or -V options may be used");
+     warningx("Only one of the -e, -h, -i, -k, -K, -l, -s, -v or -V options may be specified");
      usage(exit_val);
  }
  
  /*
   * Give usage message and exit.
+  * The actual usage strings are in sudo_usage.h for configure substitution.
   */
  static void
  usage(exit_val)
      int exit_val;
  {
-     char **p, **uvec[4];
-     int i, linelen, linemax, ulen, plen;
-     static char *uvec1[] = {
-       " -h |",
-       " -K |",
-       " -k |",
-       " -L |",
-       " -l |",
-       " -V |",
-       " -v",
-       NULL
-     };
-     static char *uvec2[] = {
-       " [-bEHPS]",
- #ifdef HAVE_BSD_AUTH_H
-       " [-a auth_type]",
- #endif
- #ifdef HAVE_LOGIN_CAP_H
-       " [-c class|-]",
- #endif
- #ifdef HAVE_SELINUX
-       " [-r role]",
- #endif
-       " [-p prompt]",
- #ifdef HAVE_SELINUX
-       " [-t type]",
- #endif
-       " [-u username|#uid]",
-       " [VAR=value]",
-       " {-i | -s | <command>}",
-       NULL
-     };
-     static char *uvec3[] = {
-       " -e",
-       " [-S]",
- #ifdef HAVE_BSD_AUTH_H
-       " [-a auth_type]",
- #endif
- #ifdef HAVE_LOGIN_CAP_H
-       " [-c class|-]",
- #endif
-       " [-p prompt]",
-       " [-u username|#uid]",
-       " file ...",
-       NULL
-     };
+     struct lbuf lbuf;
+     char *uvec[5];
+     int i, ulen;
  
      /*
       * Use usage vectors appropriate to the progname.
       */
      if (strcmp(getprogname(), "sudoedit") == 0) {
-       uvec[0] = uvec3 + 1;
+       uvec[0] = SUDO_USAGE4 + 3;
        uvec[1] = NULL;
      } else {
-       uvec[0] = uvec1;
-       uvec[1] = uvec2;
-       uvec[2] = uvec3;
-       uvec[3] = NULL;
+       uvec[0] = SUDO_USAGE1;
+       uvec[1] = SUDO_USAGE2;
+       uvec[2] = SUDO_USAGE3;
+       uvec[3] = SUDO_USAGE4;
+       uvec[4] = NULL;
      }
  
      /*
-      * Print usage and wrap lines as needed.
-      * Assumes an 80-character wide terminal, which is kind of bogus...
+      * Print usage and wrap lines as needed, depending on the
+      * tty width.
       */
-     ulen = (int)strlen(getprogname()) + 7;
-     linemax = 80;
+     ulen = (int)strlen(getprogname()) + 8;
+     lbuf_init(&lbuf, NULL, ulen, 0);
      for (i = 0; uvec[i] != NULL; i++) {
-       printf("usage: %s", getprogname());
-       linelen = linemax - ulen;
-       for (p = uvec[i]; *p != NULL; p++) {
-           plen = (int)strlen(*p);
-           if (linelen >= plen || linelen == linemax - ulen) {
-               fputs(*p, stdout);
-               linelen -= plen;
-           } else {
-               p--;
-               linelen = linemax - ulen;
-               printf("\n%*s", ulen, "");
-           }
-       }
-       putchar('\n');
+       lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL);
+       lbuf_print(&lbuf);
      }
+     lbuf_destroy(&lbuf);
      exit(exit_val);
  }
diff --combined sudo.man.in
index fbef6554d8ea8f555003367bd9d61bdab8bb7881,26d8a309538e416889416c0889d03cbf7389c040..01e33e6f7ea2ff05204f552b1fdd36e5eb1b44a7
@@@ -1,4 -1,4 +1,4 @@@
- .\" Copyright (c) 1994-1996, 1998-2005, 2007
+ .\" Copyright (c) 1994-1996, 1998-2005, 2007-2008
  .\"   Todd C. Miller <Todd.Miller@courtesan.com>
  .\" 
  .\" Permission to use, copy, modify, and distribute this software for any
@@@ -18,8 -18,8 +18,8 @@@
  .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
  .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
  .\" 
- .\" $Sudo: sudo.man.in,v 1.29.2.27 2008/06/22 20:29:03 millert Exp $
- .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+ .\" $Sudo: sudo.man.in,v 1.53 2008/11/15 18:34:26 millert Exp $
+ .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
  .\"
  .\" Standard preamble:
  .\" ========================================================================
  ..
  .\" Set up some character translations and predefined strings.  \*(-- will
  .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
- .\" double quote, and \*(R" will give a right double quote.  | will give a
- .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
- .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
- .\" expand to `' in nroff, nothing in troff, for use with C<>.
- .tr \(*W-|\(bv\*(Tr
+ .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+ .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+ .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+ .\" nothing in troff, for use with C<>.
+ .tr \(*W-
  .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
  .ie n \{\
  .    ds -- \(*W-
  .    ds R" ''
  'br\}
  .\"
+ .\" Escape single quotes in literal strings from groff's Unicode transform.
+ .ie \n(.g .ds Aq \(aq
+ .el       .ds Aq '
+ .\"
  .\" If the F register is turned on, we'll generate index entries on stderr for
  .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
  .\" entries marked with X<> in POD.  Of course, you'll have to process the
  .\" output yourself in some meaningful fashion.
- .if \nF \{\
+ .ie \nF \{\
  .    de IX
  .    tm Index:\\$1\t\\n%\t"\\$2"
  ..
  .    nr % 0
  .    rr F
  .\}
- .\"
- .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
- .\" way too many mistakes in technical documents.
- .hy 0
- .if n .na
+ .el \{\
+ .    de IX
+ ..
+ .\}
  .\"
  .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
  .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
  .\" ========================================================================
  .\"
  .IX Title "SUDO @mansectsu@"
- .TH SUDO @mansectsu@ "Jun 21, 2008" "1.6.9p17" "MAINTENANCE COMMANDS"
+ .TH SUDO @mansectsu@ "November 15, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+ .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+ .\" way too many mistakes in technical documents.
+ .if n .ad l
+ .nh
  .SH "NAME"
  sudo, sudoedit \- execute a command as another user
  .SH "SYNOPSIS"
  .IX Header "SYNOPSIS"
- \&\fBsudo\fR \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-L\fR | \fB\-l\fR | \fB\-V\fR | \fB\-v\fR
+ \&\fBsudo\fR [\fB\-n\fR] \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-L\fR | \fB\-V\fR | \fB\-v\fR
+ .PP
+ \&\fBsudo\fR \fB\-l[l]\fR [\fB\-AnS\fR] [\fB\-g\fR\ \fIgroupname\fR|\fI#gid\fR] [\fB\-U\fR\ \fIusername\fR]
+ [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR] [\fIcommand\fR]
  .PP
- \&\fBsudo\fR [\fB\-bEHPS\fR]
+ \&\fBsudo\fR [\fB\-AbEHnPS\fR]
  @BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+ [\fB\-C\fR\ \fIfd\fR]
  @LCMAN@[\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
- [\fB\-p\fR\ \fIprompt\fR]
+ [\fB\-g\fR\ \fIgroupname\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
  @SEMAN@[\fB\-r\fR\ \fIrole\fR] [\fB\-t\fR\ \fItype\fR]
  [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
- [\fB\s-1VAR\s0\fR=\fIvalue\fR] {\fB\-i\fR\ |\ \fB\-s\fR\ |\ \fIcommand\fR}
+ [\fB\s-1VAR\s0\fR=\fIvalue\fR] [\fB\-i\fR\ |\ \fB\-s\fR] [\fIcommand\fR]
  .PP
- \&\fBsudoedit\fR [\fB\-S\fR]
+ \&\fBsudoedit\fR [\fB\-AnS\fR]
  @BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+ [\fB\-C\fR\ \fIfd\fR]
  @LCMAN@[\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
- [\fB\-p\fR\ \fIprompt\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
- file ...
+ [\fB\-g\fR\ \fIgroupname\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
[\fB\-u\fR\ \fIusername\fR|\fI#uid\fR] file ...
  .SH "DESCRIPTION"
  .IX Header "DESCRIPTION"
  \&\fBsudo\fR allows a permitted user to execute a \fIcommand\fR as the
@@@ -190,17 -202,17 +202,17 @@@ When invoked as \fBsudoedit\fR, the \fB
  is implied.
  .PP
  \&\fBsudo\fR determines who is an authorized user by consulting the file
- \&\fI@sysconfdir@/sudoers\fR.  By giving \fBsudo\fR the \fB\-v\fR flag, a user
- can update the time stamp without running a \fIcommand\fR. The password
- prompt itself will also time out if the user's password is not
- entered within \f(CW\*(C`@password_timeout@\*(C'\fR minutes (unless overridden via
\&\fIsudoers\fR).
+ \&\fI@sysconfdir@/sudoers\fR.  By running \fBsudo\fR with the \fB\-v\fR option,
+ a user can update the time stamp without running a \fIcommand\fR. The
+ password prompt itself will also time out if the user's password
+ is not entered within \f(CW\*(C`@password_timeout@\*(C'\fR minutes (unless overridden
via \fIsudoers\fR).
  .PP
  If a user who is not listed in the \fIsudoers\fR file tries to run a
  command via \fBsudo\fR, mail is sent to the proper authorities, as
  defined at configure time or in the \fIsudoers\fR file (defaults to
  \&\f(CW\*(C`@mailto@\*(C'\fR).  Note that the mail will not be sent if an unauthorized
- user tries to run sudo with the \fB\-l\fR or \fB\-v\fR flags.  This allows
+ user tries to run sudo with the \fB\-l\fR or \fB\-v\fR option.  This allows
  users to determine for themselves whether or not they are allowed
  to use \fBsudo\fR.
  .PP
@@@ -208,7 -220,7 +220,7 @@@ If \fBsudo\fR is run by root and the \f
  is set, \fBsudo\fR will use this value to determine who the actual
  user is.  This can be used by a user to log commands through sudo
  even when a root shell has been invoked.  It also allows the \fB\-e\fR
flag to remain useful even when being run via a sudo-run script or
option to remain useful even when being run via a sudo-run script or
  program.  Note however, that the sudoers lookup is still done for
  root, not the user specified by \f(CW\*(C`SUDO_USER\*(C'\fR.
  .PP
@@@ -219,57 -231,75 +231,75 @@@ or via the \fIsudoers\fR file
  .SH "OPTIONS"
  .IX Header "OPTIONS"
  \&\fBsudo\fR accepts the following command line options:
- @BAMAN@.IP "\-a" 4
- @BAMAN@.IX Item "-a"
+ .IP "\-A" 12
+ .IX Item "-A"
+ Normally, if \fBsudo\fR requires a password, it will read it from the
+ current terminal.  If the \fB\-A\fR (\fIaskpass\fR) option is specified,
+ a helper program is executed to read the user's password and output
+ the password to the standard output.  If the \f(CW\*(C`SUDO_ASKPASS\*(C'\fR
+ environment variable is set, it specifies the path to the helper
+ program.  Otherwise, the value specified by the \fIaskpass\fR option
+ in \fIsudoers\fR\|(@mansectform@) is used.
+ @BAMAN@.IP "\-a \fItype\fR" 12
+ @BAMAN@.IX Item "-a type"
  @BAMAN@The \fB\-a\fR (\fIauthentication type\fR) option causes \fBsudo\fR to use the
  @BAMAN@specified authentication type when validating the user, as allowed
  @BAMAN@by \fI/etc/login.conf\fR.  The system administrator may specify a list
- @BAMAN@of sudo-specific authentication methods by adding an \*(L"auth\-sudo\*(R"
+ @BAMAN@of sudo-specific authentication methods by adding an \*(L"auth-sudo\*(R"
  @BAMAN@entry in \fI/etc/login.conf\fR.  This option is only available on systems
  @BAMAN@that support \s-1BSD\s0 authentication.
- .IP "\-b" 4
+ .IP "\-b" 12
  .IX Item "-b"
  The \fB\-b\fR (\fIbackground\fR) option tells \fBsudo\fR to run the given
  command in the background.  Note that if you use the \fB\-b\fR
  option you cannot use shell job control to manipulate the process.
- @LCMAN@.IP "\-c" 4
- @LCMAN@.IX Item "-c"
+ .IP "\-C \fIfd\fR" 12
+ .IX Item "-C fd"
+ Normally, \fBsudo\fR will close all open file descriptors other than
+ standard input, standard output and standard error.  The \fB\-C\fR
+ (\fIclose from\fR) option allows the user to specify a starting point
+ above the standard error (file descriptor three).  Values less than
+ three are not permitted.  This option is only available if the
+ administrator has enabled the \fIclosefrom_override\fR option in
+ \&\fIsudoers\fR\|(@mansectform@).
+ @LCMAN@.IP "\-c \fIclass\fR" 12
+ @LCMAN@.IX Item "-c class"
  @LCMAN@The \fB\-c\fR (\fIclass\fR) option causes \fBsudo\fR to run the specified command
  @LCMAN@with resources limited by the specified login class.  The \fIclass\fR
- @LCMAN@argument can be either a class name as defined in \f(CW\*(C`/etc/login.conf\*(C'\fR,
+ @LCMAN@argument can be either a class name as defined in \fI/etc/login.conf\fR,
  @LCMAN@or a single '\-' character.  Specifying a \fIclass\fR of \f(CW\*(C`\-\*(C'\fR indicates
  @LCMAN@that the command should be run restricted by the default login
  @LCMAN@capabilities for the user the command is run as.  If the \fIclass\fR
  @LCMAN@argument specifies an existing user class, the command must be run
  @LCMAN@as root, or the \fBsudo\fR command must be run from a shell that is already
  @LCMAN@root.  This option is only available on systems with \s-1BSD\s0 login classes.
- .IP "\-E" 4
+ .IP "\-E" 12
  .IX Item "-E"
  The \fB\-E\fR (\fIpreserve\fR \fIenvironment\fR) option will override the
  \&\fIenv_reset\fR option in \fIsudoers\fR\|(@mansectform@)).  It is only
  available when either the matching command has the \f(CW\*(C`SETENV\*(C'\fR tag
  or the \fIsetenv\fR option is set in \fIsudoers\fR\|(@mansectform@).
- .IP "\-e" 4
+ .IP "\-e" 12
  .IX Item "-e"
  The \fB\-e\fR (\fIedit\fR) option indicates that, instead of running
  a command, the user wishes to edit one or more files.  In lieu
  of a command, the string \*(L"sudoedit\*(R" is used when consulting
  the \fIsudoers\fR file.  If the user is authorized by \fIsudoers\fR
  the following steps are taken:
- .RS 4
+ .RS 12
  .IP "1." 4
  Temporary copies are made of the files to be edited with the owner
  set to the invoking user.
  .IP "2." 4
- The editor specified by the \f(CW\*(C`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR environment
- variables is run to edit the temporary files.  If neither \f(CW\*(C`VISUAL\*(C'\fR
- nor \f(CW\*(C`EDITOR\*(C'\fR are set, the program listed in the \fIeditor\fR \fIsudoers\fR
- variable is used.
+ The editor specified by the \f(CW\*(C`SUDO_EDITOR\*(C'\fR, \f(CW\*(C`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR
+ environment variables is run to edit the temporary files.  If none
+ of \f(CW\*(C`SUDO_EDITOR\*(C'\fR, \f(CW\*(C`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR are set, the first program
listed in the \fIeditor\fR \fIsudoers\fR variable is used.
  .IP "3." 4
  If they have been modified, the temporary files are copied back to
  their original location and the temporary versions are removed.
  .RE
- .RS 4
+ .RS 12
  .Sp
  If the specified file does not exist, it will be created.  Note
  that unlike most commands run by \fBsudo\fR, the editor is run with
@@@ -278,63 -308,85 +308,85 @@@ the invoking user's environment unmodif
  user will receive a warning and the edited copy will remain in a
  temporary file.
  .RE
- .IP "\-H" 4
+ .IP "\-g \fIgroup\fR" 12
+ .IX Item "-g group"
+ Normally, \fBsudo\fR sets the primary group to the one specified by
+ the passwd database for the user the command is being run as (by
+ default, root).  The \fB\-g\fR (\fIgroup\fR) option causes \fBsudo\fR to run
+ the specified command with the primary group set to \fIgroup\fR.  To
+ specify a \fIgid\fR instead of a \fIgroup name\fR, use \fI#gid\fR.  When
+ running commands as a \fIgid\fR, many shells require that the '#' be
+ escaped with a backslash ('\e').  If no \fB\-u\fR option is specified,
+ the command will be run as the invoking user (not root).  In either
+ case, the primary group will be set to \fIgroup\fR.
+ .IP "\-H" 12
  .IX Item "-H"
  The \fB\-H\fR (\fI\s-1HOME\s0\fR) option sets the \f(CW\*(C`HOME\*(C'\fR environment variable
  to the homedir of the target user (root by default) as specified
  in \fIpasswd\fR\|(@mansectform@).  By default, \fBsudo\fR does not modify \f(CW\*(C`HOME\*(C'\fR
  (see \fIset_home\fR and \fIalways_set_home\fR in \fIsudoers\fR\|(@mansectform@)).
- .IP "\-h" 4
+ .IP "\-h" 12
  .IX Item "-h"
  The \fB\-h\fR (\fIhelp\fR) option causes \fBsudo\fR to print a usage message and exit.
- .IP "\-i" 4
- .IX Item "-i"
+ .IP "\-i [command]" 12
+ .IX Item "-i [command]"
  The \fB\-i\fR (\fIsimulate initial login\fR) option runs the shell specified
- in the \fIpasswd\fR\|(@mansectform@) entry of the user that the command is
- being run as.  The command name argument given to the shell begins
- with a `\f(CW\*(C`\-\*(C'\fR' to tell the shell to run as a login shell.  \fBsudo\fR
- attempts to change to that user's home directory before running the
- shell.  It also initializes the environment, leaving \fI\s-1TERM\s0\fR
- unchanged, setting \fI\s-1HOME\s0\fR, \fI\s-1SHELL\s0\fR, \fI\s-1USER\s0\fR, \fI\s-1LOGNAME\s0\fR, and
- \&\fI\s-1PATH\s0\fR, and unsetting all other environment variables.  Note that
- because the shell to use is determined before the \fIsudoers\fR file
- is parsed, a \fIrunas_default\fR setting in \fIsudoers\fR will specify
- the user to run the shell as but will not affect which shell is
- actually run.
- .IP "\-K" 4
+ in the \fIpasswd\fR\|(@mansectform@) entry of the target user as a login shell.  This
+ means that login-specific resource files such as \f(CW\*(C`.profile\*(C'\fR or
+ \&\f(CW\*(C`.login\*(C'\fR will be read by the shell.  If a command is specified,
+ it is passed to the shell for execution.  Otherwise, an interactive
+ shell is executed.  \fBsudo\fR attempts to change to that user's home
+ directory before running the shell.  It also initializes the
+ environment, leaving \fI\s-1DISPLAY\s0\fR and \fI\s-1TERM\s0\fR unchanged, setting
+ \&\fI\s-1HOME\s0\fR, \fI\s-1SHELL\s0\fR, \fI\s-1USER\s0\fR, \fI\s-1LOGNAME\s0\fR, and \fI\s-1PATH\s0\fR, as well as
+ the contents of \fI/etc/environment\fR on Linux and \s-1AIX\s0 systems.
+ All other environment variables are removed.
+ .IP "\-K" 12
  .IX Item "-K"
  The \fB\-K\fR (sure \fIkill\fR) option is like \fB\-k\fR except that it removes
  the user's timestamp entirely.  Like \fB\-k\fR, this option does not
  require a password.
- .IP "\-k" 4
+ .IP "\-k" 12
  .IX Item "-k"
  The \fB\-k\fR (\fIkill\fR) option to \fBsudo\fR invalidates the user's timestamp
  by setting the time on it to the Epoch.  The next time \fBsudo\fR is
  run a password will be required.  This option does not require a password
  and was added to allow a user to revoke \fBsudo\fR permissions from a .logout
  file.
- .IP "\-L" 4
+ .IP "\-L" 12
  .IX Item "-L"
  The \fB\-L\fR (\fIlist\fR defaults) option will list out the parameters
  that may be set in a \fIDefaults\fR line along with a short description
  for each.  This option is useful in conjunction with \fIgrep\fR\|(1).
- .IP "\-l" 4
- .IX Item "-l"
- The \fB\-l\fR (\fIlist\fR) option will list out the allowed (and
- forbidden) commands for the invoking user on the current host.
- .IP "\-P" 4
+ .IP "\-l[l] [\fIcommand\fR]" 12
+ .IX Item "-l[l] [command]"
+ If no \fIcommand\fR is specified, the \fB\-l\fR (\fIlist\fR) option will list
+ the allowed (and forbidden) commands for the invoking user (or the
+ user specified by the \fB\-U\fR option) on the current host.  If a
+ \&\fIcommand\fR is specified and is permitted by \fIsudoers\fR, the
+ fully-qualified path to the command is displayed along with any
+ command line arguments.  If \fIcommand\fR is specified but not allowed,
+ \&\fBsudo\fR will exit with a status value of 1.  If the \fB\-l\fR option is
+ specified with an \fBl\fR argument (i.e. \fB\-ll\fR), or if \fB\-l\fR
+ is specified multiple times, a longer list format is used.
+ .IP "\-n" 12
+ .IX Item "-n"
+ The \fB\-n\fR (\fInon-interactive\fR) option prevents \fBsudo\fR from prompting
+ the user for a password.  If a password is required for the command
+ to run, \fBsudo\fR will display an error messages and exit.
+ .IP "\-P" 12
  .IX Item "-P"
  The \fB\-P\fR (\fIpreserve\fR \fIgroup vector\fR) option causes \fBsudo\fR to
  preserve the invoking user's group vector unaltered.  By default,
  \&\fBsudo\fR will initialize the group vector to the list of groups the
  target user is in.  The real and effective group IDs, however, are
  still set to match the target user.
- .IP "\-p" 4
- .IX Item "-p"
+ .IP "\-p \fIprompt\fR" 12
+ .IX Item "-p prompt"
  The \fB\-p\fR (\fIprompt\fR) option allows you to override the default
  password prompt and use a custom one.  The following percent (`\f(CW\*(C`%\*(C'\fR')
  escapes are supported:
- .RS 4
+ .RS 12
  .ie n .IP "%H" 4
  .el .IP "\f(CW%H\fR" 4
  .IX Item "%H"
@@@ -364,51 -416,62 +416,62 @@@ expanded to the invoking user's login n
  .IX Item "%%"
  two consecutive \f(CW\*(C`%\*(C'\fR characters are collapsed into a single \f(CW\*(C`%\*(C'\fR character
  .RE
- .RS 4
+ .RS 12
+ .Sp
+ The prompt specified by the \fB\-p\fR option will override the system
+ password prompt on systems that support \s-1PAM\s0 unless the
+ \&\fIpassprompt_override\fR flag is disabled in \fIsudoers\fR.
  .RE
- @SEMAN@.IP "\-r" 4
- @SEMAN@.IX Item "-r"
+ @SEMAN@.IP "\-r \fIrole\fR" 12
+ @SEMAN@.IX Item "-r role"
  @SEMAN@The \fB\-r\fR (\fIrole\fR) option causes the new (SELinux) security context to 
  @SEMAN@have the role specified by \fIrole\fR.
- .IP "\-S" 4
+ .IP "\-S" 12
  .IX Item "-S"
  The \fB\-S\fR (\fIstdin\fR) option causes \fBsudo\fR to read the password from
  the standard input instead of the terminal device.
- .IP "\-s" 4
- .IX Item "-s"
+ .IP "\-s [command]" 12
+ .IX Item "-s [command]"
  The \fB\-s\fR (\fIshell\fR) option runs the shell specified by the \fI\s-1SHELL\s0\fR
- environment variable if it is set or the shell as specified
- in \fIpasswd\fR\|(@mansectform@).
- @SEMAN@.IP "\-t" 4
- @SEMAN@.IX Item "-t"
+ environment variable if it is set or the shell as specified in
+ \&\fIpasswd\fR\|(@mansectform@).  If a command is specified, it is passed to the shell
+ for execution.  Otherwise, an interactive shell is executed.
+ @SEMAN@.IP "\-t \fItype\fR" 12
+ @SEMAN@.IX Item "-t type"
  @SEMAN@The \fB\-t\fR (\fItype\fR) option causes the new (SELinux) security context to 
  @SEMAN@have the type specified by \fItype\fR.  If no type is specified, the default
  @SEMAN@type is derived from the specified role.
- .IP "\-u" 4
- .IX Item "-u"
+ .IP "\-U \fIuser\fR" 12
+ .IX Item "-U user"
+ The \fB\-U\fR (\fIother user\fR) option is used in conjunction with the \fB\-l\fR
+ option to specify the user whose privileges should be listed.  Only
+ root or a user with \fBsudo\fR \f(CW\*(C`ALL\*(C'\fR on the current host may use this
+ option.
+ .IP "\-u \fIuser\fR" 12
+ .IX Item "-u user"
  The \fB\-u\fR (\fIuser\fR) option causes \fBsudo\fR to run the specified
  command as a user other than \fIroot\fR.  To specify a \fIuid\fR instead
- of a \fIusername\fR, use \fI#uid\fR.  When running commands as a \fIuid\fR,
+ of a \fIuser name\fR, use \fI#uid\fR.  When running commands as a \fIuid\fR,
  many shells require that the '#' be escaped with a backslash ('\e').
  Note that if the \fItargetpw\fR Defaults option is set (see \fIsudoers\fR\|(@mansectform@))
  it is not possible to run commands with a uid not listed in the
  password database.
- .IP "\-V" 4
+ .IP "\-V" 12
  .IX Item "-V"
  The \fB\-V\fR (\fIversion\fR) option causes \fBsudo\fR to print the version
  number and exit.  If the invoking user is already root the \fB\-V\fR
  option will print out a list of the defaults \fBsudo\fR was compiled
  with as well as the machine's local network addresses.
- .IP "\-v" 4
+ .IP "\-v" 12
  .IX Item "-v"
  If given the \fB\-v\fR (\fIvalidate\fR) option, \fBsudo\fR will update the
  user's timestamp, prompting for the user's password if necessary.
  This extends the \fBsudo\fR timeout for another \f(CW\*(C`@timeout@\*(C'\fR minutes
  (or whatever the timeout is set to in \fIsudoers\fR) but does not run
  a command.
- .IP "\-\-" 4
- The \fB\-\-\fR flag indicates that \fBsudo\fR should stop processing command
- line arguments.  It is most useful in conjunction with the \fB\-s\fR flag.
+ .IP "\-\-" 12
+ The \fB\-\-\fR option indicates that \fBsudo\fR should stop processing command
+ line arguments.  It is most useful in conjunction with the \fB\-s\fR option.
  .PP
  Environment variables to be set for the command may also be passed
  on the command line in the form of \fB\s-1VAR\s0\fR=\fIvalue\fR, e.g.
@@@ -420,8 -483,8 +483,8 @@@ set or the command matched is \f(CW\*(C
  that would overwise be forbidden.  See \fIsudoers\fR\|(@mansectform@) for more information.
  .SH "RETURN VALUES"
  .IX Header "RETURN VALUES"
- Upon successful execution of a program, the return value from \fBsudo\fR
- will simply be the return value of the program that was executed.
+ Upon successful execution of a program, the exit status from \fBsudo\fR
+ will simply be the exit status of the program that was executed.
  .PP
  Otherwise, \fBsudo\fR quits with an exit value of 1 if there is a
  configuration/permission problem or if \fBsudo\fR cannot execute the
@@@ -469,8 -532,8 +532,8 @@@ and, as such, it is not possible for \f
  To prevent command spoofing, \fBsudo\fR checks \*(L".\*(R" and "" (both denoting
  current directory) last when searching for a command in the user's
  \&\s-1PATH\s0 (if one or both are in the \s-1PATH\s0).  Note, however, that the
 -actual \f(CW\*(C`PATH\*(C'\fR environment variable is \fInot\fR modified and is passed
 -unchanged to the program that \fBsudo\fR executes.
 +\&\f(CW\*(C`PATH\*(C'\fR environment variable is further modified in Debian because of
 +the use of the \fI\s-1SECURE_PATH\s0\fR build option.
  .PP
  \&\fBsudo\fR will check the ownership of its timestamp directory
  (\fI@timedir@\fR by default) and ignore the directory's contents if
@@@ -511,7 -574,8 +574,8 @@@ information, please see the \f(CW\*(C`P
  .ie n .IP "\*(C`EDITOR\*(C'" 16
  .el .IP "\f(CW\*(C`EDITOR\*(C'\fR" 16
  .IX Item "EDITOR"
- Default editor to use in \fB\-e\fR (sudoedit) mode if \f(CW\*(C`VISUAL\*(C'\fR is not set
+ Default editor to use in \fB\-e\fR (sudoedit) mode if neither \f(CW\*(C`SUDO_EDITOR\*(C'\fR
+ nor \f(CW\*(C`VISUAL\*(C'\fR is set
  .ie n .IP "\*(C`HOME\*(C'" 16
  .el .IP "\f(CW\*(C`HOME\*(C'\fR" 16
  .IX Item "HOME"
@@@ -525,30 -589,39 +589,39 @@@ Set to a sane value if the \fIsecure_pa
  .el .IP "\f(CW\*(C`SHELL\*(C'\fR" 16
  .IX Item "SHELL"
  Used to determine shell to run with \f(CW\*(C`\-s\*(C'\fR option
- .ie n .IP "\*(C`SUDO_PROMPT\*(C'" 16
- .el .IP "\f(CW\*(C`SUDO_PROMPT\*(C'\fR" 16
- .IX Item "SUDO_PROMPT"
- Used as the default password prompt
+ .ie n .IP "\*(C`SUDO_ASKPASS\*(C'" 16
+ .el .IP "\f(CW\*(C`SUDO_ASKPASS\*(C'\fR" 16
+ .IX Item "SUDO_ASKPASS"
+ Specifies the path to a helper program used to read the password
+ if no terminal is available or if the \f(CW\*(C`\-A\*(C'\fR option is specified.
  .ie n .IP "\*(C`SUDO_COMMAND\*(C'" 16
  .el .IP "\f(CW\*(C`SUDO_COMMAND\*(C'\fR" 16
  .IX Item "SUDO_COMMAND"
  Set to the command run by sudo
- .ie n .IP "\*(C`SUDO_USER\*(C'" 16
- .el .IP "\f(CW\*(C`SUDO_USER\*(C'\fR" 16
- .IX Item "SUDO_USER"
- Set to the login of the user who invoked sudo
- .ie n .IP "\*(C`SUDO_UID\*(C'" 16
- .el .IP "\f(CW\*(C`SUDO_UID\*(C'\fR" 16
- .IX Item "SUDO_UID"
- Set to the uid of the user who invoked sudo
+ .ie n .IP "\*(C`SUDO_EDITOR\*(C'" 16
+ .el .IP "\f(CW\*(C`SUDO_EDITOR\*(C'\fR" 16
+ .IX Item "SUDO_EDITOR"
+ Default editor to use in \fB\-e\fR (sudoedit) mode
  .ie n .IP "\*(C`SUDO_GID\*(C'" 16
  .el .IP "\f(CW\*(C`SUDO_GID\*(C'\fR" 16
  .IX Item "SUDO_GID"
- Set to the gid of the user who invoked sudo
+ Set to the group \s-1ID\s0 of the user who invoked sudo
+ .ie n .IP "\*(C`SUDO_PROMPT\*(C'" 16
+ .el .IP "\f(CW\*(C`SUDO_PROMPT\*(C'\fR" 16
+ .IX Item "SUDO_PROMPT"
+ Used as the default password prompt
  .ie n .IP "\*(C`SUDO_PS1\*(C'" 16
  .el .IP "\f(CW\*(C`SUDO_PS1\*(C'\fR" 16
  .IX Item "SUDO_PS1"
- If set, \f(CW\*(C`PS1\*(C'\fR will be set to its value
+ If set, \f(CW\*(C`PS1\*(C'\fR will be set to its value for the program being run
+ .ie n .IP "\*(C`SUDO_UID\*(C'" 16
+ .el .IP "\f(CW\*(C`SUDO_UID\*(C'\fR" 16
+ .IX Item "SUDO_UID"
+ Set to the user \s-1ID\s0 of the user who invoked sudo
+ .ie n .IP "\*(C`SUDO_USER\*(C'" 16
+ .el .IP "\f(CW\*(C`SUDO_USER\*(C'\fR" 16
+ .IX Item "SUDO_USER"
+ Set to the login of the user who invoked sudo
  .ie n .IP "\*(C`USER\*(C'" 16
  .el .IP "\f(CW\*(C`USER\*(C'\fR" 16
  .IX Item "USER"
@@@ -556,15 -629,21 +629,21 @@@ Set to the target user (root unless th
  .ie n .IP "\*(C`VISUAL\*(C'" 16
  .el .IP "\f(CW\*(C`VISUAL\*(C'\fR" 16
  .IX Item "VISUAL"
- Default editor to use in \fB\-e\fR (sudoedit) mode
+ Default editor to use in \fB\-e\fR (sudoedit) mode if \f(CW\*(C`SUDO_EDITOR\*(C'\fR
+ is not set
  .SH "FILES"
  .IX Header "FILES"
- .IP "\fI@sysconfdir@/sudoers\fR" 24
+ .ie n .IP "\fI@sysconfdir@/sudoers\fR" 24
+ .el .IP "\fI@sysconfdir@/sudoers\fR" 24
  .IX Item "@sysconfdir@/sudoers"
  List of who can run what
- .IP "\fI@timedir@\fR" 24
+ .ie n .IP "\fI@timedir@\fR" 24
+ .el .IP "\fI@timedir@\fR" 24
  .IX Item "@timedir@"
  Directory containing timestamps
+ .IP "\fI/etc/environment\fR" 24
+ .IX Item "/etc/environment"
+ Initial environment for \fB\-i\fR mode on Linux and \s-1AIX\s0
  .SH "EXAMPLES"
  .IX Header "EXAMPLES"
  Note: the following examples assume suitable \fIsudoers\fR\|(@mansectform@) entries.
@@@ -606,18 -685,13 +685,17 @@@ to make the \f(CW\*(C`cd\*(C'\fR and fi
  \&\fIgrep\fR\|(1), \fIsu\fR\|(1), \fIstat\fR\|(2),
  @LCMAN@\&\fIlogin_cap\fR\|(3),
  \&\fIpasswd\fR\|(@mansectform@), \fIsudoers\fR\|(5), \fIvisudo\fR\|(@mansectsu@)
 +.PP
 +The file /usr/share/doc/sudo/OPTIONS describes the options used for building
 +the Debian version of sudo, some of which change default behaviors documented
 +elsewhere in this document.
  .SH "AUTHORS"
  .IX Header "AUTHORS"
  Many people have worked on \fBsudo\fR over the years; this
  version consists of code written primarily by:
  .PP
- .Vb 2
+ .Vb 1
  \&        Todd C. Miller
- \&        Chris Jepeway
  .Ve
  .PP
  See the \s-1HISTORY\s0 file in the \fBsudo\fR distribution or visit
diff --combined sudo.pod
index 55f4f88bdc102a0e998bc32acca14a4915064b7c,e96f044c0b699bb39273eb03131578afad31be2c..7c4dbaf73028e47240e50ee0f4699c18b3f76ed8
+++ b/sudo.pod
@@@ -1,4 -1,4 +1,4 @@@
- Copyright (c) 1994-1996, 1998-2005, 2007
+ Copyright (c) 1994-1996, 1998-2005, 2007-2008
        Todd C. Miller <Todd.Miller@courtesan.com>
  
  Permission to use, copy, modify, and distribute this software for any
@@@ -18,7 -18,7 +18,7 @@@ Sponsored in part by the Defense Advanc
  Agency (DARPA) and Air Force Research Laboratory, Air Force
  Materiel Command, USAF, under agreement number F39502-99-1-0512.
  
- $Sudo: sudo.pod,v 1.70.2.24 2008/02/19 18:22:11 millert Exp $
+ $Sudo: sudo.pod,v 1.120 2008/11/15 18:34:01 millert Exp $
  =pod
  
  =head1 NAME
@@@ -27,21 -27,26 +27,26 @@@ sudo, sudoedit - execute a command as a
  
  =head1 SYNOPSIS
  
- B<sudo> B<-h> | B<-K> | B<-k> | B<-L> | B<-l> | B<-V> | B<-v>
+ B<sudo> [B<-n>] B<-h> | B<-K> | B<-k> | B<-L> | B<-V> | B<-v>
  
- B<sudo> [B<-bEHPS>]
+ B<sudo> B<-l[l]> [B<-AnS>] S<[B<-g> I<groupname>|I<#gid>]> S<[B<-U> I<username>]>
+ S<[B<-u> I<username>|I<#uid>]> [I<command>]
+ B<sudo> [B<-AbEHnPS>]
  S<[B<-a> I<auth_type>]>
+ S<[B<-C> I<fd>]>
  S<[B<-c> I<class>|I<->]>
- S<[B<-p> I<prompt>]>
+ S<[B<-g> I<groupname>|I<#gid>]> S<[B<-p> I<prompt>]>
  S<[B<-r> I<role>]> S<[B<-t> I<type>]>
  S<[B<-u> I<username>|I<#uid>]>
- S<[B<VAR>=I<value>]> S<{B<-i> | B<-s> | I<command>}>
+ S<[B<VAR>=I<value>]> S<[B<-i> | B<-s>]> [I<command>]
  
- B<sudoedit> [B<-S>]
+ B<sudoedit> [B<-AnS>]
  S<[B<-a> I<auth_type>]>
+ S<[B<-C> I<fd>]>
  S<[B<-c> I<class>|I<->]>
- S<[B<-p> I<prompt>]> S<[B<-u> I<username>|I<#uid>]>
- file ...
+ S<[B<-g> I<groupname>|I<#gid>]> S<[B<-p> I<prompt>]>
S<[B<-u> I<username>|I<#uid>]> file ...
  
  =head1 DESCRIPTION
  
@@@ -63,17 -68,17 +68,17 @@@ When invoked as B<sudoedit>, the B<-e> 
  is implied.
  
  B<sudo> determines who is an authorized user by consulting the file
- F<@sysconfdir@/sudoers>.  By giving B<sudo> the B<-v> flag, a user
- can update the time stamp without running a I<command>. The password
- prompt itself will also time out if the user's password is not
- entered within C<@password_timeout@> minutes (unless overridden via
- I<sudoers>).
+ F<@sysconfdir@/sudoers>.  By running B<sudo> with the B<-v> option,
+ a user can update the time stamp without running a I<command>. The
+ password prompt itself will also time out if the user's password
+ is not entered within C<@password_timeout@> minutes (unless overridden
via I<sudoers>).
  
  If a user who is not listed in the I<sudoers> file tries to run a
  command via B<sudo>, mail is sent to the proper authorities, as
  defined at configure time or in the I<sudoers> file (defaults to
  C<@mailto@>).  Note that the mail will not be sent if an unauthorized
- user tries to run sudo with the B<-l> or B<-v> flags.  This allows
+ user tries to run sudo with the B<-l> or B<-v> option.  This allows
  users to determine for themselves whether or not they are allowed
  to use B<sudo>.
  
@@@ -81,7 -86,7 +86,7 @@@ If B<sudo> is run by root and the C<SUD
  is set, B<sudo> will use this value to determine who the actual
  user is.  This can be used by a user to log commands through sudo
  even when a root shell has been invoked.  It also allows the B<-e>
flag to remain useful even when being run via a sudo-run script or
option to remain useful even when being run via a sudo-run script or
  program.  Note however, that the sudoers lookup is still done for
  root, not the user specified by C<SUDO_USER>.
  
@@@ -94,9 -99,19 +99,19 @@@ or via the I<sudoers> file
  
  B<sudo> accepts the following command line options:
  
- =over 4
+ =over 12
+ =item -A
  
- =item -a
+ Normally, if B<sudo> requires a password, it will read it from the
+ current terminal.  If the B<-A> (I<askpass>) option is specified,
+ a helper program is executed to read the user's password and output
+ the password to the standard output.  If the C<SUDO_ASKPASS>
+ environment variable is set, it specifies the path to the helper
+ program.  Otherwise, the value specified by the I<askpass> option
+ in L<sudoers(5)> is used.
+ =item -a I<type>
  
  The B<-a> (I<authentication type>) option causes B<sudo> to use the
  specified authentication type when validating the user, as allowed
@@@ -111,11 -126,21 +126,21 @@@ The B<-b> (I<background>) option tells 
  command in the background.  Note that if you use the B<-b>
  option you cannot use shell job control to manipulate the process.
  
- =item -c
+ =item -C I<fd>
+ Normally, B<sudo> will close all open file descriptors other than
+ standard input, standard output and standard error.  The B<-C>
+ (I<close from>) option allows the user to specify a starting point
+ above the standard error (file descriptor three).  Values less than
+ three are not permitted.  This option is only available if the
+ administrator has enabled the I<closefrom_override> option in
+ L<sudoers(5)>.
+ =item -c I<class>
  
  The B<-c> (I<class>) option causes B<sudo> to run the specified command
  with resources limited by the specified login class.  The I<class>
- argument can be either a class name as defined in C</etc/login.conf>,
+ argument can be either a class name as defined in F</etc/login.conf>,
  or a single '-' character.  Specifying a I<class> of C<-> indicates
  that the command should be run restricted by the default login
  capabilities for the user the command is run as.  If the I<class>
@@@ -147,10 -172,10 +172,10 @@@ set to the invoking user
  
  =item 2.
  
- The editor specified by the C<VISUAL> or C<EDITOR> environment
- variables is run to edit the temporary files.  If neither C<VISUAL>
- nor C<EDITOR> are set, the program listed in the I<editor> I<sudoers>
- variable is used.
+ The editor specified by the C<SUDO_EDITOR>, C<VISUAL> or C<EDITOR>
+ environment variables is run to edit the temporary files.  If none
+ of C<SUDO_EDITOR>, C<VISUAL> or C<EDITOR> are set, the first program
listed in the I<editor> I<sudoers> variable is used.
  
  =item 3.
  
@@@ -166,6 -191,18 +191,18 @@@ B<sudo> is unable to update a file wit
  user will receive a warning and the edited copy will remain in a
  temporary file.
  
+ =item -g I<group>
+ Normally, B<sudo> sets the primary group to the one specified by
+ the passwd database for the user the command is being run as (by
+ default, root).  The B<-g> (I<group>) option causes B<sudo> to run
+ the specified command with the primary group set to I<group>.  To
+ specify a I<gid> instead of a I<group name>, use I<#gid>.  When
+ running commands as a I<gid>, many shells require that the '#' be
+ escaped with a backslash ('\').  If no B<-u> option is specified,
+ the command will be run as the invoking user (not root).  In either
+ case, the primary group will be set to I<group>.
  =item -H
  
  The B<-H> (I<HOME>) option sets the C<HOME> environment variable
@@@ -177,20 -214,19 +214,19 @@@ in passwd(5).  By default, B<sudo> doe
  
  The B<-h> (I<help>) option causes B<sudo> to print a usage message and exit.
  
- =item -i
+ =item -i [command]
  
  The B<-i> (I<simulate initial login>) option runs the shell specified
- in the L<passwd(5)> entry of the user that the command is
- being run as.  The command name argument given to the shell begins
- with a `C<->' to tell the shell to run as a login shell.  B<sudo>
- attempts to change to that user's home directory before running the
- shell.  It also initializes the environment, leaving I<TERM>
- unchanged, setting I<HOME>, I<SHELL>, I<USER>, I<LOGNAME>, and
- I<PATH>, and unsetting all other environment variables.  Note that
- because the shell to use is determined before the I<sudoers> file
- is parsed, a I<runas_default> setting in I<sudoers> will specify
- the user to run the shell as but will not affect which shell is
- actually run.
+ in the L<passwd(5)> entry of the target user as a login shell.  This
+ means that login-specific resource files such as C<.profile> or
+ C<.login> will be read by the shell.  If a command is specified,
+ it is passed to the shell for execution.  Otherwise, an interactive
+ shell is executed.  B<sudo> attempts to change to that user's home
+ directory before running the shell.  It also initializes the
+ environment, leaving I<DISPLAY> and I<TERM> unchanged, setting
+ I<HOME>, I<SHELL>, I<USER>, I<LOGNAME>, and I<PATH>, as well as
+ the contents of F</etc/environment> on Linux and AIX systems.
+ All other environment variables are removed.
  
  =item -K
  
@@@ -212,10 -248,23 +248,23 @@@ The B<-L> (I<list> defaults) option wil
  that may be set in a I<Defaults> line along with a short description
  for each.  This option is useful in conjunction with L<grep(1)>.
  
- =item -l
+ =item -l[l] [I<command>]
  
- The B<-l> (I<list>) option will list out the allowed (and
- forbidden) commands for the invoking user on the current host.
+ If no I<command> is specified, the B<-l> (I<list>) option will list
+ the allowed (and forbidden) commands for the invoking user (or the
+ user specified by the B<-U> option) on the current host.  If a
+ I<command> is specified and is permitted by I<sudoers>, the
+ fully-qualified path to the command is displayed along with any
+ command line arguments.  If I<command> is specified but not allowed,
+ B<sudo> will exit with a status value of 1.  If the B<-l> option is
+ specified with an B<l> argument (i.e. B<-ll>), or if B<-l>
+ is specified multiple times, a longer list format is used.
+ =item -n
+ The B<-n> (I<non-interactive>) option prevents B<sudo> from prompting
+ the user for a password.  If a password is required for the command
+ to run, B<sudo> will display an error messages and exit.
  
  =item -P
  
@@@ -225,7 -274,7 +274,7 @@@ B<sudo> will initialize the group vecto
  target user is in.  The real and effective group IDs, however, are
  still set to match the target user.
  
- =item -p
+ =item -p I<prompt>
  
  The B<-p> (I<prompt>) option allows you to override the default
  password prompt and use a custom one.  The following percent (`C<%>')
@@@ -263,7 -312,11 +312,11 @@@ two consecutive C<%> characters are col
  
  =back
  
- =item -r
+ The prompt specified by the B<-p> option will override the system
+ password prompt on systems that support PAM unless the
+ I<passprompt_override> flag is disabled in I<sudoers>.
+ =item -r I<role>
  
  The B<-r> (I<role>) option causes the new (SELinux) security context to 
  have the role specified by I<role>.
  The B<-S> (I<stdin>) option causes B<sudo> to read the password from
  the standard input instead of the terminal device.
  
- =item -s
+ =item -s [command]
  
  The B<-s> (I<shell>) option runs the shell specified by the I<SHELL>
- environment variable if it is set or the shell as specified
- in L<passwd(5)>.
+ environment variable if it is set or the shell as specified in
+ L<passwd(5)>.  If a command is specified, it is passed to the shell
+ for execution.  Otherwise, an interactive shell is executed.
  
- =item -t
+ =item -t I<type>
  
  The B<-t> (I<type>) option causes the new (SELinux) security context to 
  have the type specified by I<type>.  If no type is specified, the default
  type is derived from the specified role.
  
- =item -u
+ =item -U I<user>
+ The B<-U> (I<other user>) option is used in conjunction with the B<-l>
+ option to specify the user whose privileges should be listed.  Only
+ root or a user with B<sudo> C<ALL> on the current host may use this
+ option.
+ =item -u I<user>
  
  The B<-u> (I<user>) option causes B<sudo> to run the specified
  command as a user other than I<root>.  To specify a I<uid> instead
- of a I<username>, use I<#uid>.  When running commands as a I<uid>,
+ of a I<user name>, use I<#uid>.  When running commands as a I<uid>,
  many shells require that the '#' be escaped with a backslash ('\').
  Note that if the I<targetpw> Defaults option is set (see L<sudoers(5)>)
  it is not possible to run commands with a uid not listed in the
@@@ -312,8 -373,8 +373,8 @@@ a command
  
  =item --
  
- The B<--> flag indicates that B<sudo> should stop processing command
- line arguments.  It is most useful in conjunction with the B<-s> flag.
+ The B<--> option indicates that B<sudo> should stop processing command
+ line arguments.  It is most useful in conjunction with the B<-s> option.
  
  =back
  
@@@ -328,8 -389,8 +389,8 @@@ that would overwise be forbidden.  See 
  
  =head1 RETURN VALUES
  
- Upon successful execution of a program, the return value from B<sudo>
- will simply be the return value of the program that was executed.
+ Upon successful execution of a program, the exit status from B<sudo>
+ will simply be the exit status of the program that was executed.
  
  Otherwise, B<sudo> quits with an exit value of 1 if there is a
  configuration/permission problem or if B<sudo> cannot execute the
@@@ -378,8 -439,8 +439,8 @@@ and, as such, it is not possible for B<
  To prevent command spoofing, B<sudo> checks "." and "" (both denoting
  current directory) last when searching for a command in the user's
  PATH (if one or both are in the PATH).  Note, however, that the
 -actual C<PATH> environment variable is I<not> modified and is passed
 -unchanged to the program that B<sudo> executes.
 +C<PATH> environment variable is further modified in Debian because of
 +the use of the I<SECURE_PATH> build option.
  
  B<sudo> will check the ownership of its timestamp directory
  (F<@timedir@> by default) and ignore the directory's contents if
@@@ -423,7 -484,8 +484,8 @@@ B<sudo> utilizes the following environm
  
  =item C<EDITOR>
  
- Default editor to use in B<-e> (sudoedit) mode if C<VISUAL> is not set
+ Default editor to use in B<-e> (sudoedit) mode if neither C<SUDO_EDITOR>
+ nor C<VISUAL> is set
  
  =item C<HOME>
  
@@@ -438,29 -500,38 +500,38 @@@ Set to a sane value if the I<secure_pat
  
  Used to determine shell to run with C<-s> option
  
- =item C<SUDO_PROMPT>
+ =item C<SUDO_ASKPASS>
  
- Used as the default password prompt
+ Specifies the path to a helper program used to read the password
+ if no terminal is available or if the C<-A> option is specified.
  
  =item C<SUDO_COMMAND>
  
  Set to the command run by sudo
  
- =item C<SUDO_USER>
+ =item C<SUDO_EDITOR>
  
- Set to the login of the user who invoked sudo
+ Default editor to use in B<-e> (sudoedit) mode
  
- =item C<SUDO_UID>
+ =item C<SUDO_GID>
  
- Set to the uid of the user who invoked sudo
+ Set to the group ID of the user who invoked sudo
  
- =item C<SUDO_GID>
+ =item C<SUDO_PROMPT>
  
- Set to the gid of the user who invoked sudo
+ Used as the default password prompt
  
  =item C<SUDO_PS1>
  
- If set, C<PS1> will be set to its value
+ If set, C<PS1> will be set to its value for the program being run
+ =item C<SUDO_UID>
+ Set to the user ID of the user who invoked sudo
+ =item C<SUDO_USER>
+ Set to the login of the user who invoked sudo
  
  =item C<USER>
  
@@@ -468,7 -539,8 +539,8 @@@ Set to the target user (root unless th
  
  =item C<VISUAL>
  
- Default editor to use in B<-e> (sudoedit) mode
+ Default editor to use in B<-e> (sudoedit) mode if C<SUDO_EDITOR>
+ is not set
  
  =back
  
@@@ -484,6 -556,10 +556,10 @@@ List of who can run wha
  
  Directory containing timestamps
  
+ =item F</etc/environment>
+ Initial environment for B<-i> mode on Linux and AIX
  =back
  
  =head1 EXAMPLES
@@@ -519,17 -595,12 +595,16 @@@ L<grep(1)>, L<su(1)>, L<stat(2)>
  L<login_cap(3)>,
  L<passwd(5)>, L<sudoers(5)>, L<visudo(8)>
  
 +The file /usr/share/doc/sudo/OPTIONS describes the options used for building
 +the Debian version of sudo, some of which change default behaviors documented
 +elsewhere in this document.
 +
  =head1 AUTHORS
  
  Many people have worked on B<sudo> over the years; this
  version consists of code written primarily by:
  
        Todd C. Miller
-       Chris Jepeway
  
  See the HISTORY file in the B<sudo> distribution or visit
  http://www.sudo.ws/sudo/history.html for a short history
diff --combined sudoers.man.in
index 19ebe5e4ba54b05b9075472c7352135d901e3658,533c8c70ce76d19160226e10e25d43b7c96edc5b..079adffb80f0560eb72d57180acdc2dbc2bffdd3
@@@ -1,4 -1,4 +1,4 @@@
- .\" Copyright (c) 1994-1996, 1998-2005, 2007
+ .\" Copyright (c) 1994-1996, 1998-2005, 2007-2008
  .\"   Todd C. Miller <Todd.Miller@courtesan.com>
  .\" 
  .\" Permission to use, copy, modify, and distribute this software for any
@@@ -18,8 -18,8 +18,8 @@@
  .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
  .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
  .\" 
- .\" $Sudo: sudoers.man.in,v 1.45.2.29 2008/06/22 20:29:03 millert Exp $
- .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+ .\" $Sudo: sudoers.man.in,v 1.74 2008/12/03 20:58:41 millert Exp $
+ .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
  .\"
  .\" Standard preamble:
  .\" ========================================================================
  ..
  .\" Set up some character translations and predefined strings.  \*(-- will
  .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
- .\" double quote, and \*(R" will give a right double quote.  | will give a
- .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
- .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
- .\" expand to `' in nroff, nothing in troff, for use with C<>.
- .tr \(*W-|\(bv\*(Tr
+ .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+ .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+ .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+ .\" nothing in troff, for use with C<>.
+ .tr \(*W-
  .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
  .ie n \{\
  .    ds -- \(*W-
  .    ds R" ''
  'br\}
  .\"
+ .\" Escape single quotes in literal strings from groff's Unicode transform.
+ .ie \n(.g .ds Aq \(aq
+ .el       .ds Aq '
+ .\"
  .\" If the F register is turned on, we'll generate index entries on stderr for
  .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
  .\" entries marked with X<> in POD.  Of course, you'll have to process the
  .\" output yourself in some meaningful fashion.
- .if \nF \{\
+ .ie \nF \{\
  .    de IX
  .    tm Index:\\$1\t\\n%\t"\\$2"
  ..
  .    nr % 0
  .    rr F
  .\}
- .\"
- .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
- .\" way too many mistakes in technical documents.
- .hy 0
- .if n .na
+ .el \{\
+ .    de IX
+ ..
+ .\}
  .\"
  .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
  .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
  .\" ========================================================================
  .\"
  .IX Title "SUDOERS @mansectform@"
- .TH SUDOERS @mansectform@ "Jun 21, 2008" "1.6.9p17" "MAINTENANCE COMMANDS"
+ .TH SUDOERS @mansectform@ "December  3, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+ .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+ .\" way too many mistakes in technical documents.
+ .if n .ad l
+ .nh
  .SH "NAME"
  sudoers \- list of which users may execute what
  .SH "DESCRIPTION"
@@@ -205,30 -212,20 +212,20 @@@ There are four kinds of aliases: \f(CW\
  \&\f(CW\*(C`Host_Alias\*(C'\fR and \f(CW\*(C`Cmnd_Alias\*(C'\fR.
  .PP
  .Vb 4
- \& Alias ::= 'User_Alias'  User_Alias (':' User_Alias)* |
- \&           'Runas_Alias' Runas_Alias (':' Runas_Alias)* |
- \&           'Host_Alias'  Host_Alias (':' Host_Alias)* |
- \&           'Cmnd_Alias'  Cmnd_Alias (':' Cmnd_Alias)*
- .Ve
- .PP
- .Vb 1
- \& User_Alias ::= NAME '=' User_List
- .Ve
- .PP
- .Vb 1
- \& Runas_Alias ::= NAME '=' Runas_List
- .Ve
- .PP
- .Vb 1
- \& Host_Alias ::= NAME '=' Host_List
- .Ve
- .PP
- .Vb 1
- \& Cmnd_Alias ::= NAME '=' Cmnd_List
- .Ve
- .PP
- .Vb 1
- \& NAME ::= [A-Z]([A-Z][0-9]_)*
+ \& Alias ::= \*(AqUser_Alias\*(Aq  User_Alias (\*(Aq:\*(Aq User_Alias)* |
+ \&           \*(AqRunas_Alias\*(Aq Runas_Alias (\*(Aq:\*(Aq Runas_Alias)* |
+ \&           \*(AqHost_Alias\*(Aq  Host_Alias (\*(Aq:\*(Aq Host_Alias)* |
+ \&           \*(AqCmnd_Alias\*(Aq  Cmnd_Alias (\*(Aq:\*(Aq Cmnd_Alias)*
+ \&
+ \& User_Alias ::= NAME \*(Aq=\*(Aq User_List
+ \&
+ \& Runas_Alias ::= NAME \*(Aq=\*(Aq Runas_List
+ \&
+ \& Host_Alias ::= NAME \*(Aq=\*(Aq Host_List
+ \&
+ \& Cmnd_Alias ::= NAME \*(Aq=\*(Aq Cmnd_List
+ \&
+ \& NAME ::= [A\-Z]([A\-Z][0\-9]_)*
  .Ve
  .PP
  Each \fIalias\fR definition is of the form
@@@ -251,54 -248,48 +248,48 @@@ The definitions of what constitutes a v
  .PP
  .Vb 2
  \& User_List ::= User |
- \&               User ',' User_List
+ \&               User \*(Aq,\*(Aq User_List
+ \&
+ \& User ::= \*(Aq!\*(Aq* username |
+ \&          \*(Aq!\*(Aq* \*(Aq#\*(Aquid |
+ \&          \*(Aq!\*(Aq* \*(Aq%\*(Aqgroup |
+ \&          \*(Aq!\*(Aq* \*(Aq+\*(Aqnetgroup |
+ \&          \*(Aq!\*(Aq* User_Alias
  .Ve
  .PP
- .Vb 4
- \& User ::= '!'* username |
- \&          '!'* '%'group |
- \&          '!'* '+'netgroup |
- \&          '!'* User_Alias
- .Ve
- .PP
- A \f(CW\*(C`User_List\*(C'\fR is made up of one or more usernames, system groups
- (prefixed with '%'), netgroups (prefixed with '+') and other aliases.
- Each list item may be prefixed with one or more '!' operators.
- An odd number of '!' operators negate the value of the item; an even
- number just cancel each other out.
+ A \f(CW\*(C`User_List\*(C'\fR is made up of one or more usernames, uids (prefixed
+ with '#'), system groups (prefixed with '%'), netgroups (prefixed
+ with '+') and \f(CW\*(C`User_Alias\*(C'\fRes.  Each list item may be prefixed with
+ zero or more '!' operators.  An odd number of '!' operators negate
+ the value of the item; an even number just cancel each other out.
  .PP
  .Vb 2
- \& Runas_List ::= Runas_User |
- \&                Runas_User ',' Runas_List
- .Ve
- .PP
- .Vb 5
- \& Runas_User ::= '!'* username |
- \&                '!'* '#'uid |
- \&                '!'* '%'group |
- \&                '!'* +netgroup |
- \&                '!'* Runas_Alias
+ \& Runas_List ::= Runas_Member |
+ \&                Runas_Member \*(Aq,\*(Aq Runas_List
+ \&
+ \& Runas_Member ::= \*(Aq!\*(Aq* username |
+ \&                  \*(Aq!\*(Aq* \*(Aq#\*(Aquid |
+ \&                  \*(Aq!\*(Aq* \*(Aq%\*(Aqgroup |
+ \&                  \*(Aq!\*(Aq* +netgroup |
+ \&                  \*(Aq!\*(Aq* Runas_Alias
  .Ve
  .PP
- A \f(CW\*(C`Runas_List\*(C'\fR is similar to a \f(CW\*(C`User_List\*(C'\fR except that it can
- also contain uids (prefixed with '#') and instead of \f(CW\*(C`User_Alias\*(C'\fRes
- it can contain \f(CW\*(C`Runas_Alias\*(C'\fRes.  Note that usernames and groups
- are matched as strings.  In other words, two users (groups) with
- the same uid (gid) are considered to be distinct.  If you wish to
- match all usernames with the same uid (e.g.\ root and toor), you
- can use a uid instead (#0 in the example given).
+ A \f(CW\*(C`Runas_List\*(C'\fR is similar to a \f(CW\*(C`User_List\*(C'\fR except that instead
+ of \f(CW\*(C`User_Alias\*(C'\fRes it can contain \f(CW\*(C`Runas_Alias\*(C'\fRes.  Note that
+ usernames and groups are matched as strings.  In other words, two
+ users (groups) with the same uid (gid) are considered to be distinct.
+ If you wish to match all usernames with the same uid (e.g.\ root
+ and toor), you can use a uid instead (#0 in the example given).
  .PP
  .Vb 2
  \& Host_List ::= Host |
- \&               Host ',' Host_List
- .Ve
- .PP
- .Vb 5
- \& Host ::= '!'* hostname |
- \&          '!'* ip_addr |
- \&          '!'* network(/netmask)? |
- \&          '!'* '+'netgroup |
- \&          '!'* Host_Alias
+ \&               Host \*(Aq,\*(Aq Host_List
+ \&
+ \& Host ::= \*(Aq!\*(Aq* hostname |
+ \&          \*(Aq!\*(Aq* ip_addr |
+ \&          \*(Aq!\*(Aq* network(/netmask)? |
+ \&          \*(Aq!\*(Aq* \*(Aq+\*(Aqnetgroup |
+ \&          \*(Aq!\*(Aq* Host_Alias
  .Ve
  .PP
  A \f(CW\*(C`Host_List\*(C'\fR is made up of one or more hostnames, \s-1IP\s0 addresses,
@@@ -318,20 -309,16 +309,16 @@@ wildcards to be useful
  .PP
  .Vb 2
  \& Cmnd_List ::= Cmnd |
- \&               Cmnd ',' Cmnd_List
- .Ve
- .PP
- .Vb 3
+ \&               Cmnd \*(Aq,\*(Aq Cmnd_List
+ \&
  \& commandname ::= filename |
  \&                 filename args |
- \&                 filename '""'
- .Ve
- .PP
- .Vb 4
- \& Cmnd ::= '!'* commandname |
- \&          '!'* directory |
- \&          '!'* "sudoedit" |
- \&          '!'* Cmnd_Alias
+ \&                 filename \*(Aq""\*(Aq
+ \&
+ \& Cmnd ::= \*(Aq!\*(Aq* commandname |
+ \&          \*(Aq!\*(Aq* directory |
+ \&          \*(Aq!\*(Aq* "sudoedit" |
+ \&          \*(Aq!\*(Aq* Cmnd_Alias
  .Ve
  .PP
  A \f(CW\*(C`Cmnd_List\*(C'\fR is a list of one or more commandnames, directories, and other
@@@ -350,7 -337,7 +337,7 @@@ in the \f(CW\*(C`Cmnd\*(C'\fR must matc
  (or match the wildcards if there are any).  Note that the following
  characters must be escaped with a '\e' if they are used in command
  arguments: ',', ':', '=', '\e'.  The special command \f(CW"sudoedit"\fR
- is used to permit a user to run \fBsudo\fR with the \fB\-e\fR flag (or
+ is used to permit a user to run \fBsudo\fR with the \fB\-e\fR option (or
  as \fBsudoedit\fR).  It may take command line arguments just as
  a normal command does.
  .Sh "Defaults"
  Certain configuration options may be changed from their default
  values at runtime via one or more \f(CW\*(C`Default_Entry\*(C'\fR lines.  These
  may affect all users on any host, all users on a specific host, a
- specific user, or commands being run as a specific user.
+ specific user, a specific command, or commands being run as a specific user.
+ Note that per-command entries may not include command line arguments.
+ If you need to specify arguments, define a \f(CW\*(C`Cmnd_Alias\*(C'\fR and reference
+ that instead.
  .PP
- .Vb 4
- \& Default_Type ::= 'Defaults' |
- \&                  'Defaults' '@' Host_List |
- \&                  'Defaults' ':' User_List |
- \&                  'Defaults' '>' Runas_List
- .Ve
- .PP
- .Vb 1
+ .Vb 5
+ \& Default_Type ::= \*(AqDefaults\*(Aq |
+ \&                  \*(AqDefaults\*(Aq \*(Aq@\*(Aq Host_List |
+ \&                  \*(AqDefaults\*(Aq \*(Aq:\*(Aq User_List |
+ \&                  \*(AqDefaults\*(Aq \*(Aq!\*(Aq Cmnd_List |
+ \&                  \*(AqDefaults\*(Aq \*(Aq>\*(Aq Runas_List
+ \&
  \& Default_Entry ::= Default_Type Parameter_List
- .Ve
- .PP
- .Vb 2
+ \&
  \& Parameter_List ::= Parameter |
- \&                    Parameter ',' Parameter_List
- .Ve
- .PP
- .Vb 4
- \& Parameter ::= Parameter '=' Value |
- \&               Parameter '+=' Value |
- \&               Parameter '-=' Value |
- \&               '!'* Parameter
+ \&                    Parameter \*(Aq,\*(Aq Parameter_List
+ \&
+ \& Parameter ::= Parameter \*(Aq=\*(Aq Value |
+ \&               Parameter \*(Aq+=\*(Aq Value |
+ \&               Parameter \*(Aq\-=\*(Aq Value |
+ \&               \*(Aq!\*(Aq* Parameter
  .Ve
  .PP
  Parameters may be \fBflags\fR, \fBinteger\fR values, \fBstrings\fR, or \fBlists\fR.
@@@ -395,30 -380,26 +380,26 @@@ These operators are used to add to and 
  It is not an error to use the \f(CW\*(C`\-=\*(C'\fR operator to remove an element
  that does not exist in a list.
  .PP
+ Defaults entries are parsed in the following order: generic, host
+ and user Defaults first, then runas Defaults and finally command
+ defaults.
+ .PP
  See \*(L"\s-1SUDOERS\s0 \s-1OPTIONS\s0\*(R" for a list of supported Defaults parameters.
  .Sh "User Specification"
  .IX Subsection "User Specification"
  .Vb 2
- \& User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
- \&               (':' Host_List '=' Cmnd_Spec_List)*
- .Ve
- .PP
- .Vb 2
+ \& User_Spec ::= User_List Host_List \*(Aq=\*(Aq Cmnd_Spec_List \e
+ \&               (\*(Aq:\*(Aq Host_List \*(Aq=\*(Aq Cmnd_Spec_List)*
+ \&
  \& Cmnd_Spec_List ::= Cmnd_Spec |
- \&                    Cmnd_Spec ',' Cmnd_Spec_List
- .Ve
- .PP
- .Vb 1
+ \&                    Cmnd_Spec \*(Aq,\*(Aq Cmnd_Spec_List
+ \&
  \& Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
- .Ve
- .PP
- .Vb 1
- \& Runas_Spec ::= '(' Runas_List ')'
- .Ve
- .PP
- .Vb 2
- \& Tag_Spec ::= ('NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' |
- \&               'SETENV:' | 'NOSETENV:')
+ \&
+ \& Runas_Spec ::= \*(Aq(\*(Aq Runas_List? (: Runas_List)? \*(Aq)\*(Aq
+ \&
+ \& Tag_Spec ::= (\*(AqNOPASSWD:\*(Aq | \*(AqPASSWD:\*(Aq | \*(AqNOEXEC:\*(Aq | \*(AqEXEC:\*(Aq |
+ \&               \*(AqSETENV:\*(Aq | \*(AqNOSETENV:\*(Aq )
  .Ve
  .PP
  A \fBuser specification\fR determines which commands a user may run
@@@ -428,11 -409,24 +409,24 @@@ run as \fBroot\fR, but this can be chan
  Let's break that down into its constituent parts:
  .Sh "Runas_Spec"
  .IX Subsection "Runas_Spec"
- A \f(CW\*(C`Runas_Spec\*(C'\fR is simply a \f(CW\*(C`Runas_List\*(C'\fR (as defined above)
- enclosed in a set of parentheses.  If you do not specify a
- \&\f(CW\*(C`Runas_Spec\*(C'\fR in the user specification, a default \f(CW\*(C`Runas_Spec\*(C'\fR
- of \fBroot\fR will be used.  A \f(CW\*(C`Runas_Spec\*(C'\fR sets the default for
- commands that follow it.  What this means is that for the entry:
+ A \f(CW\*(C`Runas_Spec\*(C'\fR determines the user and/or the group that a command
+ may be run as.  A fully-specified \f(CW\*(C`Runas_Spec\*(C'\fR consists of two
+ \&\f(CW\*(C`Runas_List\*(C'\fRs (as defined above) separated by a colon (':') and
+ enclosed in a set of parentheses.  The first \f(CW\*(C`Runas_List\*(C'\fR indicates
+ which users the command may be run as via \fBsudo\fR's \fB\-u\fR option.
+ The second defines a list of groups that can be specified via
+ \&\fBsudo\fR's \fB\-g\fR option.  If both \f(CW\*(C`Runas_List\*(C'\fRs are specified, the
+ command may be run with any combination of users and groups listed
+ in their respective \f(CW\*(C`Runas_List\*(C'\fRs.  If only the first is specified,
+ the command may be run as any user in the list but no \fB\-g\fR option
+ may be specified.  If the first \f(CW\*(C`Runas_List\*(C'\fR is empty but the
+ second is specified, the command may be run as the invoking user
+ with the group set to any listed in the \f(CW\*(C`Runas_List\*(C'\fR.  If no
+ \&\f(CW\*(C`Runas_Spec\*(C'\fR is specified the command may be run as \fBroot\fR and
+ no group may be specified.
+ .PP
+ A \f(CW\*(C`Runas_Spec\*(C'\fR sets the default for the commands that follow it.
+ What this means is that for the entry:
  .PP
  .Vb 1
  \& dgb    boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
@@@ -442,7 -436,7 +436,7 @@@ The user \fBdgb\fR may run \fI/bin/ls\f
  \&\fI/usr/bin/lprm\fR \*(-- but only as \fBoperator\fR.  E.g.,
  .PP
  .Vb 1
- \& $ sudo -u operator /bin/ls.
+ \& $ sudo \-u operator /bin/ls.
  .Ve
  .PP
  It is also possible to override a \f(CW\*(C`Runas_Spec\*(C'\fR later on in an
@@@ -454,10 -448,27 +448,27 @@@ entry.  If we modify the entry like so
  .PP
  Then user \fBdgb\fR is now allowed to run \fI/bin/ls\fR as \fBoperator\fR,
  but  \fI/bin/kill\fR and \fI/usr/bin/lprm\fR as \fBroot\fR.
+ .PP
+ We can extend this to allow \fBdgb\fR to run \f(CW\*(C`/bin/ls\*(C'\fR with either
+ the user or group set to \fBoperator\fR:
+ .PP
+ .Vb 2
+ \& dgb    boulder = (operator : operator) /bin/ls, (root) /bin/kill, \e
+ \&        /usr/bin/lprm
+ .Ve
+ .PP
+ In the following example, user \fBtcm\fR may run commands that access
+ a modem device file with the dialer group.  Note that in this example
+ only the group will be set, the command still runs as user \fBtcm\fR.
+ .PP
+ .Vb 2
+ \& tcm    boulder = (:dialer) /usr/bin/tip, /usr/bin/cu, \e
+ \&        /usr/local/bin/minicom
+ .Ve
  .Sh "Tag_Spec"
  .IX Subsection "Tag_Spec"
  A command may have zero or more tags associated with it.  There are
six possible tag values, \f(CW\*(C`NOPASSWD\*(C'\fR, \f(CW\*(C`PASSWD\*(C'\fR, \f(CW\*(C`NOEXEC\*(C'\fR, \f(CW\*(C`EXEC\*(C'\fR,
eight possible tag values, \f(CW\*(C`NOPASSWD\*(C'\fR, \f(CW\*(C`PASSWD\*(C'\fR, \f(CW\*(C`NOEXEC\*(C'\fR, \f(CW\*(C`EXEC\*(C'\fR,
  \&\f(CW\*(C`SETENV\*(C'\fR and \f(CW\*(C`NOSETENV\*(C'\fR.
  Once a tag is set on a \f(CW\*(C`Cmnd\*(C'\fR, subsequent \f(CW\*(C`Cmnd\*(C'\fRs in the
  \&\f(CW\*(C`Cmnd_Spec_List\*(C'\fR, inherit the tag unless it is overridden by the
@@@ -479,7 -490,7 +490,7 @@@ For example
  .Ve
  .PP
  would allow the user \fBray\fR to run \fI/bin/kill\fR, \fI/bin/ls\fR, and
- \&\fI/usr/bin/lprm\fR as root on the machine rushmore as \fBroot\fR without
+ \&\fI/usr/bin/lprm\fR as \fBroot\fR on the machine rushmore without
  authenticating himself.  If we only want \fBray\fR to be able to
  run \fI/bin/kill\fR without a password the entry would be:
  .PP
@@@ -528,7 -539,7 +539,7 @@@ be overridden by use of the \f(CW\*(C`U
  .Sh "Wildcards"
  .IX Subsection "Wildcards"
  \&\fBsudo\fR allows shell-style \fIwildcards\fR (aka meta or glob characters)
- to be used in pathnames as well as command line arguments in the
+ to be used in hostnames, pathnames and command line arguments in the
  \&\fIsudoers\fR file.  Wildcard matching is done via the \fB\s-1POSIX\s0\fR
  \&\fIfnmatch\fR\|(3) routine.  Note that these are \fInot\fR regular expressions.
  .ie n .IP "\*(C`*\*(C'" 8
@@@ -553,6 -564,17 +564,17 @@@ Matches any character \fBnot\fR in the 
  For any character \*(L"x\*(R", evaluates to \*(L"x\*(R".  This is used to
  escape special characters such as: \*(L"*\*(R", \*(L"?\*(R", \*(L"[\*(R", and \*(L"}\*(R".
  .PP
+ \&\s-1POSIX\s0 character classes may also be used if your system's
+ \&\fIfnmatch\fR\|(3) function supports them.  However, because the
+ \&\f(CW\*(Aq:\*(Aq\fR character has special meaning in \fIsudoers\fR, it must
+ be escaped.  For example:
+ .PP
+ .Vb 1
+ \&    /bin/ls [[\e:alpha\e:]]*
+ .Ve
+ .PP
+ Would match any filename beginning with a letter.
+ .PP
  Note that a forward slash ('/') will \fBnot\fR be matched by
  wildcards used in the pathname.  When matching the command
  line arguments, however, a slash \fBdoes\fR get matched by
@@@ -572,6 -594,27 +594,27 @@@ The following exceptions apply to the a
  If the empty string \f(CW""\fR is the only command line argument in the
  \&\fIsudoers\fR entry it means that command is not allowed to be run
  with \fBany\fR arguments.
+ .Sh "Including other files from within sudoers"
+ .IX Subsection "Including other files from within sudoers"
+ It is possible to include other \fIsudoers\fR files from within the
+ \&\fIsudoers\fR file currently being parsed using the \f(CW\*(C`#include\*(C'\fR
+ directive, similar to the one used by the C preprocessor.  This is
+ useful, for example, for keeping a site-wide \fIsudoers\fR file in
+ addition to a per-machine local one.  For the sake of this example
+ the site-wide \fIsudoers\fR will be \fI/etc/sudoers\fR and the per-machine
+ one will be \fI/etc/sudoers.local\fR.  To include \fI/etc/sudoers.local\fR
+ from \fI/etc/sudoers\fR we would use the following line in \fI/etc/sudoers\fR:
+ .PP
+ .Vb 1
+ \& #include /etc/sudoers.local
+ .Ve
+ .PP
+ When \fBsudo\fR reaches this line it will suspend processing of the
+ current file (\fI/etc/sudoers\fR) and switch to \fI/etc/sudoers.local\fR.
+ Upon reaching the end of \fI/etc/sudoers.local\fR, the rest of
+ \&\fI/etc/sudoers\fR will be processed.  Files that are included may
+ themselves include other files.  A hard limit of 128 nested include
+ files is enforced to prevent include file loops.
  .Sh "Other special characters and reserved words"
  .IX Subsection "Other special characters and reserved words"
  The pound sign ('#') is used to indicate a comment (unless it is
@@@ -615,7 -658,7 +658,7 @@@ grouped by type, are listed below
  .IX Item "always_set_home"
  If set, \fBsudo\fR will set the \f(CW\*(C`HOME\*(C'\fR environment variable to the home
  directory of the target user (which is root unless the \fB\-u\fR option is used).
- This effectively means that the \fB\-H\fR flag is always implied.
+ This effectively means that the \fB\-H\fR option is always implied.
  This flag is \fIoff\fR by default.
  .IP "authenticate" 16
  .IX Item "authenticate"
@@@ -623,6 -666,11 +666,11 @@@ If set, users must authenticate themsel
  means of authentication) before they may run commands.  This default
  may be overridden via the \f(CW\*(C`PASSWD\*(C'\fR and \f(CW\*(C`NOPASSWD\*(C'\fR tags.
  This flag is \fIon\fR by default.
+ .IP "closefrom_override" 16
+ .IX Item "closefrom_override"
+ If set, the user may use \fBsudo\fR's \fB\-C\fR option which
+ overrides the default starting point at which \fBsudo\fR begins
+ closing open file descriptors.  This flag is \fIoff\fR by default.
  .IP "env_editor" 16
  .IX Item "env_editor"
  If set, \fBvisudo\fR will use the value of the \s-1EDITOR\s0 or \s-1VISUAL\s0
@@@ -640,9 -688,9 +688,9 @@@ If set, \fBsudo\fR will reset the envir
  variables in the caller's environment that match the \f(CW\*(C`env_keep\*(C'\fR
  and \f(CW\*(C`env_check\*(C'\fR lists are then added.  The default contents of the
  \&\f(CW\*(C`env_keep\*(C'\fR and \f(CW\*(C`env_check\*(C'\fR lists are displayed when \fBsudo\fR is
- run by root with the \fI\-V\fR option.  If \fBsudo\fR was compiled with
- the \f(CW\*(C`SECURE_PATH\*(C'\fR option, its value will be used for the \f(CW\*(C`PATH\*(C'\fR
environment variable.  This flag is \fIon\fR by default.
+ run by root with the \fI\-V\fR option.  If the \fIsecure_path\fR option
+ is set, its value will be used for the \f(CW\*(C`PATH\*(C'\fR environment variable.
+ This flag is \fIon\fR by default.
  .IP "fqdn" 16
  .IX Item "fqdn"
  Set this flag if you want to put fully qualified hostnames in the
@@@ -661,10 -709,7 +709,7 @@@ command) is already fully qualified yo
  .IX Item "ignore_dot"
  If set, \fBsudo\fR will ignore '.' or '' (current dir) in the \f(CW\*(C`PATH\*(C'\fR
  environment variable; the \f(CW\*(C`PATH\*(C'\fR itself is not modified.  This
- flag is \fI@ignore_dot@\fR by default.  Currently, while it is possible
- to set \fIignore_dot\fR in \fIsudoers\fR, its value is not used.  This option
- should be considered read-only (it will be fixed in a future version
- of \fBsudo\fR).
+ flag is \fI@ignore_dot@\fR by default.
  .IP "ignore_local_sudoers" 16
  .IX Item "ignore_local_sudoers"
  If set via \s-1LDAP\s0, parsing of \fI@sysconfdir@/sudoers\fR will be skipped.
@@@ -681,11 -726,11 +726,11 @@@ If set, \fBsudo\fR will insult users wh
  password.  This flag is \fI@insults@\fR by default.
  .IP "log_host" 16
  .IX Item "log_host"
- If set, the hostname will be logged in the (non\-syslog) \fBsudo\fR log file.
+ If set, the hostname will be logged in the (non-syslog) \fBsudo\fR log file.
  This flag is \fIoff\fR by default.
  .IP "log_year" 16
  .IX Item "log_year"
- If set, the four-digit year will be logged in the (non\-syslog) \fBsudo\fR log file.
+ If set, the four-digit year will be logged in the (non-syslog) \fBsudo\fR log file.
  This flag is \fIoff\fR by default.
  .IP "long_otp_prompt" 16
  .IX Item "long_otp_prompt"
@@@ -722,7 -767,8 +767,8 @@@ by default
  .IX Item "noexec"
  If set, all commands run via \fBsudo\fR will behave as if the \f(CW\*(C`NOEXEC\*(C'\fR
  tag has been set, unless overridden by a \f(CW\*(C`EXEC\*(C'\fR tag.  See the
- description of \fI\s-1NOEXEC\s0 and \s-1EXEC\s0\fR below as well as the \*(L"\s-1PREVENTING\s0 \s-1SHELL\s0 \s-1ESCAPES\s0\*(R" section at the end of this manual.  This flag is \fIoff\fR by default.
+ description of \fI\s-1NOEXEC\s0 and \s-1EXEC\s0\fR below as well as the \*(L"\s-1PREVENTING\s0 \s-1SHELL\s0
+ \&\s-1ESCAPES\s0\*(R" section at the end of this manual.  This flag is \fIoff\fR by default.
  .IP "path_info" 16
  .IX Item "path_info"
  Normally, \fBsudo\fR will tell the user when a command could not be
@@@ -736,7 -782,7 +782,7 @@@ by default
  .IP "passprompt_override" 16
  .IX Item "passprompt_override"
  The password prompt specified by \fIpassprompt\fR will normally only
 -be used if the passwod prompt provided by systems such as \s-1PAM\s0 matches
 +be used if the password prompt provided by systems such as \s-1PAM\s0 matches
  the string \*(L"Password:\*(R".  If \fIpassprompt_override\fR is set, \fIpassprompt\fR
  will always be used.  This flag is \fIoff\fR by default.
  .IP "preserve_groups" 16
@@@ -749,11 -795,9 +795,9 @@@ user.  This flag is \fIoff\fR by defaul
  .IP "requiretty" 16
  .IX Item "requiretty"
  If set, \fBsudo\fR will only run when the user is logged in to a real
- tty.  This will disallow things like \f(CW"rsh somehost sudo ls"\fR since
- \&\fIrsh\fR\|(1) does not allocate a tty.  Because it is not possible to turn
- off echo when there is no tty present, some sites may wish to set
- this flag to prevent a user from entering a visible password.  This
- flag is \fIoff\fR by default.
+ tty.  When this flag is set, \fBsudo\fR can only be run from a login
+ session and not via other means such as \fIcron\fR\|(@mansectsu@) or cgi-bin scripts.
+ This flag is \fIoff\fR by default.
  .IP "root_sudo" 16
  .IX Item "root_sudo"
  If set, root is allowed to run \fBsudo\fR too.  Disabling this prevents users
@@@ -774,15 -818,15 +818,15 @@@ If set, \fBsudo\fR will prompt for the 
  password of the invoking user.  This flag is \fIoff\fR by default.
  .IP "set_home" 16
  .IX Item "set_home"
- If set and \fBsudo\fR is invoked with the \fB\-s\fR flag the \f(CW\*(C`HOME\*(C'\fR
+ If set and \fBsudo\fR is invoked with the \fB\-s\fR option the \f(CW\*(C`HOME\*(C'\fR
  environment variable will be set to the home directory of the target
  user (which is root unless the \fB\-u\fR option is used).  This effectively
- makes the \fB\-s\fR flag imply \fB\-H\fR.  This flag is \fIoff\fR by default.
+ makes the \fB\-s\fR option imply \fB\-H\fR.  This flag is \fIoff\fR by default.
  .IP "set_logname" 16
  .IX Item "set_logname"
  Normally, \fBsudo\fR will set the \f(CW\*(C`LOGNAME\*(C'\fR, \f(CW\*(C`USER\*(C'\fR and \f(CW\*(C`USERNAME\*(C'\fR
  environment variables to the name of the target user (usually root
- unless the \fB\-u\fR flag is given).  However, since some programs
+ unless the \fB\-u\fR option 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
@@@ -800,7 -844,7 +844,7 @@@ by default
  .IP "shell_noargs" 16
  .IX Item "shell_noargs"
  If set and \fBsudo\fR is invoked with no arguments it acts as if the
- \&\fB\-s\fR flag had been given.  That is, it runs a shell as root (the
+ \&\fB\-s\fR option had been given.  That is, it runs a shell as root (the
  shell is determined by the \f(CW\*(C`SHELL\*(C'\fR environment variable if it is
  set, falling back on the shell listed in the invoking user's
  /etc/passwd entry if not).  This flag is \fIoff\fR by default.
@@@ -817,9 -861,9 +861,9 @@@ function.  This flag is \fIoff\fR by de
  .IP "targetpw" 16
  .IX Item "targetpw"
  If set, \fBsudo\fR will prompt for the password of the user specified by
- the \fB\-u\fR flag (defaults to \f(CW\*(C`root\*(C'\fR) instead of the password of the
+ the \fB\-u\fR option (defaults to \f(CW\*(C`root\*(C'\fR) instead of the password of the
  invoking user.  Note that this precludes the use of a uid not listed
- in the passwd database as an argument to the \fB\-u\fR flag.
+ in the passwd database as an argument to the \fB\-u\fR option.
  This flag is \fIoff\fR by default.
  .IP "tty_tickets" 16
  .IX Item "tty_tickets"
@@@ -833,8 -877,23 +877,23 @@@ This flag is \fI@tty_tickets@\fR by def
  @LCMAN@If set, \fBsudo\fR will apply the defaults specified for the target user's
  @LCMAN@login class if one exists.  Only available if \fBsudo\fR is configured with
  @LCMAN@the \-\-with\-logincap option.  This flag is \fIoff\fR by default.
+ .IP "visiblepw" 16
+ .IX Item "visiblepw"
+ By default, \fBsudo\fR will refuse to run if the user must enter a
+ password but it is not possible to disable echo on the terminal.
+ If the \fIvisiblepw\fR flag is set, \fBsudo\fR will prompt for a password
+ even when it would be visible on the screen.  This makes it possible
+ to run things like \f(CW"rsh somehost sudo ls"\fR since \fIrsh\fR\|(1) does
+ not allocate a tty.  This flag is \fIoff\fR by default.
  .PP
  \&\fBIntegers\fR:
+ .IP "closefrom" 16
+ .IX Item "closefrom"
+ Before it executes a command, \fBsudo\fR will close all open file
+ descriptors other than standard input, standard output and standard
+ error (ie: file descriptors 0\-2).  The \fIclosefrom\fR option can be used
+ to specify a different file descriptor at which to start closing.
+ The default is \f(CW3\fR.
  .IP "passwd_tries" 16
  .IX Item "passwd_tries"
  The number of tries a user gets to enter his/her password before
@@@ -862,7 -921,12 +921,12 @@@ own timestamps via \f(CW\*(C`sudo \-v\*
  .IP "umask" 16
  .IX Item "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 \f(CW\*(C`@sudo_umask@\*(C'\fR.
+ it to 0777 to preserve the user's umask.  The actual umask that is
+ used will be the union of the user's umask and \f(CW\*(C`@sudo_umask@\*(C'\fR.
+ This guarantees that \fBsudo\fR never lowers the umask when running a
+ command.  Note on systems that use \s-1PAM\s0, the default \s-1PAM\s0 configuration
+ may specify its own umask which will override the value set in
+ \&\fIsudoers\fR.
  .PP
  \&\fBStrings\fR:
  .IP "badpass_message" 16
@@@ -917,12 -981,6 +981,12 @@@ be run as (defaults to root
  .el .IP "\f(CW%u\fR" 4
  .IX Item "%u"
  expanded to the invoking user's login name
 +.ie n .IP "%p" 4
 +.el .IP "\f(CW%p\fR" 4
 +.IX Item "%p"
 +expanded to the user whose password is asked for (respects the presence of the
 +rootpw, targetpw or runaspw options in the configuration)
 +
  .ie n .IP "\*(C`%%\*(C'" 4
  .el .IP "\f(CW\*(C`%%\*(C'\fR" 4
  .IX Item "%%"
@@@ -940,7 -998,7 +1004,7 @@@ The default value is \f(CW\*(C`@passpro
  @SEMAN@This option is only available whe \fBsudo\fR is built with SELinux support.
  .IP "runas_default" 16
  .IX Item "runas_default"
- The default user to run commands as if the \fB\-u\fR flag is not specified
+ The default user to run commands as if the \fB\-u\fR option is not specified
  on the command line.  This defaults to \f(CW\*(C`@runas_default@\*(C'\fR.
  Note that if \fIrunas_default\fR is set it \fBmust\fR occur before
  any \f(CW\*(C`Runas_Alias\*(C'\fR specifications.
@@@ -952,6 -1010,11 +1016,11 @@@ Defaults to \f(CW\*(C`@badpri@\*(C'\fR
  .IX Item "syslog_goodpri"
  Syslog priority to use when user authenticates successfully.
  Defaults to \f(CW\*(C`@goodpri@\*(C'\fR.
+ .IP "sudoers_locale" 16
+ .IX Item "sudoers_locale"
+ Locale to use when parsing the sudoers file.  Note that changing
+ the locale may affect how sudoers is interpreted.
+ Defaults to \f(CW"C"\fR.
  .IP "timestampdir" 16
  .IX Item "timestampdir"
  The directory in which \fBsudo\fR stores its timestamp files.
@@@ -968,6 -1031,23 +1037,23 @@@ The default is \f(CW\*(C`root\*(C'\fR
  @SEMAN@This option is only available whe \fBsudo\fR is built with SELinux support.
  .PP
  \&\fBStrings that can be used in a boolean context\fR:
+ .IP "askpass" 12
+ .IX Item "askpass"
+ The \fIaskpass\fR option specifies the fully qualified path to a helper
+ program used to read the user's password when no terminal is
+ available.  This may be the case when \fBsudo\fR is executed from a
+ graphical (as opposed to text-based) application.  The program
+ specified by \fIaskpass\fR should display the argument passed to it
+ as the prompt and write the user's password to the standard output.
+ The value of \fIaskpass\fR may be overridden by the \f(CW\*(C`SUDO_ASKPASS\*(C'\fR
+ environment variable.
+ .IP "env_file" 12
+ .IX Item "env_file"
+ The \fIenv_file\fR options specifies the fully qualified path to a file
+ containing variables to be set in the environment of the program
+ being run.  Entries in this file should be of the form \f(CW\*(C`VARIABLE=value\*(C'\fR.
+ Variables in this file are subject to other \fBsudo\fR environment
+ settings such as \fIenv_keep\fR and \fIenv_check\fR.
  .IP "exempt_group" 12
  .IX Item "exempt_group"
  Users in this group are exempt from password and \s-1PATH\s0 requirements.
@@@ -1001,58 -1081,7 +1087,7 @@@ By default, \fBsudo\fR uses a built-in 
  .IP "listpw" 12
  .IX Item "listpw"
  This option controls when a password will be required when a
- user runs \fBsudo\fR with the \fB\-l\fR flag.  It has the following possible values:
- .RS 12
- .IP "all" 8
- .IX Item "all"
- All the user's \fIsudoers\fR entries for the current host must have
- the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
- .IP "always" 8
- .IX Item "always"
- The user must always enter a password to use the \fB\-l\fR flag.
- .IP "any" 8
- .IX Item "any"
- At least one of the user's \fIsudoers\fR entries for the current host
- must have the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
- .IP "never" 8
- .IX Item "never"
- The user need never enter a password to use the \fB\-l\fR flag.
- .RE
- .RS 12
- .Sp
- If no value is specified, a value of \fIany\fR is implied.
- Negating the option results in a value of \fInever\fR being used.
- The default value is \fIany\fR.
- .RE
- .IP "logfile" 12
- .IX Item "logfile"
- Path to the \fBsudo\fR log file (not the syslog log file).  Setting a path
- turns on logging to a file; negating this option turns it off.
- By default, \fBsudo\fR logs via syslog.
- .IP "mailerflags" 12
- .IX Item "mailerflags"
- Flags to use when invoking mailer. Defaults to \fB\-t\fR.
- .IP "mailerpath" 12
- .IX Item "mailerpath"
- Path to mail program used to send warning mail.
- Defaults to the path to sendmail found at configure time.
- .IP "mailto" 12
- .IX Item "mailto"
- Address to send warning and error mail to.  The address should
- be enclosed in double quotes (\f(CW\*(C`"\*(C'\fR) to protect against \fBsudo\fR
- 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.
- On Debian systems, this is set to the group 'sudo' by default. 
- .IP "syslog" 12
- .IX Item "syslog"
- Syslog facility if syslog is being used for logging (negate to
- disable syslog logging).  Defaults to \f(CW\*(C`@logfac@\*(C'\fR.
- .IP "verifypw" 12
- .IX Item "verifypw"
- This option controls when a password will be required when a user runs
- \&\fBsudo\fR with the \fB\-v\fR flag.  It has the following possible values:
+ user runs \fBsudo\fR with the \fB\-l\fR option.  It has the following possible values:
  .RS 12
  .IP "all" 8
  .IX Item "all"
@@@ -1060,14 -1089,14 +1095,14 @@@ All the user's \fIsudoers\fR entries fo
  the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
  .IP "always" 8
  .IX Item "always"
- The user must always enter a password to use the \fB\-l\fR flag.
+ The user must always enter a password to use the \fB\-l\fR option.
  .IP "any" 8
  .IX Item "any"
  At least one of the user's \fIsudoers\fR entries for the current host
  must have the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
  .IP "never" 8
  .IX Item "never"
- The user need never enter a password to use the \fB\-l\fR flag.
+ The user need never enter a password to use the \fB\-l\fR option.
  .RE
  .RS 12
  .Sp
@@@ -1087,11 -1116,25 +1122,25 @@@ Flags to use when invoking mailer. Defa
  .IX Item "mailerpath"
  Path to mail program used to send warning mail.
  Defaults to the path to sendmail found at configure time.
+ .IP "mailfrom" 12
+ .IX Item "mailfrom"
+ Address to use for the \*(L"from\*(R" address when sending warning and error
+ mail.  The address should be enclosed in double quotes (\f(CW\*(C`"\*(C'\fR) to
+ protect against \fBsudo\fR interpreting the \f(CW\*(C`@\*(C'\fR sign.  Defaults to
+ the name of the user running \fBsudo\fR.
  .IP "mailto" 12
  .IX Item "mailto"
  Address to send warning and error mail to.  The address should
  be enclosed in double quotes (\f(CW\*(C`"\*(C'\fR) to protect against \fBsudo\fR
  interpreting the \f(CW\*(C`@\*(C'\fR sign.  Defaults to \f(CW\*(C`@mailto@\*(C'\fR.
+ .IP "secure_path" 12
+ .IX Item "secure_path"
+ Path used for every command run from \fBsudo\fR.  If you don't trust the
+ people running \fBsudo\fR to have a sane \f(CW\*(C`PATH\*(C'\fR environment variable you may
+ want to use this.  Another use is if you want to have the \*(L"root path\*(R"
+ be separate from the \*(L"user path.\*(R"  Users in the group specified by the
+ \&\fIexempt_group\fR option are not affected by \fIsecure_path\fR.
+ This is not set by default.
  .IP "syslog" 12
  .IX Item "syslog"
  Syslog facility if syslog is being used for logging (negate to
@@@ -1099,7 -1142,7 +1148,7 @@@ disable syslog logging).  Defaults to \
  .IP "verifypw" 12
  .IX Item "verifypw"
  This option controls when a password will be required when a user runs
- \&\fBsudo\fR with the \fB\-v\fR flag.  It has the following possible values:
+ \&\fBsudo\fR with the \fB\-v\fR option.  It has the following possible values:
  .RS 12
  .IP "all" 8
  .IX Item "all"
@@@ -1107,14 -1150,14 +1156,14 @@@ All the user's \fIsudoers\fR entries fo
  the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
  .IP "always" 8
  .IX Item "always"
- The user must always enter a password to use the \fB\-v\fR flag.
+ The user must always enter a password to use the \fB\-v\fR option.
  .IP "any" 8
  .IX Item "any"
  At least one of the user's \fIsudoers\fR entries for the current host
  must have the \f(CW\*(C`NOPASSWD\*(C'\fR flag set to avoid entering a password.
  .IP "never" 8
  .IX Item "never"
- The user need never enter a password to use the \fB\-v\fR flag.
+ The user need never enter a password to use the \fB\-v\fR option.
  .RE
  .RS 12
  .Sp
@@@ -1129,8 -1172,8 +1178,8 @@@ The default value is \fIall\fR
  Environment variables to be removed from the user's environment if
  the variable's value contains \f(CW\*(C`%\*(C'\fR or \f(CW\*(C`/\*(C'\fR characters.  This can
  be used to guard against printf-style format vulnerabilities in
- poorly-written programs.  The argument may be a double\-quoted,
- space-separated list or a single value without double\-quotes.  The
+ poorly-written programs.  The argument may be a double-quoted,
+ space-separated list or a single value without double-quotes.  The
  list can be replaced, added to, deleted from, or disabled by using
  the \f(CW\*(C`=\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, and \f(CW\*(C`!\*(C'\fR operators respectively.  Regardless
  of whether the \f(CW\*(C`env_reset\*(C'\fR option is enabled or disabled, variables
@@@ -1141,8 -1184,8 +1190,8 @@@ the \fI\-V\fR option
  .IP "env_delete" 16
  .IX Item "env_delete"
  Environment variables to be removed from the user's environment.
- The argument may be a double\-quoted, space-separated list or a
- single value without double\-quotes.  The list can be replaced, added
+ The argument may be a double-quoted, space-separated list or a
+ single value without double-quotes.  The list can be replaced, added
  to, deleted from, or disabled by using the \f(CW\*(C`=\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, and
  \&\f(CW\*(C`!\*(C'\fR operators respectively.  The default list of environment
  variables to remove is displayed when \fBsudo\fR is run by root with the
@@@ -1154,8 -1197,8 +1203,8 @@@ as \fBsudo\fR)
  Environment variables to be preserved in the user's environment
  when the \fIenv_reset\fR option is in effect.  This allows fine-grained
  control over the environment \fBsudo\fR\-spawned processes will receive.
- The argument may be a double\-quoted, space-separated list or a
- single value without double\-quotes.  The list can be replaced, added
+ The argument may be a double-quoted, space-separated list or a
+ single value without double-quotes.  The list can be replaced, added
  to, deleted from, or disabled by using the \f(CW\*(C`=\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, and
  \&\f(CW\*(C`!\*(C'\fR operators respectively.  The default list of variables to keep
  is displayed when \fBsudo\fR is run by root with the \fI\-V\fR option.
@@@ -1169,7 -1212,8 +1218,8 @@@ supported: \fBalert\fR, \fBcrit\fR, \fB
  \&\fBnotice\fR, and \fBwarning\fR.
  .SH "FILES"
  .IX Header "FILES"
- .IP "\fI@sysconfdir@/sudoers\fR" 24
+ .ie n .IP "\fI@sysconfdir@/sudoers\fR" 24
+ .el .IP "\fI@sysconfdir@/sudoers\fR" 24
  .IX Item "@sysconfdir@/sudoers"
  List of who can run what
  .IP "\fI/etc/group\fR" 24
@@@ -1180,13 -1224,6 +1230,6 @@@ Local groups fil
  List of network groups
  .SH "EXAMPLES"
  .IX Header "EXAMPLES"
- Since the \fIsudoers\fR file is parsed in a single pass, order is
- important.  In general, you should structure \fIsudoers\fR such that
- the \f(CW\*(C`Host_Alias\*(C'\fR, \f(CW\*(C`User_Alias\*(C'\fR, and \f(CW\*(C`Cmnd_Alias\*(C'\fR specifications
- come first, followed by any \f(CW\*(C`Default_Entry\*(C'\fR lines, and finally the
- \&\f(CW\*(C`Runas_Alias\*(C'\fR and user specifications.  The basic rule of thumb
- is you cannot reference an Alias that has not already been defined.
- .PP
  Below are example \fIsudoers\fR entries.  Admittedly, some of
  these are a bit contrived.  First, we define our \fIaliases\fR:
  .PP
  \& User_Alias     FULLTIMERS = millert, mikef, dowdy
  \& User_Alias     PARTTIMERS = bostley, jwfox, crawl
  \& User_Alias     WEBMASTERS = will, wendy, wim
- .Ve
- .PP
- .Vb 3
+ \&
  \& # Runas alias specification
  \& Runas_Alias    OP = root, operator
  \& Runas_Alias    DB = oracle, sybase
- .Ve
- .PP
- .Vb 9
+ \&
  \& # Host alias specification
  \& Host_Alias     SPARC = bigtime, eclipse, moet, anchor :\e
  \&                SGI = grolsch, dandelion, black :\e
  \& Host_Alias     CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
  \& Host_Alias     SERVERS = master, mail, www, ns
  \& Host_Alias     CDROM = orion, perseus, hercules
- .Ve
- .PP
- .Vb 13
+ \&
  \& # Cmnd alias specification
  \& Cmnd_Alias     DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
  \&                        /usr/sbin/restore, /usr/sbin/rrestore
@@@ -1244,7 -1275,7 +1281,7 @@@ disable shell escapes for the commands 
  (\fI/usr/bin/more\fR, \fI/usr/bin/pg\fR and \fI/usr/bin/less\fR).
  .PP
  .Vb 7
- \& # Override built-in defaults
+ \& # Override built\-in defaults
  \& Defaults               syslog=auth
  \& Defaults>root          !set_logname
  \& Defaults:FULLTIMERS    !lecture
@@@ -1314,7 -1345,7 +1351,7 @@@ directory \fI/usr/oper/bin/\fR
  The user \fBjoe\fR may only \fIsu\fR\|(1) to operator.
  .PP
  .Vb 1
- \& pete           HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
+ \& pete           HPPA = /usr/bin/passwd [A\-Za\-z]*, !/usr/bin/passwd root
  .Ve
  .PP
  The user \fBpete\fR is allowed to change anyone's password except for
@@@ -1351,11 -1382,11 +1388,11 @@@ The user \fBfred\fR can run commands a
  (\fBoracle\fR or \fBsybase\fR) without giving a password.
  .PP
  .Vb 1
- \& john           ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+ \& john           ALPHA = /usr/bin/su [!\-]*, !/usr/bin/su *root*
  .Ve
  .PP
  On the \fI\s-1ALPHA\s0\fR machines, user \fBjohn\fR may su to anyone except root
- but he is not allowed to give \fIsu\fR\|(1) any flags.
+ but he is not allowed to specify any options to the \fIsu\fR\|(1) command.
  .PP
  .Vb 1
  \& jen            ALL, !SERVERS = ALL
@@@ -1396,7 -1427,7 +1433,7 @@@ web pages) or simply \fIsu\fR\|(1) to w
  .PP
  .Vb 2
  \& ALL            CDROM = NOPASSWD: /sbin/umount /CDROM,\e
- \&                /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM
+ \&                /sbin/mount \-o nosuid\e,nodev /dev/cd0a /CDROM
  .Ve
  .PP
  Any user may mount or unmount a CD-ROM on the machines in the \s-1CDROM\s0
@@@ -1452,7 -1483,7 +1489,7 @@@ To tell whether or not \fBsudo\fR suppo
  the following as root:
  .Sp
  .Vb 1
- \&    sudo -V | grep "dummy exec"
+ \&    sudo \-V | grep "dummy exec"
  .Ve
  .Sp
  If the resulting output contains a line that begins with:
  then \fBsudo\fR may be able to replace the exec family of functions
  in the standard library with its own that simply return an error.
  Unfortunately, there is no foolproof way to know whether or not
- \&\fInoexec\fR will work at compile\-time.  \fInoexec\fR should work on
+ \&\fInoexec\fR will work at compile-time.  \fInoexec\fR should work on
  SunOS, Solaris, *BSD, Linux, \s-1IRIX\s0, Tru64 \s-1UNIX\s0, MacOS X, and HP-UX
  11.x.  It is known \fBnot\fR to work on \s-1AIX\s0 and UnixWare.  \fInoexec\fR
  is expected to work on most operating systems that support the
diff --combined sudoers.pod
index 5f25ce3f29b60bcfb6c7a21ef82171a9ea2d27bb,63c49cf7d88e1155f81f3212aa2265aec293e2b9..4d1149c87e3b4955fb1832c7ee0a1d2fbb214809
@@@ -1,4 -1,4 +1,4 @@@
- Copyright (c) 1994-1996, 1998-2005, 2007
+ Copyright (c) 1994-1996, 1998-2005, 2007-2008
        Todd C. Miller <Todd.Miller@courtesan.com>
  
  Permission to use, copy, modify, and distribute this software for any
@@@ -18,7 -18,7 +18,7 @@@ Sponsored in part by the Defense Advanc
  Agency (DARPA) and Air Force Research Laboratory, Air Force
  Materiel Command, USAF, under agreement number F39502-99-1-0512.
  
- $Sudo: sudoers.pod,v 1.95.2.26 2008/02/19 18:13:17 millert Exp $
+ $Sudo: sudoers.pod,v 1.155 2008/12/03 20:57:13 millert Exp $
  =pod
  
  =head1 NAME
@@@ -93,7 -93,7 +93,7 @@@ C<Host_Alias> and C<Cmnd_Alias>
  
   Cmnd_Alias ::= NAME '=' Cmnd_List
  
 - NAME ::= [A-Z]([A-Z][0-9]_)*
 + NAME ::= [A-Z]([a-z][A-Z][0-9]_)*
  
  Each I<alias> definition is of the form
  
@@@ -113,32 -113,32 +113,32 @@@ The definitions of what constitutes a v
               User ',' User_List
  
   User ::= '!'* username |
+         '!'* '#'uid |
          '!'* '%'group |
          '!'* '+'netgroup |
          '!'* User_Alias
  
- A C<User_List> is made up of one or more usernames, system groups
- (prefixed with '%'), netgroups (prefixed with '+') and other aliases.
- Each list item may be prefixed with one or more '!' operators.
- An odd number of '!' operators negate the value of the item; an even
- number just cancel each other out.
-  Runas_List ::= Runas_User |
-               Runas_User ',' Runas_List
-  Runas_User ::= '!'* username |
-               '!'* '#'uid |
-               '!'* '%'group |
-               '!'* +netgroup |
-               '!'* Runas_Alias
- A C<Runas_List> is similar to a C<User_List> except that it can
- also contain uids (prefixed with '#') and instead of C<User_Alias>es
- it can contain C<Runas_Alias>es.  Note that usernames and groups
- are matched as strings.  In other words, two users (groups) with
- the same uid (gid) are considered to be distinct.  If you wish to
- match all usernames with the same uid (e.g.E<nbsp>root and toor), you
- can use a uid instead (#0 in the example given).
+ A C<User_List> is made up of one or more usernames, uids (prefixed
+ with '#'), system groups (prefixed with '%'), netgroups (prefixed
+ with '+') and C<User_Alias>es.  Each list item may be prefixed with
+ zero or more '!' operators.  An odd number of '!' operators negate
+ the value of the item; an even number just cancel each other out.
+  Runas_List ::= Runas_Member |
+               Runas_Member ',' Runas_List
+  Runas_Member ::= '!'* username |
+                 '!'* '#'uid |
+                 '!'* '%'group |
+                 '!'* +netgroup |
+                 '!'* Runas_Alias
+ A C<Runas_List> is similar to a C<User_List> except that instead
+ of C<User_Alias>es it can contain C<Runas_Alias>es.  Note that
+ usernames and groups are matched as strings.  In other words, two
+ users (groups) with the same uid (gid) are considered to be distinct.
+ If you wish to match all usernames with the same uid (e.g.E<nbsp>root
+ and toor), you can use a uid instead (#0 in the example given).
  
   Host_List ::= Host |
               Host ',' Host_List
@@@ -192,7 -192,7 +192,7 @@@ in the C<Cmnd> must match exactly thos
  (or match the wildcards if there are any).  Note that the following
  characters must be escaped with a '\' if they are used in command
  arguments: ',', ':', '=', '\'.  The special command C<"sudoedit">
- is used to permit a user to run B<sudo> with the B<-e> flag (or
+ is used to permit a user to run B<sudo> with the B<-e> option (or
  as B<sudoedit>).  It may take command line arguments just as
  a normal command does.
  
  Certain configuration options may be changed from their default
  values at runtime via one or more C<Default_Entry> lines.  These
  may affect all users on any host, all users on a specific host, a
- specific user, or commands being run as a specific user.
+ specific user, a specific command, or commands being run as a specific user.
+ Note that per-command entries may not include command line arguments.
+ If you need to specify arguments, define a C<Cmnd_Alias> and reference
+ that instead.
  
   Default_Type ::= 'Defaults' |
                  'Defaults' '@' Host_List |
                  'Defaults' ':' User_List |
+                 'Defaults' '!' Cmnd_List |
                  'Defaults' '>' Runas_List
  
   Default_Entry ::= Default_Type Parameter_List
@@@ -230,6 -234,10 +234,10 @@@ These operators are used to add to and 
  It is not an error to use the C<-=> operator to remove an element
  that does not exist in a list.
  
+ Defaults entries are parsed in the following order: generic, host
+ and user Defaults first, then runas Defaults and finally command
+ defaults.
  See L</"SUDOERS OPTIONS"> for a list of supported Defaults parameters.
  
  =head2 User Specification
  
   Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
  
-  Runas_Spec ::= '(' Runas_List ')'
+  Runas_Spec ::= '(' Runas_List? (: Runas_List)? ')'
  
   Tag_Spec ::= ('NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' |
-              'SETENV:' | 'NOSETENV:')
+              'SETENV:' | 'NOSETENV:' )
  
  A B<user specification> determines which commands a user may run
  (and as what user) on specified hosts.  By default, commands are
@@@ -255,11 -263,24 +263,24 @@@ Let's break that down into its constitu
  
  =head2 Runas_Spec
  
- A C<Runas_Spec> is simply a C<Runas_List> (as defined above)
- enclosed in a set of parentheses.  If you do not specify a
- C<Runas_Spec> in the user specification, a default C<Runas_Spec>
- of B<root> will be used.  A C<Runas_Spec> sets the default for
- commands that follow it.  What this means is that for the entry:
+ A C<Runas_Spec> determines the user and/or the group that a command
+ may be run as.  A fully-specified C<Runas_Spec> consists of two
+ C<Runas_List>s (as defined above) separated by a colon (':') and
+ enclosed in a set of parentheses.  The first C<Runas_List> indicates
+ which users the command may be run as via B<sudo>'s B<-u> option.
+ The second defines a list of groups that can be specified via
+ B<sudo>'s B<-g> option.  If both C<Runas_List>s are specified, the
+ command may be run with any combination of users and groups listed
+ in their respective C<Runas_List>s.  If only the first is specified,
+ the command may be run as any user in the list but no B<-g> option
+ may be specified.  If the first C<Runas_List> is empty but the
+ second is specified, the command may be run as the invoking user
+ with the group set to any listed in the C<Runas_List>.  If no
+ C<Runas_Spec> is specified the command may be run as B<root> and
+ no group may be specified.
+ A C<Runas_Spec> sets the default for the commands that follow it.
+ What this means is that for the entry:
  
   dgb  boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
  
@@@ -276,10 -297,23 +297,23 @@@ entry.  If we modify the entry like so
  Then user B<dgb> is now allowed to run F</bin/ls> as B<operator>,
  but  F</bin/kill> and F</usr/bin/lprm> as B<root>.
  
+ We can extend this to allow B<dgb> to run C</bin/ls> with either
+ the user or group set to B<operator>:
+  dgb  boulder = (operator : operator) /bin/ls, (root) /bin/kill, \
+       /usr/bin/lprm
+ In the following example, user B<tcm> may run commands that access
+ a modem device file with the dialer group.  Note that in this example
+ only the group will be set, the command still runs as user B<tcm>.
+  tcm  boulder = (:dialer) /usr/bin/tip, /usr/bin/cu, \
+       /usr/local/bin/minicom
  =head2 Tag_Spec
  
  A command may have zero or more tags associated with it.  There are
six possible tag values, C<NOPASSWD>, C<PASSWD>, C<NOEXEC>, C<EXEC>,
eight possible tag values, C<NOPASSWD>, C<PASSWD>, C<NOEXEC>, C<EXEC>,
  C<SETENV> and C<NOSETENV>.
  Once a tag is set on a C<Cmnd>, subsequent C<Cmnd>s in the
  C<Cmnd_Spec_List>, inherit the tag unless it is overridden by the
@@@ -298,7 -332,7 +332,7 @@@ For example
   ray  rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
  
  would allow the user B<ray> to run F</bin/kill>, F</bin/ls>, and
- F</usr/bin/lprm> as root on the machine rushmore as B<root> without
+ F</usr/bin/lprm> as B<root> on the machine rushmore without
  authenticating himself.  If we only want B<ray> to be able to
  run F</bin/kill> without a password the entry would be:
  
@@@ -342,7 -376,7 +376,7 @@@ be overridden by use of the C<UNSETENV
  =head2 Wildcards
  
  B<sudo> allows shell-style I<wildcards> (aka meta or glob characters)
- to be used in pathnames as well as command line arguments in the
+ to be used in hostnames, pathnames and command line arguments in the
  I<sudoers> file.  Wildcard matching is done via the B<POSIX>
  L<fnmatch(3)> routine.  Note that these are I<not> regular expressions.
  
@@@ -371,6 -405,15 +405,15 @@@ escape special characters such as: "*"
  
  =back
  
+ POSIX character classes may also be used if your system's
+ L<fnmatch(3)> function supports them.  However, because the
+ C<':'> character has special meaning in I<sudoers>, it must
+ be escaped.  For example:
+     /bin/ls [[\:alpha\:]]*
+ Would match any filename beginning with a letter.
  Note that a forward slash ('/') will B<not> be matched by
  wildcards used in the pathname.  When matching the command
  line arguments, however, a slash B<does> get matched by
@@@ -394,6 -437,26 +437,26 @@@ with B<any> arguments
  
  =back
  
+ =head2 Including other files from within sudoers
+ It is possible to include other I<sudoers> files from within the
+ I<sudoers> file currently being parsed using the C<#include>
+ directive, similar to the one used by the C preprocessor.  This is
+ useful, for example, for keeping a site-wide I<sudoers> file in
+ addition to a per-machine local one.  For the sake of this example
+ the site-wide I<sudoers> will be F</etc/sudoers> and the per-machine
+ one will be F</etc/sudoers.local>.  To include F</etc/sudoers.local>
+ from F</etc/sudoers> we would use the following line in F</etc/sudoers>:
+  #include /etc/sudoers.local
+ When B<sudo> reaches this line it will suspend processing of the
+ current file (F</etc/sudoers>) and switch to F</etc/sudoers.local>.
+ Upon reaching the end of F</etc/sudoers.local>, the rest of
+ F</etc/sudoers> will be processed.  Files that are included may
+ themselves include other files.  A hard limit of 128 nested include
+ files is enforced to prevent include file loops.
  =head2 Other special characters and reserved words
  
  The pound sign ('#') is used to indicate a comment (unless it is
@@@ -437,36 -500,12 +500,12 @@@ B<Flags>
  
  =over 16
  
 -=item always_set_home
 +=item mail_badpass
  
- Send mail to the I<mailto> user if the user running B<sudo> does not
- enter the correct password.  This flag is I<off> by default.
- =item mail_no_host
- If set, mail will be sent to the I<mailto> user if the invoking
- user exists in the I<sudoers> file, but is not allowed to run
- commands on the current host.  This flag is I<@mail_no_host@> by default.
- =item mail_no_perms
- If set, mail will be sent to the I<mailto> user if the invoking
- user is allowed to use B<sudo> but the command they are trying is not
- listed in their I<sudoers> file entry or is explicitly denied.
- This flag is I<@mail_no_perms@> by default.
- =item mail_no_user
- If set, mail will be sent to the I<mailto> user if the invoking
- user is not in the I<sudoers> file.  This flag is I<@mail_no_user@>
- by default.
- =item noexec
- If set, all commands run via B<sudo> will behave as if the C<NOEXEC>
- tag has been set, unless overridden by a C<EXEC> tag.  See the
- description of I<NOEXEC and EXEC> below as well as the L<PREVENTING SHELL
- ESCAPES> section at the end of this manual.  This flag is I<off> by default.
+ If set, B<sudo> will set the C<HOME> environment variable to the home
+ directory of the target user (which is root unless the B<-u> option is used).
+ This effectively means that the B<-H> option is always implied.
+ This flag is I<off> by default.
  
  =item authenticate
  
@@@ -475,6 -514,12 +514,12 @@@ means of authentication) before they ma
  may be overridden via the C<PASSWD> and C<NOPASSWD> tags.
  This flag is I<on> by default.
  
+ =item closefrom_override
+ If set, the user may use B<sudo>'s B<-C> option which
+ overrides the default starting point at which B<sudo> begins
+ closing open file descriptors.  This flag is I<off> by default.
  =item env_editor
  
  If set, B<visudo> will use the value of the EDITOR or VISUAL
@@@ -493,9 -538,9 +538,9 @@@ LOGNAME, SHELL, USER, USERNAME and the 
  variables in the caller's environment that match the C<env_keep>
  and C<env_check> lists are then added.  The default contents of the
  C<env_keep> and C<env_check> lists are displayed when B<sudo> is
- run by root with the I<-V> option.  If B<sudo> was compiled with
- the C<SECURE_PATH> option, its value will be used for the C<PATH>
environment variable.  This flag is I<on> by default.
+ run by root with the I<-V> option.  If the I<secure_path> option
+ is set, its value will be used for the C<PATH> environment variable.
+ This flag is I<on> by default.
  
  =item fqdn
  
@@@ -516,10 -561,7 +561,7 @@@ I<fqdn>.  This flag is I<@fqdn@> by def
  
  If set, B<sudo> will ignore '.' or '' (current dir) in the C<PATH>
  environment variable; the C<PATH> itself is not modified.  This
- flag is I<@ignore_dot@> by default.  Currently, while it is possible
- to set I<ignore_dot> in I<sudoers>, its value is not used.  This option
- should be considered read-only (it will be fixed in a future version
- of B<sudo>).
+ flag is I<@ignore_dot@> by default.
  
  =item ignore_local_sudoers
  
@@@ -620,11 -662,9 +662,9 @@@ user.  This flag is I<off> by default
  =item requiretty
  
  If set, B<sudo> will only run when the user is logged in to a real
- tty.  This will disallow things like C<"rsh somehost sudo ls"> since
- L<rsh(1)> does not allocate a tty.  Because it is not possible to turn
- off echo when there is no tty present, some sites may wish to set
- this flag to prevent a user from entering a visible password.  This
- flag is I<off> by default.
+ tty.  When this flag is set, B<sudo> can only be run from a login
+ session and not via other means such as L<cron(8)> or cgi-bin scripts.
+ This flag is I<off> by default.
  
  =item root_sudo
  
@@@ -649,16 -689,16 +689,16 @@@ password of the invoking user.  This fl
  
  =item set_home
  
- If set and B<sudo> is invoked with the B<-s> flag the C<HOME>
+ If set and B<sudo> is invoked with the B<-s> option the C<HOME>
  environment variable will be set to the home directory of the target
  user (which is root unless the B<-u> option is used).  This effectively
- makes the B<-s> flag imply B<-H>.  This flag is I<off> by default.
+ makes the B<-s> option imply B<-H>.  This flag is I<off> by default.
  
  =item set_logname
  
  Normally, B<sudo> will set the C<LOGNAME>, C<USER> and C<USERNAME>
  environment variables to the name of the target user (usually root
- unless the B<-u> flag is given).  However, since some programs
+ unless the B<-u> option is given).  However, since some programs
  (including the RCS revision control system) use C<LOGNAME> to
  determine the real identity of the user, it may be desirable to
  change this behavior.  This can be done by negating the set_logname
@@@ -678,7 -718,7 +718,7 @@@ by default
  =item shell_noargs
  
  If set and B<sudo> is invoked with no arguments it acts as if the
- B<-s> flag had been given.  That is, it runs a shell as root (the
+ B<-s> option had been given.  That is, it runs a shell as root (the
  shell is determined by the C<SHELL> environment variable if it is
  set, falling back on the shell listed in the invoking user's
  /etc/passwd entry if not).  This flag is I<off> by default.
@@@ -697,9 -737,9 +737,9 @@@ function.  This flag is I<off> by defau
  =item targetpw
  
  If set, B<sudo> will prompt for the password of the user specified by
- the B<-u> flag (defaults to C<root>) instead of the password of the
+ the B<-u> option (defaults to C<root>) instead of the password of the
  invoking user.  Note that this precludes the use of a uid not listed
- in the passwd database as an argument to the B<-u> flag.
+ in the passwd database as an argument to the B<-u> option.
  This flag is I<off> by default.
  
  =item tty_tickets
@@@ -716,12 -756,29 +756,29 @@@ If set, B<sudo> will apply the default
  login class if one exists.  Only available if B<sudo> is configured with
  the --with-logincap option.  This flag is I<off> by default.
  
+ =item visiblepw
+ By default, B<sudo> will refuse to run if the user must enter a
+ password but it is not possible to disable echo on the terminal.
+ If the I<visiblepw> flag is set, B<sudo> will prompt for a password
+ even when it would be visible on the screen.  This makes it possible
+ to run things like C<"rsh somehost sudo ls"> since L<rsh(1)> does
+ not allocate a tty.  This flag is I<off> by default.
  =back
  
  B<Integers>:
  
  =over 16
  
+ =item closefrom
+ Before it executes a command, B<sudo> will close all open file
+ descriptors other than standard input, standard output and standard
+ error (ie: file descriptors 0-2).  The I<closefrom> option can be used
+ to specify a different file descriptor at which to start closing.
+ The default is C<3>.
  =item passwd_tries
  
  The number of tries a user gets to enter his/her password before
@@@ -757,7 -814,12 +814,12 @@@ own timestamps via C<sudo -v> and C<sud
  =item 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 C<@sudo_umask@>.
+ it to 0777 to preserve the user's umask.  The actual umask that is
+ used will be the union of the user's umask and C<@sudo_umask@>.
+ This guarantees that B<sudo> never lowers the umask when running a
+ command.  Note on systems that use PAM, the default PAM configuration
+ may specify its own umask which will override the value set in
+ I<sudoers>.
  
  =back
  
@@@ -840,7 -902,7 +902,7 @@@ This option is only available whe B<sud
  
  =item runas_default
  
- The default user to run commands as if the B<-u> flag is not specified
+ The default user to run commands as if the B<-u> option is not specified
  on the command line.  This defaults to C<@runas_default@>.
  Note that if I<runas_default> is set it B<must> occur before
  any C<Runas_Alias> specifications.
@@@ -855,6 -917,12 +917,12 @@@ Defaults to C<@badpri@>
  Syslog priority to use when user authenticates successfully.
  Defaults to C<@goodpri@>.
  
+ =item sudoers_locale
+ Locale to use when parsing the sudoers file.  Note that changing
+ the locale may affect how sudoers is interpreted.
+ Defaults to C<"C">.
  =item timestampdir
  
  The directory in which B<sudo> stores its timestamp files.
@@@ -878,6 -946,25 +946,25 @@@ B<Strings that can be used in a boolea
  
  =over 12
  
+ =item askpass
+ The I<askpass> option specifies the fully qualified path to a helper
+ program used to read the user's password when no terminal is
+ available.  This may be the case when B<sudo> is executed from a
+ graphical (as opposed to text-based) application.  The program
+ specified by I<askpass> should display the argument passed to it
+ as the prompt and write the user's password to the standard output.
+ The value of I<askpass> may be overridden by the C<SUDO_ASKPASS>
+ environment variable.
+ =item env_file
+ The I<env_file> options specifies the fully qualified path to a file
+ containing variables to be set in the environment of the program
+ being run.  Entries in this file should be of the form C<VARIABLE=value>.
+ Variables in this file are subject to other B<sudo> environment
+ settings such as I<env_keep> and I<env_check>.
  =item exempt_group
  
  Users in this group are exempt from password and PATH requirements.
@@@ -917,7 -1004,7 +1004,7 @@@ By default, B<sudo> uses a built-in lec
  =item listpw
  
  This option controls when a password will be required when a
- user runs B<sudo> with the B<-l> flag.  It has the following possible values:
+ user runs B<sudo> with the B<-l> option.  It has the following possible values:
  
  =over 8
  
@@@ -928,7 -1015,7 +1015,7 @@@ the C<NOPASSWD> flag set to avoid enter
  
  =item always
  
- The user must always enter a password to use the B<-l> flag.
+ The user must always enter a password to use the B<-l> option.
  
  =item any
  
@@@ -937,7 -1024,7 +1024,7 @@@ must have the C<NOPASSWD> flag set to a
  
  =item never
  
- The user need never enter a password to use the B<-l> flag.
+ The user need never enter a password to use the B<-l> option.
  
  =back
  
@@@ -960,12 -1047,28 +1047,28 @@@ Flags to use when invoking mailer. Defa
  Path to mail program used to send warning mail.
  Defaults to the path to sendmail found at configure time.
  
+ =item mailfrom
+ Address to use for the "from" address when sending warning and error
+ mail.  The address should be enclosed in double quotes (C<">) to
+ protect against B<sudo> interpreting the C<@> sign.  Defaults to
+ the name of the user running B<sudo>.
  =item mailto
  
  Address to send warning and error mail to.  The address should
  be enclosed in double quotes (C<">) to protect against B<sudo>
  interpreting the C<@> sign.  Defaults to C<@mailto@>.
  
+ =item secure_path
+ Path used for every command run from B<sudo>.  If you don't trust the
+ people running B<sudo> to have a sane C<PATH> environment variable you may
+ want to use this.  Another use is if you want to have the "root path"
+ be separate from the "user path."  Users in the group specified by the
+ I<exempt_group> option are not affected by I<secure_path>.
+ This is not set by default.
  =item syslog
  
  Syslog facility if syslog is being used for logging (negate to
@@@ -974,7 -1077,7 +1077,7 @@@ disable syslog logging).  Defaults to C
  =item verifypw
  
  This option controls when a password will be required when a user runs
- B<sudo> with the B<-v> flag.  It has the following possible values:
+ B<sudo> with the B<-v> option.  It has the following possible values:
  
  =over 8
  
@@@ -985,7 -1088,7 +1088,7 @@@ the C<NOPASSWD> flag set to avoid enter
  
  =item always
  
- The user must always enter a password to use the B<-v> flag.
+ The user must always enter a password to use the B<-v> option.
  
  =item any
  
@@@ -994,7 -1097,7 +1097,7 @@@ must have the C<NOPASSWD> flag set to a
  
  =item never
  
- The user need never enter a password to use the B<-v> flag.
+ The user need never enter a password to use the B<-v> option.
  
  =back
  
@@@ -1025,10 -1128,7 +1128,10 @@@ the I<-V> option
  
  =item env_delete
  
 -Environment variables to be removed from the user's environment.
 +
 +Not effective due to security issues: only variables listed in 
 +I<env_keep> or I<env_check> can be passed through B<sudo>!
 +
  The argument may be a double-quoted, space-separated list or a
  single value without double-quotes.  The list can be replaced, added
  to, deleted from, or disabled by using the C<=>, C<+=>, C<-=>, and
@@@ -1040,8 -1140,8 +1143,8 @@@ as B<sudo>)
  
  =item env_keep
  
 -Environment variables to be preserved in the user's environment
 -when the I<env_reset> option is in effect.  This allows fine-grained
 +Environment variables to be preserved in the user's environment.
 +This allows fine-grained
  control over the environment B<sudo>-spawned processes will receive.
  The argument may be a double-quoted, space-separated list or a
  single value without double-quotes.  The list can be replaced, added
@@@ -1079,25 -1179,9 +1182,18 @@@ List of network group
  
  =head1 EXAMPLES
  
- Since the I<sudoers> file is parsed in a single pass, order is
- important.  In general, you should structure I<sudoers> such that
- the C<Host_Alias>, C<User_Alias>, and C<Cmnd_Alias> specifications
- come first, followed by any C<Default_Entry> lines, and finally the
- C<Runas_Alias> and user specifications.  The basic rule of thumb
- is you cannot reference an Alias that has not already been defined.
  Below are example I<sudoers> entries.  Admittedly, some of
  these are a bit contrived.  First, we define our I<aliases>:
  
 +Below are example I<sudoers> entries.  Admittedly, some of
 +these are a bit contrived.  First, we allow a few environment
 +variables to pass and then define our I<aliases>:
 +
 + # Run X applications through sudo; HOME is used to find .Xauthority file
 + # Note that some programs may use HOME for other purposes too and
 + # this may lead to privilege escalation!
 + Defaults env_keep = "DISPLAY HOME"
 + 
   # User alias specification
   User_Alias   FULLTIMERS = millert, mikef, dowdy
   User_Alias   PARTTIMERS = bostley, jwfox, crawl
@@@ -1197,7 -1281,7 +1293,7 @@@ directory F</usr/oper/bin/>
  
  The user B<joe> may only L<su(1)> to operator.
  
-  pete         HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
+  pete         HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
  
  The user B<pete> is allowed to change anyone's password except for
  root on the I<HPPA> machines.  Note that this assumes L<passwd(1)>
@@@ -1227,7 -1311,7 +1323,7 @@@ The user B<fred> can run commands as an
   john         ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
  
  On the I<ALPHA> machines, user B<john> may su to anyone except root
- but he is not allowed to give L<su(1)> any flags.
+ but he is not allowed to specify any options to the L<su(1)> command.
  
   jen          ALL, !SERVERS = ALL
  
diff --combined visudo.man.in
index bb94e3bbef5cc0bb9465424644c0bec1ab761fbd,7aa576b4ceaae7bdf2ac6dfe8e3f91302dbf2439..eca8d900f465308fb9c0c714b1a92e6043794263
@@@ -1,4 -1,5 +1,5 @@@
- .\" Copyright (c) 1996,1998-2005, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ .\" Copyright (c) 1996,1998-2005, 2007-2008
+ .\"   Todd C. Miller <Todd.Miller@courtesan.com>
  .\" 
  .\" Permission to use, copy, modify, and distribute this software for any
  .\" purpose with or without fee is hereby granted, provided that the above
@@@ -17,8 -18,8 +18,8 @@@
  .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
  .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
  .\" 
- .\" $Sudo: visudo.man.in,v 1.20.2.22 2008/06/22 20:29:03 millert Exp $
- .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+ .\" $Sudo: visudo.man.in,v 1.32 2008/11/15 18:34:26 millert Exp $
+ .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
  .\"
  .\" Standard preamble:
  .\" ========================================================================
  ..
  .\" Set up some character translations and predefined strings.  \*(-- will
  .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
- .\" double quote, and \*(R" will give a right double quote.  | will give a
- .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
- .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
- .\" expand to `' in nroff, nothing in troff, for use with C<>.
- .tr \(*W-|\(bv\*(Tr
+ .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+ .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+ .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+ .\" nothing in troff, for use with C<>.
+ .tr \(*W-
  .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
  .ie n \{\
  .    ds -- \(*W-
  .    ds R" ''
  'br\}
  .\"
+ .\" Escape single quotes in literal strings from groff's Unicode transform.
+ .ie \n(.g .ds Aq \(aq
+ .el       .ds Aq '
+ .\"
  .\" If the F register is turned on, we'll generate index entries on stderr for
  .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
  .\" entries marked with X<> in POD.  Of course, you'll have to process the
  .\" output yourself in some meaningful fashion.
- .if \nF \{\
+ .ie \nF \{\
  .    de IX
  .    tm Index:\\$1\t\\n%\t"\\$2"
  ..
  .    nr % 0
  .    rr F
  .\}
- .\"
- .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
- .\" way too many mistakes in technical documents.
- .hy 0
- .if n .na
+ .el \{\
+ .    de IX
+ ..
+ .\}
  .\"
  .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
  .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
  .\" ========================================================================
  .\"
  .IX Title "VISUDO @mansectsu@"
- .TH VISUDO @mansectsu@ "Jun 21, 2008" "1.6.9p17" "MAINTENANCE COMMANDS"
+ .TH VISUDO @mansectsu@ "November 15, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+ .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+ .\" way too many mistakes in technical documents.
+ .if n .ad l
+ .nh
  .SH "NAME"
  visudo \- edit the sudoers file
  .SH "SYNOPSIS"
@@@ -165,19 -173,15 +173,19 @@@ edited you will receive a message to tr
  .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
 -\&\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`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR environment
 +\&\f(CW\*(C`Default\*(C'\fR variable.  
 +On Debian systems, this list defaults to /usr/bin/editor, which is meant to
 +be a system-wide default editor chosen through the alternatives system.
 +Normally, \&\fBvisudo\fR does not honor the \f(CW\*(C`VISUAL\*(C'\fR or 
 +\f(CW\*(C`EDITOR\*(C'\fR environment
  variables unless they contain an editor in the aforementioned editors
  list.  However, if \fBvisudo\fR is configured with the \fI\-\-with\-enveditor\fR
flag or the \fIenv_editor\fR \f(CW\*(C`Default\*(C'\fR variable is set in \fIsudoers\fR,
option or the \fIenv_editor\fR \f(CW\*(C`Default\*(C'\fR variable is set in \fIsudoers\fR,
  \&\fBvisudo\fR will use any the editor defines by \f(CW\*(C`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR.
  Note that this can be a security hole since it allows the user to
  execute any program they wish simply by setting \f(CW\*(C`VISUAL\*(C'\fR or \f(CW\*(C`EDITOR\*(C'\fR.
 +Despite this potential risk, sudo on Debian is compiled with the
 +\fI\-\-with\-enveditor\fR flag.
  .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
@@@ -195,7 -199,7 +203,7 @@@ error occurred (if the editor supports 
  .SH "OPTIONS"
  .IX Header "OPTIONS"
  \&\fBvisudo\fR accepts the following command line options:
- .IP "\-c" 4
+ .IP "\-c" 12
  .IX Item "-c"
  Enable \fBcheck-only\fR mode.  The existing \fIsudoers\fR file will be
  checked for syntax and a message will be printed to the
@@@ -203,32 -207,32 +211,32 @@@ standard output detailing the status o
  If the syntax check completes successfully, \fBvisudo\fR will
  exit with a value of 0.  If a syntax error is encountered,
  \&\fBvisudo\fR will exit with a value of 1.
- .IP "\-f" 4
- .IX Item "-f"
+ .IP "\-f \fIsudoers\fR" 12
+ .IX Item "-f sudoers"
  Specify and alternate \fIsudoers\fR file location.  With this option
  \&\fBvisudo\fR will edit (or check) the \fIsudoers\fR file of your choice,
- instead of the default, \fI@sysconfdir@/sudoers\fR.  The lock file used
+ instead of the default, \fI\f(CI@sysconfdir\fI@/sudoers\fR.  The lock file used
  is the specified \fIsudoers\fR file with \*(L".tmp\*(R" appended to it.
- .IP "\-q" 4
+ .IP "\-q" 12
  .IX Item "-q"
  Enable \fBquiet\fR mode.  In this mode details about syntax errors
  are not printed.  This option is only useful when combined with
- the \fB\-c\fR flag.
- .IP "\-s" 4
+ the \fB\-c\fR option.
+ .IP "\-s" 12
  .IX Item "-s"
  Enable \fBstrict\fR checking of the \fIsudoers\fR file.  If an alias is
  used before it is defined, \fBvisudo\fR will consider this a parse
  error.  Note that it is not possible to differentiate between an
  alias and a hostname or username that consists solely of uppercase
  letters, digits, and the underscore ('_') character.
- .IP "\-V" 4
+ .IP "\-V" 12
  .IX Item "-V"
  The \fB\-V\fR (version) option causes \fBvisudo\fR to print its version number
  and exit.
  .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:
+ The following environment variables may be consulted depending on
the value of the \fIeditor\fR and \fIenv_editor\fR \fIsudoers\fR variables:
  .ie n .IP "\*(C`VISUAL\*(C'" 16
  .el .IP "\f(CW\*(C`VISUAL\*(C'\fR" 16
  .IX Item "VISUAL"
@@@ -239,10 -243,12 +247,12 @@@ Invoked by visudo as the editor to us
  Used by visudo if \s-1VISUAL\s0 is not set
  .SH "FILES"
  .IX Header "FILES"
- .IP "\fI@sysconfdir@/sudoers\fR" 24
+ .ie n .IP "\fI\fI@sysconfdir\fI@/sudoers\fR" 24
+ .el .IP "\fI\f(CI@sysconfdir\fI@/sudoers\fR" 24
  .IX Item "@sysconfdir@/sudoers"
  List of who can run what
- .IP "\fI@sysconfdir@/sudoers.tmp\fR" 24
+ .ie n .IP "\fI\fI@sysconfdir\fI@/sudoers.tmp\fR" 24
+ .el .IP "\fI\f(CI@sysconfdir\fI@/sudoers.tmp\fR" 24
  .IX Item "@sysconfdir@/sudoers.tmp"
  Lock file for visudo
  .SH "DIAGNOSTICS"
  .IP "sudoers file busy, try again later." 4
  .IX Item "sudoers file busy, try again later."
  Someone else is currently editing the \fIsudoers\fR file.
- .IP "@sysconfdir@/sudoers.tmp: Permission denied" 4
+ .ie n .IP "@sysconfdir@/sudoers.tmp: Permission denied" 4
+ .el .IP "\f(CW@sysconfdir\fR@/sudoers.tmp: Permission denied" 4
  .IX Item "@sysconfdir@/sudoers.tmp: Permission denied"
  You didn't run \fBvisudo\fR as root.
  .IP "Can't find you in the passwd database" 4
  .IX Item "Can't find you in the passwd database"
  Your userid does not appear in the system passwd file.
- .IP "Warning: undeclared Alias referenced near ..." 4
- .IX Item "Warning: undeclared Alias referenced near ..."
- Either you are using a {User,Runas,Host,Cmnd}_Alias before
- defining it or you have a user or hostname listed that
- consists solely of uppercase 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.
- .IP "Warning: runas_default set after old value is in use ..." 4
- .IX Item "Warning: runas_default set after old value is in use ..."
- You have a \fIrunas_default\fR Defaults setting listed in the \fIsudoers\fR
- file after its value has already been used.  This means that entries
- prior to the \fIrunas_default\fR setting will match based on the default
- value of \fIrunas_default\fR (\f(CW\*(C`@runas_default@\*(C'\fR) whereas entries
- \&\fBafter\fR the \fIrunas_default\fR setting will match based on the new
- value.  This is usually unintentional and in most cases the
- <runas_default> setting should be placed before any \f(CW\*(C`Runas_Alias\*(C'\fR
- or User specifications.  In \fB\-s\fR (strict) mode this is an error,
- not a warning.
+ .IP "Warning: {User,Runas,Host,Cmnd}_Alias referenced but not defined" 4
+ .IX Item "Warning: {User,Runas,Host,Cmnd}_Alias referenced but not defined"
+ Either you are trying to use an undeclare {User,Runas,Host,Cmnd}_Alias
+ or you have a user or hostname listed that consists solely of
+ uppercase letters, digits, and the underscore ('_') character.  In
+ the latter case, you can ignore the warnings (\fBsudo\fR will not
+ complain).  In \fB\-s\fR (strict) mode these are errors, not warnings.
+ .IP "Warning: unused {User,Runas,Host,Cmnd}_Alias" 4
+ .IX Item "Warning: unused {User,Runas,Host,Cmnd}_Alias"
+ The specified {User,Runas,Host,Cmnd}_Alias was defined but never
+ used.  You may wish to comment out or remove the unused alias.  In
+ \&\fB\-s\fR (strict) mode this is an error, not a warning.
  .SH "SEE ALSO"
  .IX Header "SEE ALSO"
  \&\fIvi\fR\|(1), \fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@), \fIvipw\fR\|(8)