Imported Upstream version 1.6.6 upstream/1.6.6
authorBdale Garbee <bdale@gag.com>
Wed, 14 May 2008 18:03:12 +0000 (12:03 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 14 May 2008 18:03:12 +0000 (12:03 -0600)
103 files changed:
BUGS [new file with mode: 0644]
CHANGES [new file with mode: 0644]
HISTORY [new file with mode: 0644]
INSTALL [new file with mode: 0644]
INSTALL.configure [new file with mode: 0644]
LICENSE [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
PORTING [new file with mode: 0644]
README [new file with mode: 0644]
RUNSON [new file with mode: 0644]
TODO [new file with mode: 0644]
TROUBLESHOOTING [new file with mode: 0644]
UPGRADE [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
aixcrypt.exp [new file with mode: 0644]
alloc.c [new file with mode: 0644]
alloca.c [new file with mode: 0644]
auth/API [new file with mode: 0644]
auth/afs.c [new file with mode: 0644]
auth/aix_auth.c [new file with mode: 0644]
auth/bsdauth.c [new file with mode: 0644]
auth/dce.c [new file with mode: 0644]
auth/fwtk.c [new file with mode: 0644]
auth/kerb4.c [new file with mode: 0644]
auth/kerb5.c [new file with mode: 0644]
auth/pam.c [new file with mode: 0644]
auth/passwd.c [new file with mode: 0644]
auth/rfc1938.c [new file with mode: 0644]
auth/secureware.c [new file with mode: 0644]
auth/securid.c [new file with mode: 0644]
auth/sia.c [new file with mode: 0644]
auth/sudo_auth.c [new file with mode: 0644]
auth/sudo_auth.h [new file with mode: 0644]
check.c [new file with mode: 0644]
compat.h [new file with mode: 0644]
config.guess [new file with mode: 0755]
config.h.in [new file with mode: 0644]
config.sub [new file with mode: 0755]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
def_data.c [new file with mode: 0644]
def_data.h [new file with mode: 0644]
def_data.in [new file with mode: 0644]
defaults.c [new file with mode: 0644]
defaults.h [new file with mode: 0644]
emul/fnmatch.h [new file with mode: 0644]
emul/search.h [new file with mode: 0644]
emul/utime.h [new file with mode: 0644]
env.c [new file with mode: 0644]
fileops.c [new file with mode: 0644]
find_path.c [new file with mode: 0644]
fnmatch.3 [new file with mode: 0644]
fnmatch.c [new file with mode: 0644]
getcwd.c [new file with mode: 0644]
getspwuid.c [new file with mode: 0644]
goodpath.c [new file with mode: 0644]
indent.pro [new file with mode: 0644]
ins_2001.h [new file with mode: 0644]
ins_classic.h [new file with mode: 0644]
ins_csops.h [new file with mode: 0644]
ins_goons.h [new file with mode: 0644]
install-sh [new file with mode: 0755]
insults.h [new file with mode: 0644]
interfaces.c [new file with mode: 0644]
interfaces.h [new file with mode: 0644]
lex.yy.c [new file with mode: 0644]
logging.c [new file with mode: 0644]
logging.h [new file with mode: 0644]
lsearch.c [new file with mode: 0644]
mkdefaults [new file with mode: 0755]
mkinstalldirs [new file with mode: 0755]
parse.c [new file with mode: 0644]
parse.h [new file with mode: 0644]
parse.lex [new file with mode: 0644]
parse.yacc [new file with mode: 0644]
pathnames.h.in [new file with mode: 0644]
sample.pam [new file with mode: 0644]
sample.sudoers [new file with mode: 0644]
sample.syslog.conf [new file with mode: 0644]
set_perms.c [new file with mode: 0644]
sigaction.c [new file with mode: 0644]
snprintf.c [new file with mode: 0644]
strcasecmp.c [new file with mode: 0644]
strerror.c [new file with mode: 0644]
sudo.c [new file with mode: 0644]
sudo.cat [new file with mode: 0644]
sudo.h [new file with mode: 0644]
sudo.man.in [new file with mode: 0644]
sudo.pod [new file with mode: 0644]
sudo.tab.c [new file with mode: 0644]
sudo.tab.h [new file with mode: 0644]
sudoers [new file with mode: 0644]
sudoers.cat [new file with mode: 0644]
sudoers.man.in [new file with mode: 0644]
sudoers.pod [new file with mode: 0644]
testsudoers.c [new file with mode: 0644]
tgetpass.c [new file with mode: 0644]
utime.c [new file with mode: 0644]
version.h [new file with mode: 0644]
visudo.c [new file with mode: 0644]
visudo.cat [new file with mode: 0644]
visudo.man.in [new file with mode: 0644]
visudo.pod [new file with mode: 0644]

diff --git a/BUGS b/BUGS
new file mode 100644 (file)
index 0000000..628f98e
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,25 @@
+Known bugs in sudo version 1.6.6
+================================
+
+1) Sudo should have an option to log when removing "dangerous"
+   environment variables.
+
+2) On DUNIX in sia mode, hitting return at the prompt does not quit.
+
+3) In parse.lex, '@' should not need to be a special character.
+   However, because lex does greedy matching, {WORD} will match
+   instead of the "^Defaults[:@]?" line.
+
+4) In list mode (sudo -l), characters escaped with a backslash
+   are shown verbatim with the backslash.
+
+5) Because the parser only does a single pass it is possible to
+   make a sudoers file where the "defaults" options are set after
+   a user's entry has been validated, changing the permissions for
+   the user.  The work-around is to put all 'defaults' entries
+   before the "User privilege specification" section but after all
+   the "alias specifications".  In the future the parser will
+   converted to a two-pass parser.
+
+For a list of things that are not bugs but that I would like to
+add / fix, please see the TODO file.
diff --git a/CHANGES b/CHANGES
new file mode 100644 (file)
index 0000000..ee37c48
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,1531 @@
+CHANGES since sudo 1.2
+
+01) sudo now works under hpux, aix, sunos, bsd43, ultrix, linux, osf and irix.
+
+02) Files w/o the executable bit will be ignored if they are in your PATH.
+
+03) If execv() fails, perror is called (which prints out an error based on
+       errno) and sudo exits with -1.
+
+04) Included in this shar should also be a version of getpass() derived from
+       the bsd net-2 source which works on bsd, ultrix, hpux, aix, and irix
+       at least.  The latter three unixes have what i consider to be a broken
+       getpass() in that if /dev/tty can't be opened it doesn't just use stdin
+       like bsd getpass().  This means you cannot do: rsh host "sudo command"
+       and have it work if your ticket has expired.
+
+05) The Makefile has changed significantly.  It now has defines for all
+       supported architectures.
+
+06) Changed MAXCOMMANDLENGTH from 48 bytes to MAXPATHLEN and included
+       sys/param.h where appropriate.
+
+07) Rewrote the code that expands links & paths.  It now works correctly.
+       (rewrote find_path.c)
+
+08) Added a define NEED_STRDUP so we don't conflict with the system's strdup(3)
+
+09) Now does *not* pass LD_* environmental vars on to programs that get
+       exec'd.  Also removes SHLIB_PATH for hpux and _RLD_* for dec osf.
+
+10) Now searches current dir last if '.' or '' are in PATH.  Misses braindeath
+    like './' but if that's in your path you deserve all the trojans you get.
+
+11) Added in linux patches from drew + flex support.
+
+12) Added insults back in from original sudo(8) (define USE_INSULTS).
+
+13) visudo now uses EDITOR envar (from John_Rouillard@dl5000.bc.edu)
+
+14) you can now specify a dir containing commands that a sudoer can do.
+    (from John_Rouillard@dl5000.bc.edu)
+
+15) Ported to Solaris 2.x (based on a port of sudo 1.1 done by UnixOps).
+
+16) Took out setuid(0); setruid(uid); pairs that bracketed calls to
+    update_timestamp() since they are unnecessary and setruid() is
+    broken on systems without a setreuid(2) or setresuid(2) system call.
+    (Ie: AIX and Solaris 2.x).
+
+17) The bulk of sudo now runs with the caller's real uid.  Grep for
+    be_root() to find the exceptions.
+
+CHANGES from sudo 1.3
+
+18) Added SECURE_PATH as suggested by russells@ccu1.auckland.ac.nz.
+
+19) Reworked clean_envp() to modify environ (not envp) so we can use
+    execvp() safely.
+
+20) Now use execvp() instead of execve() so sudo /bin/kill works under
+    broken solaris.  This also fixed sudo /etc/fastboot under stock
+    4.3 BSD.  Basically, this means that any executable shell script that
+    lacks a '#!/bin/sh' magic number will now work with sudo.  Personally
+    I think that the broken scripts should be fixed rather than changing
+    sudo, but vendors will be broken.  Sigh.
+
+21) Added USE_EXECV define so you can make sudo use execv() if you
+    want.  Using execvp() shouldn't be a problem since it is always
+    handed a non-relative path that begins with '/' but some people
+    may not trust execvp().
+
+22) Log file lines will no longer get truncated.  Syslog entries that
+    would overrun the syslog(3) line limit are continued on another entry.
+
+23) When logging to a log file, long entries are indented to improve
+    readability.
+
+24) Whenever the umask is changed, it is changed back to what it was
+    before.
+
+25) Log file is written as mode 600 instead of 644
+
+26) Umask that sudo runs with may now be specified.
+
+27) There is now a "configure" script.
+
+28) Sudo will use ultra fast crypt (ufc) if it finds it for systems w/o
+    a real crypt(3) (non-US ConvexOS/Secure for instance).
+
+29) _BSD_COMPAT is now defined for Irix.
+
+30) The global variable uid is now initialized to -2 because I'm paranoid.
+
+31) Native Solaris 2 port from Matthew.Stier@aisg.com
+
+32) Now use sysconf(2) instead of getdtablesize(2) if it is available
+    (see change #31).  Because of the the getdtablesize() emulation for
+    hpux is no longer necessary.
+
+33) Now only do a getcwd(3) or getwd(3) once and do it as the real user.
+    Sudo should no longer complain that it can't get the cwd unless
+    there is a real problem.
+
+34) Changed some malloc'd globals of fixed length to be allocated from
+    the stack instead as there was no win in allocating them from the
+    heap.
+
+35) Fixed AIX STATIC_FLAGS as per the AIX faq.
+
+36) Added -V flag to sudo and visudo (for version)
+
+37) Now treat EACCESS like EPERM when doing stat(2) in find_path.c
+
+38) Added prototypes for sudo functions (via __P macro)
+
+39) configure now uses uname(1) if it exists
+
+40) gethostbyname(3) is now only called if you define FQDN.  There's really
+    no reason to not trust gethostname(2) and this way if name service is
+    hosed sudo isn't...
+
+41) added -v (validate) flag to sudo to update a timestamp w/o running
+    a command
+
+42) now use tgetpass() (getpass with a timeout)
+
+43) find_path() now uses realpath(3)
+
+44) wrote versions of realpath(3) and getcwd(3) for those without
+
+45) wrote tgetpass()--a getpass() that times out via select(2)
+
+46) sudo now uses posix signals if available
+
+47) Finally added ConvexOS C2 security support from
+    "Peter A. Nikitser, Systems Software Support, QUT" <P.NIKITSER@qut.edu.au>
+
+48) You can now #undef MAILER if you don't run sendmail or the equivalent.
+
+49) AFS support from adamh@austin.ibm.com
+
+50) If you define BOTH_LOGS in sudo.h you can log both via syslog(3) *ans*
+    to a log file.
+
+51) Added ultrix /etc/auth (enhanced security) support.
+
+52) Sudo now will work with a 4.2BSD syslog (SunOS < 4 && ultrix).
+    Personally, I'd say you are better off logging to a file if
+    your syslog is this ancient.
+
+53) Changed realpath(3) to sudo_realpath() since we need to do the
+    chdir(2) with the invoking uid.  sudo_realpath() should be
+    faster than vendor-supplied realpath(3)'s anyway...
+
+54) No longer create a static binary on AIX since it reportedly
+    causes problem on newer versions on AIX 3.x.
+
+55) If sudo_realpath cannot chdir() back to cwd sudo will print
+    and error and exit.  Previously it would either fail silently
+    or print an incorrect error message.
+
+56) Moved code to send error mail to be after the log message.
+    From rouilj@cs.umb.edu.
+
+57) Added SUDO_USER and SUDO_UID envars.  Suggested by John P. Rouillard
+   (<rouilj@cs.umb.edu).
+
+58) Added -k and -h options and rearranged some of the code to be
+    more modular and less braindamaged.  This introduces the concept
+    of "run modes" to sudo.
+
+59) Fixed visudo and flex.  visudo now calls yyrestart() if you are using
+    flex instead of lex.  From bostley@cs.colorado.edu.
+
+60) Added a "cat page" for systems w/o nroff.
+
+61) Fixed a bug whereby only the last directory specified in a Cmnd_Alias
+    was checked.  Reported by "James R. Hendrick" <hendrick@ctron.com>.
+
+62) All .{c,lex,yacc} files now include both sys/types.h and unistd.h so
+    we are sure to get the typedef of uid_t.
+
+CHANGES from sudo 1.3.1
+
+63) Added preliminary support for DEC OSF/1 protected passwords
+    (shadow passwords).
+
+CHANGES from sudo 1.3.1pl1
+
+64) More support for DEC OSF/1 protected passwords (shadow passwords).
+
+CHANGES from sudo 1.3.1pl2
+
+65) Fixed mail logging to include the username as it should have.
+
+66) Added hostname to log message in error mail.
+
+67) Added -l flag to sudo to list the allowed/forbidden commands.
+    Suggested by matthew@gateway.bsis.com (Matthew Stier)
+
+68) Fixed bison warnings for parse.yacc and visudo.yacc.
+    Pointed out by alfie@dcs.warwick.ac.uk (Nick Holloway).
+
+CHANGES from sudo 1.3.1pl3
+
+69) Sudo will now exit with an error if the command to be run is > MAXPATHLEN.
+
+70) Test in configure for termios support was insufficient.  It thought
+    Nextstep 3.2 had termios just because it as termios.h (need to link
+    with -posix for termios on NeXT's)
+
+CHANGES from sudo 1.3.1pl4
+
+71) First stab at Skey support.
+
+72) Sudo now sets IFS to be SPACE, TAB, NEWLINE.
+
+73) Sudo now sets the real and effective gid to root's group
+    (based on passwd file).
+
+74) Sudo now checks that the sudoers file is owned by a certain user
+    and not readable or writable by anyone else.
+    (based on a suggestion by Joerg Schumacher <schuma@ips.cs.tu-bs.de>)
+
+75) Visudo now sets the owner on the new sudoers file based on #74
+
+76) Sudo and visudo will now compile with byacc (Berkeley yacc).
+
+77) If the rename(2) of stmp -> sudoers fails /bin/mv is executed before
+    bailing.  Based on code from Case Larsen <clarsen@mh1.lbl.gov>.
+
+78) User-level configuration is now done in options.h.
+
+79) Moved all compatibility #defines to compat.h
+
+80) Incorporated new parsing code from Chris Jepeway <jepeway@cs.utk.edu>.
+    This is much better than the previous parser.
+
+81) Rewrote visudo.c and tickled parse.yacc to work with it.  Visudo
+    now gives you options if a parse error occurs rather than blindly
+    dumping you back in the editor.
+
+82) Took out all references to realpath since we are now checking based
+    in inode and device (with Chris' new parser).  The upshot of this
+    is that path matches are done safely and the symlink problem has
+    gone away.
+
+83) Fixed bison warnings from new parse.yacc.
+
+84) Added a default case to parse.lex to error on unmatched tokens as Chris
+    suggested.
+
+85) Converted configure.in and acsite.m4 to autoconf 2.1.
+
+86) Added lsearch.c and search.h for os's w/o lsearch()/lfind().
+
+87) Sudo now checks to see that the file it is executing is a regular file
+    (was just checking the execute bit so dirs slipped through).
+    Pointed out by Barb Dijker <barb@labyrinth.com>.
+
+88) Fixed a problem on HP-UX trusted systems with getpwuid() returning "*"
+    unless the real uid is 0.  Reported by Brian Cunnie (cunnie@nyc.hp.com).
+
+89) configure now checks for size_t and ssize_t in unistd.h as well
+    as sys/types.h.
+
+90) configure now checks for egrep before actually using it.
+
+91) configure now checks for a working void implementation (ie: void * as
+    a generic pointer) and sets VOID to void or char accordingly.
+
+92) Added support for SunOS 4.x C2 security (shadow passwords) from
+    Kendall Libby (fubar@shore.net)
+
+93) Changed all occurrences of bzero() to memset() and bcopy() to
+    memmove().
+
+94) Fixed a bug in sudo.c.  If a user has no passwd entry sudo would
+    dump core (writing to a garbage pointer).  Pointed out by
+    Stephen Schaefer <sps@gateway.bsis.com>.
+
+95) Worked around a bug in AIX's lex in parse.c.  AIX lex doesn't seem
+    to handle {x,y} range notation correctly.  Bleah.
+
+96) Sudo would not report a failed attempt if the user entered return
+    at the 2nd password: prompt so someone trying to guess a password
+    could just invoked sudo multiple times and try one passwd at a time.
+    Reported by Jonathan Adams <jonathan@smada.com>.
+
+97) Added User_Alias facility.
+
+98) Rewrote most of the ip address / network support.  Now works on all
+    systems sudo has currently been tested on.
+
+99) Sudo now sets SUDO_COMMAND and SUDO_GID envariables in addition to
+    SUDO_USER and SUDO_UID.
+
+100) Added changes to configure.in for UnixWare.
+     (from John Warburton <jwarb@SACBH.com.au>)
+
+101) Merged in changes for Interactive Unix and RISCos.
+     (from Andy Smith <abs@maunsell.co.uk>)
+
+102) Added testsudoers (from Chris Jepeway <jepeway@cs.utk.edu>).
+
+103) Added fix for parse.yacc to avoid the kludge I was doing.
+     (from Chris Jepeway <jepeway@cs.utk.edu>)
+
+104) Now remove the IFS envar if set instead of setting it to a "safe"
+     value to avoid problems with make and others.
+
+105) Added FAST_MATCH option to check basenames of sudo command and
+     paths listed in sudoers file.  If the basename doesn't match
+     then it is not a match.  If the basename matches, then do
+     a stat to make sure it is a valid match.
+
+106) Now only stat(2) cmnd once in path_matches() (in parse.c).  Sudo
+     was stating cmnd for *every* attempted match.  Now the stat struct
+     is cached (ie: the var is a static).
+
+107) Signal handlers in visudo are now only installed after the stmp
+     file is opened.  Previously, it was possible to erase an open
+     stmp file by sending visudo a signal within a small window.
+
+108) Added Goon Show insults from  Russell Street <r.street@auckland.ac.nz>.
+
+109) Broke out the insults into separate include files (insults.h
+     is the master and includes the appropriate one).
+
+110) Now use getwd() instead of getcwd() and provide emulation for
+     OS's w/o it.  This was done since some OS's with getwd()
+     implement getcwd() via a pipe to pwd(1).  By emulating getwd()
+     by calling getcwd() on OS's w/o getwd() we lose nothing since
+     the compiler should optimize away the extra function call.
+
+111) Added crypt() for DEC OSF/1 3.x enhanced security.
+     From "Richard L Jackson Jr" <rjackson@osf1.gmu.edu>.
+
+112) Added an option to run the command in the background (-b) as
+     suggested by Jonathan Adams <jonathan@smada.com>
+
+113) First stab at kerberos support.  I'm not really sure it is
+     possible to do this in a sane manor.  Sigh.
+
+114) Better kerberos support.  Had to use setreuid(2) but falls
+     back on a kludge if that does not exist or is broken.
+
+115) Added -p (password prompt) support.
+     Suggested by "David W. Cooley" <dwcooley@COLBY.EDU>
+
+116) Added partial implementation of -l (list) flag.
+     This is probably as good as it will get until sudo:tng.
+
+117) Added anti-spoofing code to tighten up a race condition
+     where a user could run sudo some_link and then change
+     where the link pointed after the old link had been
+     validated but before the exec().
+
+118) Now update timestamp file via utime() (and emulate via utimes()
+     if necessary) to eliminate a small race.  Works with
+     both POSIX utime() as well as old utime() in BSD <= 4.3.
+
+119) Kerberos ticket file now lives in same dirs as sudo timestamp
+     files (to avoid trouncing on normal ticket file) and is removed
+     after validation.
+
+120) Now log tty user is on as well as pwd in sudo logs.
+
+CHANGES from sudo 1.3.2 BETA
+
+121) Fixed a bug in the anti-spoofing check.
+
+122) Fixed up ISC support so that it works and looks like non-streams
+     stuff in interfaces.c.
+
+123) Now deal correctly with ip implementations that has an sa_len
+     field in struct sockaddr.
+
+124) Check ownership and permissions on timestamp dir and ignore if
+     not owned by root and mode 0700.  Problem pointed out by Larry Auton
+     <lda@research.AT&T.com> and Navjot Singh <singh@research.AT&T.com>.
+
+125) Ignore timestamp files with preposterous dates to keep people from
+     faking out sudo on OS's that allow you to give away files to root.
+     Problem pointed out by Larry Auton <lda@research.AT&T.com> and
+     Navjot Singh <singh@research.AT&T.com>.
+
+126) A timeout of 0 will now cause a password to be entered every
+     time.  Based on a suggestion by Larry Auton <lda@research.AT&T.com>
+     and Navjot Singh <singh@research.AT&T.com>.
+
+CHANGES from sudo 1.3.3 BETA
+
+127) Cleaned up interfaces.c so that it is more readable.
+
+128) Added support for syslog()'s that don't guarantee delivery
+     of a message.  HP-UX is the only known offender.
+
+129) No longer use memmove() since memcpy() does what we need and
+     configure doesn't always catch memmove() even when it is
+     there (may be a library problem).
+
+130) Updated man page to reflect two more security issues.
+
+131) Cleaned up shadow password support in check.c.  It should now
+     be readable.
+
+132) Added SCO support.
+
+133) Added check to configure to find the max length of a uid_t
+     in characters.
+
+134) Removed uid2str() since we now know how big a uid_t/gid_t
+     can be.  This elminates a few malloc()'s.
+
+135) Added support for multiple insult types.  Based on code and
+     a suggestion from Dieter Dworkin Muller <dworkin@village.org>.
+
+136) Replaced clean_env() and rmenv() with a rewritten clean_env()
+     that should be a little faster.  This also makes it easier to
+     add to the list of "dangerous" envariables.
+
+137) Added netgroup support.  Netgroups must start with a leading
+     "+" to that sudo knows it is a netgroup.
+
+138) Split out sudoers file format into its own man page.
+     As suggested by Andy Smith <abs@maunsell.co.uk>.
+
+139) Updated testsudoers.c to grok netgroups.
+
+CHANGES from sudo 1.3.4 BETA
+
+140) Added SecurID support from Giles Todd <giles@gt.demon.co.uk>.
+
+141) Added -s flag to start a root shell and -- to signify end of args.
+
+142) Sped up logging routines by replacing strncpy()'s with strcat()'s.
+     This is safe because we dyanically allocate logline to be big enough.
+
+143) Now support command line arguments in the sudoers file.
+
+144) Sped up the loading on command line arguments.  This fixes the
+     "commands with large argc's take forever to run" bug.
+
+145) Expanded MAXCOMMANDLEN to 8K since we now have to deal with
+     command line arguments.  Added bounds checking in fill() and
+     append() so we don't drop core.
+     XXX - 8k makes sudo *SLOW*
+
+146) Added support in the lexer for "termination characters" to be
+     escaped.  Ie: you can now use [\,:=] in command line args
+     as long as you escape with a \.
+
+147) Testsudoers can now deal with commands that have arguments.
+
+148) If a file is not executable or not a regular file sudo will
+     now give the appropriate error message instead of just
+     "command not found" which is misleading.
+
+149) Fixed a bug where if FQDN is set, load_interfaces() was never
+     called.
+
+150) tty is now a global so it can be used in the ticket file
+     at a later date.
+
+151) Strings in the parser are now allocated dynamically.  This results
+     in a large speedup as compared to a 1K array on the stack. I
+     have freed the strings in the parser where appropriate but that
+     may not catch all instances.  Even so, the average sudo now
+     takes up less memory than the 1K array version.
+
+152) Fixed a bug in tgetpass() and configure that broke termio/termios
+     support for some OS's.
+
+153) Added cheapo implementation of tty-based timestamps.  The correct
+     way is to have username be a directory with the tty tickets
+     inside.  However, the current code does not take to that very
+     well, and it does not allow the two systems to coexist. Therefore,
+     instead of timestampdir/user/tty it is timestampdir/user.tty.
+
+154) Added support for building in other than the source directory.
+     Based on changes from "Simon J. Gerraty" <sjg@frodo.dn.itg.telecom.com.au>
+
+155) options.h and pathnames.h are now included via angle brackets
+     (<>) so as to use the -I include path.  This way, those using
+     a shadow build tree may have local copies of these headers
+     w/o clobbering the distribution ones.
+
+156) EXEMPTGROUP is now a string (group name) and user_is_exempt()
+     is now less of a hack.  It uses getgrnam(EXEMPTGROUP) to
+     get a list of users in the exempted group.
+
+157) --prefix and --exe_prefix are now honored in the Makefile.
+
+158) Sudo will now behave reasonably in the case where the sudoers
+     file location is mounted via NFS and the client does not
+     have "root" NFS privs.
+
+159) _PATH_SUDO_SUDOERS, _PATH_SUDO_STMP, and SUDOERS_OWNER are
+     now set via the Makefile since that appears to be what
+     most people expect...
+
+160) Now include a pre-generated version of parse.lex since so many
+     versions of lex are brain damaged.  If parse.lex is changed
+     a new lex.yy.c will be generated.  The distribution copy is
+     sudo-lex.yy.c.
+
+161) Upgraded to GNU autoconf version 1.5.  There are now even
+     *more* options.
+
+CHANGES from sudo 1.3.5 BETA
+
+162) Fixed S/Key support.
+
+163) Cleaned up shadow password support further by moving much of
+     it to getspwuid.c.
+
+164) First cut at DCE support. [needs work to be functional]
+
+165) New Digital UNIX C2 support based on code from
+     "Randy M. Hayman" <haymanr@icefog.sois.alaska.edu>
+
+166) S/key support now works with the generic bellcore s/key
+     as well as the s/key from Wietse Venema's logdaemon.
+     (Previously only worked with the logdaemon s/key).
+     As an added bonus the s/key challenge is now embedded
+     in the password prompt for a cleaner look.
+
+167) lsearch.c will now compile on a strict ANSI C compiler.
+     ANSI doesn't allow pointer arithmetic on a "void *"
+     but gcc does.
+
+168) Bought back latest HP-UX DCE support from Jeff Earickson
+     <jaearick@colby.edu>.
+
+169) configure now comletely groks $SUDO_LIBS and $VISUDO_LIBS.
+     Plain old $LIBS is no longer used.  LDFLAGS has also been
+     split up into $SUDO_LDFLAGS and $VISUDO_LDFLAGS.
+     The reason for this is that sudo often needs extra libs
+     for alternate authentication schemes but visudo rarely does.
+
+170) The code to copy command arguments flaied for large values of
+     argc due to realloc() lossage.  We now cheat and treat argv[]
+     as a flat string (since that's what it is) and use pointer
+     arithmetic to compute the length.  Kind of sneaky but it
+     works (and is relatively fast).
+
+CHANGES from sudo 1.3.6 BETA
+
+171) Added support for UN*X groups in sudoers based on code from
+     Dougal Scott <dwagon@aaii.oz.au>.
+
+172) interfaces.c should work on ISC UN*X again.
+
+173) All source files are <= 14 characters for old SYSV filesystems.
+
+CHANGES from sudo 1.3.7 GAMMA
+
+174) Minor configure[.in] fixes.
+
+175) tgetpass.c now compiles on OS's that put the definition of
+     fd_set in <sys/bsdtypes.h>
+
+CHANGES from sudo 1.4
+
+176) Command args in sudoers are now stored in an argument vector
+     instead of a flat string to make wildcard matching simpler.
+
+177) Added NewArgv and NewArgc that describe the command to be
+     executed.  The copy of args in cmnd_args is no longer necessary
+     and has been removed.
+
+178) Using strcmp(3) for argument matching in command_matches()
+     (was path_matches()) is no longer sufficient since we don't
+     have a flat string.  compare_args() is used instead which
+     calls either strcmp(3) or wildmat(3l) depending on whether
+     there are shell-style meta chars (wildcards) present.
+
+179) Shell-style wildcard matches are now available in the sudoers
+     file.  Matches are done via Rich $alz's wildmat(3).
+     This required the tweaks described in #176-178 as well as
+     other, more minor, changes.
+
+180) Commented out rule to build lex.yy.c from parse.lex since
+     we ship with a pre-flex'd parser and can't rely on file
+     dates being set correctly.
+
+181) Fixed visudo and testsudoers to deal with new argument
+     vector handling.
+
+182) A null string ("") as shell in passwd file (or $SHELL) is
+     now treated as the bourne shell.
+
+183) Converted *.man to pod format for easy conversion to man,
+     html, latex, and just plain text.  Tried to make the
+     sudoers manual easier to read in the process.
+
+184) Updated sample.sudoers and sudoers.pod to include info
+     on wildcards.
+
+CHANGES from sudo 1.4.1
+
+185) compat.h now defines _PASSWD_LEN based on PASS_MAX if it
+     is defined (from limits.h on SYSV).
+
+186) Both short and long hostnames may now be used in the sudoers
+     file if FQDN is defined.  From patches submitted by
+     Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>.
+
+187) Now use skeylookup() instead of skeychallenge().  Hopefully
+     this will work around a problem some people have reported
+     on Solaris 2.5 with sudo and logdaemon 5.0's skey.
+
+188) Now uses /var/run to hold timestamp files if it exists.  This
+     is more secure.
+
+189) configure now puts the timestamp dir in /var/run if it exists.
+     Sugestion by Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>.
+
+190) Both short and long hostnames now exist even if FQDN is not set.
+     This allows machines with fully qualified hostnames set via
+     hostname(1) to use them in the sudoers file.
+
+191) sudo was not honoring "." in $PATH due to a bug in find_path().
+
+192) Added IGNORE_DOT_PATH option to ignore "." in $PATH.
+
+193) tgetpass() now uses raw read(2) and write(2) instead of stdio.
+     This should make it work on more OS's.  Previously, it used
+     stdio (buffered) fgets(3) and fputs(3) with select(2) which
+     may not be legal.  Also got rid of the nasty goto's and
+     generally simplified the code.
+
+194) Parser now supports hostnames like UPPERCASE.foo.com.  Previously,
+     `UPPERCASE' was interpreted as an Alias.  This means that
+     the `fqdn' stuff has been moved to the lexer (FQHOST is used
+     to avoid collision with FQDN option).
+
+195) Reworked --with-FOO in configure.in to support --without-FOO.
+     Made shadow passwords the default for appropriate OS's.  They
+     can be turned off with --without-C2.
+
+196) Added NO_PASSWD option for those who don't want to be bothered
+     by a password prompt from sudo.  This is really just a hack.
+
+197) Added support for double quotes to mean "treat these words as one
+     argument".  This is similar to what most shells do.
+
+198) Added mkinstalldirs to make install destination dirs if
+     they do not already exist.
+
+CHANGES from sudo 1.4.2
+
+199) Added support for --with-CC (which C compiler to use).
+
+200) Added support for NOPASSWD token and running commands a
+     specified users (sudo -u) from Keith Garry Boyce
+     <garp@opustel.com>
+
+201) Only link with -lshadow for Linux if libc lacks getspnam().  Problem
+     pointed out by Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>.
+
+202) Replaced SUDOERS_OWNER with SUDOERS_UID and SUDOERS_GID.  Added
+     SUDOERS_MODE and changed the default to 0440 (from 0400).
+     It is now possible to NFS-mount sudoers without doing anything fancy.
+
+202) If a runas list is specified, a user may only run commands as
+     "root" if "root" is a member of the runas list.  The old behavior
+     was to always allow commands to be run as root, even if a runas
+     list was specified.  Now you can give someone "sudo -u operator"
+     and not have the equivalent of "sudo -u root" as well.
+
+203) Added "USER=%s" to logging functions.
+
+204) configure will now add -lPW to (VI)?SUDO_LIBS if using bison
+     or DCE and alloca(3) is not in libc (or provided by gcc) but
+     is in libPW.a.
+
+205) sudo would give an incorrect error message if the sudoers file
+     didn't exist due to close() stomping errno if the open() failed.
+
+206) Fixed "shell" mode (sudo -s).  When building NewArgv sudo was
+     not allocating space for the NULL.
+
+207) Added support for wildcards in the pathname.  Ie: /bin/*.
+
+208) 'command ""' in sudoers now means no args allowed.
+
+209) Added command line args to SUDO_COMMAND envariable.
+
+210) HP-UX 10.x with C2 now uses bigcrypt().
+     Changes from david_dill@Merck.Com (David Dill).
+
+211) lsearch.c will now compile w/o compiler warnings.
+     (Updated from NetBSD lsearch.c)
+
+212) Now uses POSIX fnmatch(3) (which uses ! instead of ^ in ranges)
+
+CHANGES from sudo 1.4.3
+
+213) Now allows network/netmask in sudoers to override per-interface
+     netmask.
+
+214) Fixed -u support with multiple user lists on a line.
+
+215) Fixed a core dump problem when built with -DSHELL_IF_NO_ARGS.
+
+216) Fixed 2 typos in parse.yacc and removed some unnecessary if's.
+
+217) Now always use install-sh since SunOS install can't do uid/gid's.
+     Other BSD installs are probably similarly afflicted.
+
+218) Fixed NFS-mounted sudoers file under solaris both uid *and* gid
+     were being set to -2.  Now set uid to 1 to avoid group being
+     remapped.
+
+219) Now includes alloca.c (from gcc) for those w/o it.  Linking
+     against -lPW breaks visudo on HP-UX and probably others.
+
+220) Added --with-libpath, --with-libraries, --with-incpath options
+     to configure.
+
+221) configure now uses shicc instead of gcc on BSD/OS >= 2.0 to
+     generate binaries linked with shared libs.
+
+222) The parser was setting no_passwd even if there wasn't a
+     runas match.  I reordered some things in parse.yacc
+     to fix this.
+
+223) `sudo -v' (validate) wasn't paying attention to NOPASSWD.
+     Now it does.
+
+224) testsudoers now groks "-u user".
+
+225) Updated AFS support based on what tcsh 6.06 does.
+
+226) Fixed a typo/thinko that broke BSD > 4.3reno wrt interfaces.c.
+
+227) HPUX 10.X shadow password stuff now uses SecureWare routines.
+
+228) SecureWare passwd checking now uses bigcrypt() if available.
+     Now uses AUTH_MAX_PASSWD_LENGTH if defined.
+
+229) configure now makes sure you don't have a config.cache file
+     from another OS.
+
+230) Added better shadow password detection.
+     BSD >= 4.3reno -> /etc/master.passwd
+     hpux9: getspwnam() -> /.secure/etc/passwd
+     hpux10: getspnam() or getprpwnam() -> /tcb/files/auth/*/* (link with -lsec)
+     SVR4: getspnam() -> /etc/shadow
+     solaris: getspnam() -> /etc/shadow
+     irix[56].x: getspnam() -> /etc/shadow
+     sunos 4.x: getpwanam() -> /etc/security/passwd.adjunct
+     DUNIX: getprpwnam() -> /tcb/files/auth/*/* (link with -lsecurity)
+     SecureWare: getprpwnam() -> /tcb/files/auth/*/*
+     ultrix 4.x: getauthuid() -> /etc/auth.{pag,dir}
+
+231) '(' in command args no longer are a syntax error.
+
+232) '!command' now works in the presence of a runas or NOPASSWD token.
+     Simplified parse rules wrt runas and NOPASSWD (more consistent).
+
+233) Command args and now compared as a flat string again.  This makes
+     wildcard matches more consistent.
+
+234) DUNIX C2 support now groks AUTH_CRYPT_OLDCRYPT and AUTH_CRYPT_C1CRYPT.
+
+235) configure now uses config.{sub,guess} to guess OS type.
+     Sudo should work out of the box on more OS's now.
+
+236) Got rid of HAVE_C2_SECURITY, now just use SHADOW_TYPE.
+
+237) Fixed race in tgetpass() where echo can be turned off and
+     left off if sudo is used in a pipeline and a password is
+     required.
+
+CHANGES from sudo 1.4.4
+
+238) `sudo -l' output now includes runas and NOPASSWD info and
+     asks for a password unless NOPASSWD for ALL is set.
+
+239) Sudo can now deal with all-caps user and host names.
+
+240) Sudo will now remove the "ENV" and "BASH_ENV" envariables.
+     From Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>.
+
+241) `sudo -l' will now expand Cmnd_Alias's (could be prettier).
+
+242) `sudo -s' will now set $HOME to root's homedir (or that of
+     the user specified -u) so dot files get sourced.
+
+CHANGES from sudo 1.4.5
+
+243) $HOME was always being set, not just with `-s'.
+
+244) In visudo, the owner and group of the sudoers file were
+     being set too early; an editor could change them and change
+     the owner/group of the resulting sudoers file.
+
+CHANGES from sudo 1.5
+
+245) Added SHELL_SETS_HOME option.
+
+246) Added NO_MESSAGE option.
+
+247) Added %u and %h escapes in PASSPROMPT to expand to user's name
+     and host.
+
+248) Added "SUDO_PROMPT" envariable.
+
+249) Usernames may now begin with a digit.  Gross, but people do it.
+
+Sudo 1.5.1 released.
+
+250) Added `opie' support.
+
+251) Added check to make sure fnmatch() really works.
+
+252) Now use the prompt S/Key gives us instead of rolling our own.
+
+253) Added -H flag from Danny Barron <dcbarro@nppd.com>.
+
+254) Add SUDO_PS1 envariable support.
+
+255) Attempt at sequent support.
+
+Sudo 1.5.2 released.
+
+256) visudo acts sanely when there is no sudoers file.
+
+257) Added Runas_Alias support.
+
+258) Sudo will now work with SUDOERS_MODE == 400 and SUDO_UID = 0.
+
+259) Alias's in a runas list are now expanded.
+
+260) Fixed bug with > 32 saved aliases.  Reported by BHH@capgroup.com.
+
+261) Code that uses sprintf() is now more paranoid about buffer
+     overflows.
+
+262) Whitespace is now allowed after a line continuation character before
+     a newline in sudoers.
+
+263) %h in MAILSUBJECT expands to local hostname.
+
+Sudo 1.5.3 released.
+
+264) Don't pass getdtablesize() as first arg to select(2).  No need
+     to do this since we only select on one fd--use (fd+1) as nfds
+     and the old way caused problems on some systems (arguably
+     a bug in those OS's).  From Marc Slemko marcs@znep.com.
+
+265) Fixed coredump when passwd file is missing or unavailable.
+     Reported by Jason Downs <downsj@teeny.org> and
+     Klee Dienes <klee@mit.edu> (via a Debian Linux bug report).
+
+266) Fixed bug wrt exclusion lists and relative pathnames.
+     Reported by osiris@COURIER.CB.LUCENT.COM.
+
+267) exit(1) if user doesn't enter a passwd.
+     Noted by Alex Parchkov <alexp@ind.tansu.com.au>.
+
+Sudo 1.5.4 released.
+
+268) Newer versions of Irix use _RLDN32_* envariables for 32-bit binaries
+     so ignore _RLD* instead of _RLD_*.  From tarrall@bamboo.Colorado.EDU.
+
+269) Only open sudoers file once as opposed to once for sanity checks and
+     once for the parser.  Also try to open ten times if we get EAGAIN.
+
+Sudo 1.5.5 released.
+
+270) Initialize group vector if we are becoming a user other than root.
+     For root, it is often more useful to hang on to our existing group
+     vector.
+
+271) Fix usage of select(2) to deal correctly with a high-numbered fd.
+
+272) Fixed a bug where sudo sometime didn't give the user a chance to
+     enter a password at the prompt.
+
+273) Use a dynamically sized buffer when reading ether interfaces.
+
+274) Fixed configure problems with identification of HP-UX > 10.x and
+     with cc being identified as a cross compiler on some platforms.
+
+275) Fixed a problem with HP-UX 10.x and alloca.  Bison does not
+     include alloca.h on HP-UX 10.x even though it uses alloca()
+     (and thus needs the #define of alloca(x) to __builtin_alloca(x)).
+     To fix this we include alloca.h ourselves if using bison and not gcc.
+
+276) Included support for the AIX 4.x authenticate() function from
+     Matt Richards <v2matt@btv.ibm.com>.
+
+277) Fixed an off by one error in the parser.  Found by
+     Piete Brooks <Piete.Brooks@cl.cam.ac.uk>
+
+278) Change NewArgv size computation to work on UNICOS.
+     From Mike Kienenberger <mkienenb@arsc.edu>
+
+279) Added --with-logfile and --with-timedir configure options.
+
+280) Use getcwd(3), not getwd(3) to avoid possible buffer overflow.
+     Use BSD getcwd(3) if system lacks one or is SunOS 4.x.
+
+281) Fix 'fprintf' argument mismatches in 'visudo.c'.
+     From ariel@oz.engr.sgi.com (Ariel Faigon)
+
+282) Use waitpid or wait3 to reap children in logging.c.
+     Pointed out by Theo de Raadt <deraadt@theos.com>
+
+283) Sudo should prompt for a password before telling the user that
+     a command could not be found.  Noted by rhodie@NAC.NET.
+
+284) Fix OTP_ONLY for opie; "Deven T. Corzine" <deven@fuse.net>.
+
+285) Include pre-yacc'd parse.yacc as sudo.tab.[ch] since more and
+     more vendors are charging for yacc (bad vendor, no cookie).
+
+286) Use MAX*, not MAX*+1
+
+287) Add support for Hitachi SR2201, from b-edgington@hpcc.hitachi-eu.co.uk
+
+288) Added RUNAS_DEFAULT option to allow one to compile sudo with a
+     default runas user other than root.
+
+289) Add options to log the hostname in the file-based log and to not
+     do word wrap in file-based log.  From Theo Van Dinter <tvd@chrysalis.com>
+
+290) RedHat Linux pam support, from Gary Calvin <GCalvin@kenwoodusa.com>.
+     pam.sudo goes in /etc/pam.d/sudo on RedHat 5.0 and above.
+
+291) With sudo -s, set command the full path of the shell, not the basename.
+     Noted by Peter W. Osel <pwo@guug.de>
+
+Sudo 1.5.6 released.
+
+292) Pam auth now runs as root; necessary for shadow passwords.
+
+293) Shadow password support is now compiled in by default.  You can disable
+     it via --disable-shadow.
+
+294) We now remove a timestamp file with a bogus date when it is detected.
+     From Steve Fobes <sfobes@uswest.com>.
+
+295) In tgetpass(), restart select if it is interrupted.  This really fixes a
+     problem where a user sometimes is not given a change to enter a password.
+
+296) All options have moved from options.h -> configure.
+
+297) visudo is now installed in /usr/local/sbin where it belongs.
+
+298) Lots of configure changes.  Instead of checking for the existence
+     of -lsocket, -lnsl, or -linet, we instead check them for the
+     functions we need only if they are not already in libc.
+
+299) Added DUNIX SIA (Security Integration Architecture) support from
+     Spider Boardman <spider@Orb.Nashua.NH.US>.
+
+300) Added test for broken Digital UNIX 4.0 prot.h.
+
+301) Better support for C2 security on Digital UNIX.
+
+302) Hacked autoconf so that you have have single quotes in
+     --with-passprompt.
+
+303) For SecureWare-style shadow passwords use getprpwnam() instead
+     of getprpwuid() since getprpwuid is broken in HP-UX 10.20 at
+     least (it sleeps for 2 minutes if the shadow files don't exist).
+
+304) We can't really trust UID_MAX or MAXUID since they may only exist for
+     backwards compatibility; spider-both@Orb.Nashua.NH.US
+
+305) Make %groups work as RunAs specifiers; Ray Bellis <rpb@community.net.uk>.
+
+306) Set USER environment variable to target user.
+     Suggested by Ray Bellis <rpb@community.net.uk>.
+
+307) Go back to printing "command not found" unless --disable-path-info
+     specified.  Also, tell user when we ignore '.' in their path and it
+     would have been used but for --with-ignore-dot.
+
+308) When using tty tickets make it user:tty not user.tty as a username
+     could have a '.' in it.
+
+309) Define BSD_COMP for svr4 to get BSD ioctl defs.  Also, if we have
+     sys/sockio.h but SIOCGIFCONF is not defined by including sys/ioctl.h
+     include sys/sockio.h directly.
+
+310) Fixed a bug that could cause "sudo -l" to segfault or complain
+     about non-existent syntax errors.
+
+Sudo 1.5.7 released.
+
+311) Fixed square bracket quoting in configure and moved check for -lnsl
+     to be before -lsocket.
+
+312) In load_interfaces(), close sock after bwe are done with it.  Leak
+     noticed by Mike Kienenberger <mkienenb@arsc.edu>.
+
+313) Missing pieces from change #308; from Mike Kienenberger.
+
+314) Real Kerberos 5 support from Frank Cusack <fcusack@iconnet.net>.
+
+315) FWTK 'authsrv' support from Kevin Kadow <kadow@MSG.NET>.
+
+316) Fixed handling and documentation of -with-umask.
+
+317) If the check for socket() or inet_addr() fails, retry, this time
+     linking with both -lsocket and -lnsl for those systems that
+     have interlibrary dependencies.
+
+Sudo 1.5.8 released.
+
+318) Add dirfd() macro for systems without it.
+
+319) Better check for socket() in -lsocket -lnsl in configure.
+
+320) Minor configure fixes.
+
+Sudo 1.5.8p1 released.
+
+321) Fixed a bug wrt quoting characters in command args.
+
+322) Make --without-sendmail work.
+
+Sudo 1.5.8p2 released.
+
+323) Fixed a segv if HOST_IN_LOG defined and gethostbyname() fails.
+     Reported by Gero Treuner <gero@faveve.uni-stuttgart.de>.
+
+324) Fixed a parse bug wrt the ! operator and runas specs.  Noted by
+     David A Beck <BKD@payserv.telekurs.com>.
+
+325) Use new emalloc/erealloc/estrdup functions (catch errors and exit).
+
+326) New PAM code that should work on both Solaris and Linux.
+
+327) Make sudo's usage info better when mutually exclusive args are given
+     and don't rely on argument order to detect this.  From Nick Andrew.
+
+328) In visudo, shift return value of system() by 8 to get the real exit value.
+
+Sudo 1.5.9 released.
+
+329) The runas user and NOPASSWD tags are now persistent across entries
+     in a command list (ie: cmnd1,cmnd2,cmnd3).  A PASSWD tag has been
+     added to reverse NOPASSWD.  The runas user and *PASSWD tags can be
+     overridden on a per-command basis at which point they become the
+     new default for the rest of the list.
+
+330) It is now possible to use the '!' operator in a runas list as
+     well as in a Cmnd_Alias, Host_Alias and User_Alias.
+
+331) In estrdup(), do the malloc ourselves so we don't need to rely on the
+     system strdup(3) which may or may not exist.  There is now no need to
+     provide strdup() for those w/o it.
+
+332) You can now specify a host list instead of just a host or alias
+     in a privilege list.  Ie: user=host1,host2,ALIAS,!host3 /bin/ls
+
+333) Stash the "safe" path to the command instead of stashing the struct
+     stat.  Should be safer.
+
+334) Now set $LOGNAME in addition to $USER.
+
+335) No longer use stdio in tgetpass()
+
+336) Don't use _PASSWD_LEN or PASS_MAX as we can't rely on them corresponding
+     to anything real.  Instead, we just use a max password size of 256
+     everywhere.
+
+337) Block keyboard-generated signals during startup and restore signal
+     mask before exec'ing the program.  We don't want the user to be
+     able to simply kill us and avoid logging.
+
+338) Rewrote timestamp handling.  For the default case, a directory is used
+     instead of a file.  For the tty-based case, the timestamp is just a
+     file in that directory (eg. /var/run/sudo/username/tty).  You now only
+     get the lecture once, even in the tty case.  The goal here is to allow
+     the tty and non-tty schemes to coexist, though it is worth noting that
+     when you update a tty file, the mtime of the dir gets updated too.
+
+339) The meaning of -k has changed to mean "invalidate the timestamp".
+     There is a new -K option to really remove the timestamp file/dir.
+
+340) New modular authentication API.  This fixes the rat's nest of
+     #ifdefs that was the old auth code.
+
+341) New logging functions.  log_error() now takes a variable number of
+     args ala printf() and log_auth() reacts to the return value of validate().
+
+342) If a user is not in the sudoers file they are still asked for a password.
+     This keeps someone who finds a user logged in to a terminal from being
+     able to tell whether or not the user is allowed to use sudo.
+
+343) New PAM code again, this time it should be correct.
+
+344) tgetpass() now has a flag to specify whether or not to turn
+     off echo while reading the password.  Used by the new PAM and
+     fwtk code.
+
+345) Fixed shadow password dectection on SCO.
+
+346) Sudo is now available under a BSD/Apache style license.  This is
+     possible because it no longer contains any of the original 1.1 code.
+
+347) Added configuration info when sudo is run with the -V flag by root.
+
+348) Change visudo tmp file from /etc/stmp -> /etc/sudoers.tmp since
+     Solaris uses stmp for shadow temp file.  Also rename _PATH_SUDO_SUDOERS
+     to _PATH_SUDOERS and _PATH_SUDO_STMP to _PATH_SUDOERS_TMP.
+
+349) Added configure option to set syslog priorities.
+
+350) Sudo now locks its log file to prevent mangled entries.
+
+351) Visudo now locks the sudoers temp file instead of bailing when
+     the temp file already exists.  This fixes the problem of stale
+     temp files but it does *require* that you not try to put the
+     temp file in a world-writable directory.  This shoud not be
+     an issue as the temp file should live in the same dir as sudoers.
+
+352) Fixed crypt() check in libufc.
+
+353) It is now possible to put a list of users as the first thing in a
+     user specification.  I don't suggest this but it makes the grammar
+     more uniform.
+
+354) Visudo will now warn about what it thinks are undefined aliases.
+     Since it can't be 100% sure these are just warnings, not errors.
+
+355) Add a --without-passwd option to configure that turns off
+     passwd/shadow file authentication.  Only usable with an alternate
+     authentication scheme.
+
+356) Add a --disable-authentication option to configure that causes sudo
+     to not require authentication by default.  The PASSWD tag can be
+     used to require authentication for an entry.
+
+357) Add a --with-devel option to add -Wall and uncomment yacc/lex
+     generation in Makefile.
+
+358) Zero out plaintext password after use (should do encrypted as well).
+
+359) Added real dependencies in Makefile.
+
+360) Deprecated --with-otp-only in favor of --without-passwd.
+
+361) Add --with-mail-if-no-host to send mail if a user tries to run sudo on
+     a host for which he/she is not authorized.
+
+362) Most of sudo now runs as root instead of the invoking user to
+     minimize the possibility of user control via signals or tracing.
+
+363) Now Support CIDR-style netmasks (ie: 128.138.0.0/16).
+
+364) In "sudo -l" mode, the type of the stored (expanded) alias was not
+     stored with the contents.  This could lead to incorrect output
+     if the sudoers file had different alias types with the same name.
+     Normal parsing (ie: not in '-l' mode) is unaffected.
+
+365) Now include strcasecmp() for those without it.
+
+366) Most compile-time options are now changable at runtime via
+     the 'Defaults' specification in the sudoers file.
+
+367) Added a -L flag to printout all the possible 'Defaults' parameters.
+
+368) It is now possible to escape "special" characters in usernames, hostnames,
+     etc with a backslash.
+
+369) Sudo will now accept a hostname/username/netgroupname that contains
+     almost any character in it.  It seems many people want to use '.'
+     and other non-alphanumerics in usernames.
+
+370) Fixed the root_sudo option.  Sudo was always complaining that root
+     was not allowed to run sudo if the root_sudo flag was turned off.
+
+371) tgetpass() now uses a function to read up until the end of line.
+     Fixes problems in a pipeline when a program sets the tty mode
+     to be character at a time.
+
+372) sudo now turns off core dumps via setrlimit (probably paranoia).
+
+Sudo 1.6 released.
+
+373) Better diagnostics on PAM failure.
+
+374) Killed shell_noargs option, it cannot work since the command needs to
+     be set before sudoers is parsed.
+
+375) Fixed the following Defaults options: set_home, fqdn, syslog, tty_tickets,
+     ticket_dir, insults.
+
+376) When using select() in tgetpass(), do a separate select before
+     each read to be sure we can timeout correctly.
+
+377) SecurID support compiles and works again.
+
+378) Fixed a bug parsing runas modifiers.  If a user spec contained multiple
+     runas specs, the latter ones may not be applied.
+
+379) #uid now works in a RunasAlias
+
+380) Don't ask the user for a password if the user is not allowed to run
+     the command and the authenticate flag (in sudoers) is false.
+
+381) Added configure check for initgroups(3).
+
+382) Use our own fnmatch() if there is no fnmatch.h, even if there is an
+     fnmatch() in libc.
+
+Sudo 1.6.1 released.
+
+383) Better behavior for -l and -v flags in conjunction with NOPASSWD and
+     added "verifypw" and "listpw" options.
+
+384) For HP-UX with cc, add the -Aa flag along with -D_HPUX_SOURCE.
+
+385) Fix compilation with K&R compilers.
+
+386) For netgroup host matching, match against the short version of the
+     hostname as well as the long one if they are different.
+
+387) Terminate passwd reading on '\r' in addition to '\n'
+
+388) Visudo used to loop endlessly if a user entered ^D at the whatnow
+     prompt.  EOF is now treaded as 'x' (exit w/o saving changes).
+
+389) The 'shell_noargs' runtime option is back based on a patch from
+     bguillory@email.com.
+
+390) Systems that return RLIM_INFINITY for RLIMIT_NOFILE (like AIX)
+     would loop for a very loing time during sudo startup.  A value of
+     RLIM_INFINITY is now ignored (getdtablesize/sysconf is used instead).
+
+391) Locking in visudo was broken.  We now lock the sudoers file, not the
+     sudoers temp file, which should be safe.
+
+392) PAM fixups: custom prompts now work correctly and errors are
+     dealt with more sanely.  Patches from Cloyce D. Spradling.
+
+Sudo 1.6.2 released.
+
+393) Users in the 'exempt' group shouldn't get their $PATH overridden
+     by 'secure-path'.  Patch from jmknoble@pobox.com.
+
+394) Pam now works on HP-UX 11.0, thanks to Jeff A. Earickson.
+
+395) Fixed a bug that caused an infinite loop when the password
+     timeout was disabled.
+
+396) It is now possible to set the path to the editor for visudo as well
+     as the flag that determines whether or not visudo will look at
+     $EDITOR in the sudoers file.
+
+397) configure now pulls in the values of LIBS, LDFLAGS, CPPFLAGS, etc
+     as the documentation says it ought to.
+
+398) Added rootpw, runaspw, and targetpw to prompt for the root, runas_default
+     and target user's passwords respectively (instead of the invoking user's
+     password).
+
+399) Added -S flag to force password read from stdin.
+
+400) Restore coredumpsize resource limit before exec'ing the child
+     process (sudo sets it to 0 internally).
+
+401) Truncate unencrypted password to 8 chars if encrypted password is exactly
+     13 characters (indicateing standard a DES password).  Many versions
+     of crypt() do this for you, but not all (like HP-UX's).
+
+402) Fixed a typo/thinko that broke secureware support for long passwords.
+
+403) Added a new command line switch '-c' to support BSD login classes.
+     The '-c' option can be used to sudo a command with specific resource
+     limits in the login.conf database.  This feature is optionally enabled
+     via the --with-logincap configure switch.  Based on a patch from
+     Michael D. Marchionna.
+
+404) Fixed a bug where sudo would hang around and consume CPU if we spawn
+     a long-running process.
+
+405) Deal with HP-UX password aging info tacked on to the end of the
+     encrypted password.
+
+406) Added set_logname run-time option.  When unset, sudo will not set
+     the USER and LOGNAME environment variables.
+
+407) Wildcards are now allowed in the hostnames specified in sudoers.
+     The 'fqdn' option is often required for this to be useful.
+
+408) Fixed a bug where host and user qualifiers in a Defaults entry were
+     not being used correctly and the entry was being applied globally.
+
+Sudo 1.6.3 released.
+
+409) Fixed targetpw, rootpw, and runaspw options when used with non-passwd
+     authentication (pam, etc).
+
+Sudo 1.6.3p1 released.
+
+410) When the targetpw flag is set, use the target username as part
+     of the timestamp path.
+
+Sudo 1.6.3p2 released.
+
+411) Fixed a bug that prevented the -H option from being useful.
+
+Sudo 1.6.3p3 released.
+
+412) Fixed a case where a string was used after it had been freed.
+
+Sudo 1.6.3p4 released.
+
+413) Fixed listpw and verifypw sudoers options.
+
+414) Do not write NUL when writing passwd prompt; hag@linnaean.org.
+
+Sudo 1.6.3p5 released.
+
+415) Fix word splitting bug that caused a segv for very long command line args.
+
+Sudo 1.6.3p6 released.
+
+416) Fix negation of path-type Defaults entries in a boolean context.
+
+Sudo 1.6.3p7 released.
+
+417) Visudo now checks for the existence of an editor and gives a sensible
+     error if it does not exist.
+
+418) The path to the editor for visudo is now a colon-separated list of
+     allowable editors.  If the user has $EDITOR set and it matches
+     one of the allowed editors that editor will be used.  If not,
+     the first editor that actually exists is used.
+
+419) Visudo now does its own fork/exec instead of calling system(3).
+
+420) Allow special characters (including '#') to be embedded in pathnames
+     if quoted by a '\\'.  The quoted chars will be dealt with by fnmatch().
+     Unfortunately, 'sudo -l' still prints the '\\'.
+
+421) Added the always_set_home option.
+
+422) Strip NLSPATH and PATH_LOCALE out from the environment to prevent
+     reading of protected files by a less privileged user.
+
+423) Added support for BSD authentication and associated -a flag.
+
+424) Added check for _innetgr(3) since NCR systems have this instead
+     of innetgr(3).
+
+425) Added stay_setuid option for systems that have libraries that perform
+     extra paranoia checks in system libraries for setuid programs.
+
+426) Environment munging is now done by hand.  The environment is zeroed
+     upon sudo startup and a new environment is built before the command
+     is executed.  This means we don't rely on getenv(3), putenv(3),
+     or setenv(3).
+
+427) Added a class of environment variables that are only cleared if they
+     contain '/' or '%' characters.
+
+428) Use stashed user_gid when checking against exempt gid since sudo
+     sets its gid to SUDOERS_GID, making getgid() return that, not the
+     real gid.  Fixes problem with setting exempt group == SUDOERS_GID.
+     Fix from Paul Kranenburg.
+
+429) Fixed file locking in visudo on NeXT which has a broken lockf().
+     Patch from twetzel@gwdg.de.
+
+430) Regenerated configure script with autoconf-2.52 (required some
+     tweaking of configure.in and friends).
+
+431) Added mail_badpass option to send mail when the user does not
+     authenticate successfully.
+
+432) Added env_reset Defaults option to reset the environment to
+     a clean slate.  Also implemented env_keep Defaults option
+     to specify variables to be preserved when resetting the
+     environment.
+
+433) Added env_check and env_delete Defaults options to allow the admin
+     to modify the builtin list of environment variables to remove.
+
+434) If timestamp_timeout < 0 then the timestamp never expires.  This
+     allows users to manage their own timestamps and create or delete
+     them via 'sudo -v' and 'sudo -k' respectively.
+
+435) Authentication routines that use sudo's tgetpass() now accept
+     ^C or ^Z at the password prompt and sudo will act appropriately.
+
+436) Added a check-only mode to visudo to check an existing sudoers
+     file for sanity.
+
+437) Visudo can now edit an alternate sudoers file.
+
+438) If sudo is configured with S/Key support and the system has
+     skeyaccess(3) use that to determine whether or not to allow
+     a normal Unix password or just S/Key.
+
+439) Fixed CIDR handling in sudoers.
+
+440) Fixed a segv if the local hostname is not resolvable and
+     the 'fqdn' option is set.
+
+441) "listpw=never" was not having an effect for users who did not
+     appear in sudoers--now it does.
+
+442) The --without-sendmail option now works on systems with
+     a /usr/include/paths.h file that defines _PATH_SENDMAIL.
+
+443) Removed the "secure_path" Defaults option as it does not work and
+     cannot work until the parser is overhauled.
+
+444) Added new -P flag and "preserve_groups" sudoers option to cause
+     sudo to preserve the group vector instead of setting it to that
+     of the target user.  Previously, if the target user was root
+     the group vector was not changed.  Now it is always changed unless
+     the -P flag or "preserve_groups" option was given.
+
+445) If find_path() fails as root, try again as the invoking user (useful
+     for NFS).  Idea from Chip Capelik.
+
+446) Use setpwent()/endpwent() and its shadow equivalents to be sure
+     the passwd/shadow file gets closed.
+
+447) Use getifaddrs(3) to get the list of network interfaces if it is
+     available.
+
+448) Dump list of local IP addresses and environment variables to clear
+     when 'sudo -V' is run as root.
+
+449) Reorganized the lexer a bit and added more states.  Sudo now does a
+     better job of parsing command arguments in the sudoers file.
+
+450) Wrap each call to syslog() with openlog()/closelog() since some
+     things (such as PAM) may call closelog(3) behind sudo's back.
+
+451) The LOGNAME and USER environment variables are now set if the user
+     specified a target uid and that uid exists in the password database.
+
+452) configure will no longer add the -g flag to CFLAGS by default.
+
+453) Now call pam_setcreds() to setup creds for the target user when
+     PAM is in use.  On Linux this often sets resource limits.
+
+454) If "make install" is run by non-root and the destination dir
+     is writable, install things normally but don't set owner and mode.
+
+455) The Makefile now supports installing in a shadow hierarchy
+     specified via the DESTDIR variable.
+
+456) config.h.in is now generated by autoheader.
+
+Sudo 1.6.4 released.
+
+457) Move the call to rebuild_env() until after MODE_RESET_HOME is set.
+     Otherwise, the set_home option has no effect.
+
+458) Fix use of freed memory when the "fqdn" flag is set.  This was
+     introduced by the fix for the "segv when gethostbynam() fails" bug.
+
+459) Add 'continue' statements to optimize the switch statement.
+     From Solar Designer.
+
+Sudo 1.6.4p1 released.
+
+460) Some special characters were not being escaped properly (e..g '\,')
+     in command line arguments and would cause a syntax error instead.
+
+461) "sudo -l" would not work if the always_set_home option was set.
+
+462) Added a configure option to disable use of POSIX saved IDs for
+     operating systems where these are broken.
+
+463) The SHELL environment variable was preserved from the user's environment
+     instead of being reset based on the passwd database even when the
+     "env_reset" option was set.
+
+Sudo 1.6.4p2 released.
+
+464) Added a configure option to cause mail sent by sudo to be run as
+     the invoking user instead of root.  Some people consider this to
+     be safer.
+
+465) If the mailer is being run as root, use a hard-coded environment
+     that is not influenced in any way by the invoking user's environment.
+
+466) Fixed the call to skeyaccess().  Patch from Phillip E. Lobbes.
+
+Sudo 1.6.5 released.
+
+467) Visudo could access memory that was already freed.
+
+468) If the skey.access file denied use of plaintext passwords sudo
+     would exit instead of allowing the user to enter an S/Key.
+
+Sudo 1.6.5p1 released.
+
+469) Older versions of BSDi have getifaddrs() but no freeifaddrs().
+
+470) BSDi has a fake setreuid() as do certain versions of FreeBSD and NetBSD.
+
+471) Ignore the return value of pam_setcred().  In Linux-PAM 0.75,
+     pam_setcred() will return PAM_PERM_DENIED even if the setcred function
+     of the module succeeds when pam_authenticate() has not been called.
+
+472) Avoid giving PAM a NULL password response, use the empty string instead.
+     This avoids a log warning when the user hits ^C at the password prompt
+     when Linux-PAM is in use.  This also prevents older versions of
+     Linux-PAM from dereferencing the NULL pointer.
+
+473) The user's password was not zeroed after use when AIX authentication,
+     BSD authentication, FWTK or PAM was in use.
+
+Sudo 1.6.5p2 released.
+
+474) Fixed compilation problem on HP-UX 9.x.
+
+475) Moved call to endpwent() and added a call to endgrent().
+
+476) Fixed a warning conflicting declaration of VOID with AFS.
+
+477) Fixed a security hole in prompt rewriting found by Global InterSec.
+
+Sudo 1.6.6 released.
diff --git a/HISTORY b/HISTORY
new file mode 100644 (file)
index 0000000..71d1d9e
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,36 @@
+A Brief history of sudo(8):
+
+The sudo philosophy originated at SUNY-Buffalo in the early 1980's.
+In the Summer of 1986, Garth Snyder enhanced sudo and released it
+to the public.  For the next 5 years, sudo was fed and watered by
+a handful of folks at CU-Boulder, including Bob Coggeshall, Bob
+Manchek, and Trent Hein.
+
+In 1991, Dave Hieb and Jeff Nieusma wrote a new version of sudo
+with an enhanced sudoers format under contract to a consulting firm
+called "The Root Group".  This version was later released under the
+GNU public license.
+
+In 1994, after maintaining sudo informally within CU-Boulder for
+some time, Todd Miller made a public release of "CU sudo" (version
+1.3) with bug fixes and support for more operating systems.  The
+"CU" was added to differentiate it from the "official" version from
+"The Root Group".
+
+In 1996, Todd, who had been maintaining sudo for several years in
+his spare time, brought sudo development under the umbrella of his
+consulting firm, Courtesan Consulting.  Courtesan remains committed
+to a free sudo and is sponsoring another sudo rewrite as well as
+continued development of the sudo 1.x code base.
+
+In 1999, the "CU" prefix was dropped from the name since there has
+been no formal release of sudo from "The Root Group" since 1991
+(the original authors now work elsewhere).  As of version 1.6, Sudo
+no longer contains any of the original "Root Group" code and is
+available with a BSD-style license.
+
+sudo, in its current form, is maintained by:
+
+       Todd Miller <Todd.Miller@courtesan.com>
+
+Todd continues to enhance sudo and fix bugs.
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..c2a9cf5
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,642 @@
+Installation instructions for Sudo 1.6.6
+========================================
+
+Sudo uses a `configure' script to probe the capabilities and type
+of the system in question.  In this release, `configure' takes many
+more options than it did before.  Please read this document fully
+before configuring and building sudo.  You may also wish to read the
+file INSTALL.configure which explains more about the `configure' script.
+
+Simple sudo installation
+========================
+
+For most systems and configurations it is possible simply to:
+
+    0) If you are upgrading from a previous version of sudo
+       please read the info in the UPGRADE file before proceeding.
+
+    1) If you previously ran `configure' on a different host
+       you will probably want to do a `make distclean' to remove
+       the old `config.cache' file.  Otherwise, `configure'
+       will complain and refuse to run.  Alternately, one can
+       simply `rm config.cache'.
+
+    2) Read the `OS dependent notes' section for any particular
+       "gotchas" relating to your operating system.
+
+    3) `cd' to the source or build directory and type `./configure'
+       to generate a Makefile and config.h file suitable for
+       building sudo.  Before you actually run configure you
+       should read the `Available configure options' section
+       to see if there are any special options you may want
+       or need.
+
+    4) Edit the configure-generated Makefile if you wish to
+       change any of the default paths (alternately you could
+       have changed the paths via options to `configure'.
+
+    5) Type `make' to compile sudo.  If you are building sudo
+       in a separate build tree (apart from the sudo source)
+       GNU make will probably be required.  If `configure' did
+       its job properly (and you have a supported configuration)
+       there won't be any problems.  If this doesn't work, take
+       a look at the files TROUBLESHOOTING and PORTING for tips
+       on what might have gone wrong.  Please mail us if you have a
+       fix or if you are unable to come up with a fix (address at EOF).
+
+    6) Type `make install' (as root) to install sudo, visudo, the
+       man pages, and a skeleton sudoers file.  Note that the install
+       will not overwrite an existing sudoers file.  You can also
+       install various pieces the package via the install-binaries,
+       install-man, and install-sudoers make targets.
+
+    7) Edit the sudoers file with `visudo' as necessary for your
+       site.  You will probably want to refer the sample.sudoers
+       file and sudoers man page included with the sudo package.
+
+    8) If you want to use syslogd(8) to do the logging, you'll need
+       to update your /etc/syslog.conf file.  See the sample.syslog.conf
+       file included in the distribution for an example.
+
+Available configure options
+===========================
+
+This section describes flags accepted by the sudo's `configure' script.
+Defaults are listed in brackets after the description.
+
+Configuration:
+  --cache-file=FILE
+       Cache test results in FILE
+
+  --config-cache, -C
+       Alias for `--cache-file=config.cache'
+
+  --help, -h
+       Print the usage/help info
+
+  --no-create, -n
+       Do not create output files
+
+  --quiet, --silent, -q
+       Do not print `checking...' messages
+
+Directory and file names:
+  --prefix=PREFIX
+       Install architecture-independent files in PREFIX This really only
+       applies to man pages.  [/usr/local]
+
+  --exec-prefix=EPREFIX
+       Install architecture-dependent files in EPREFIX This includes the
+       sudo and visudo executables.  [same as prefix]
+
+  --bindir=DIR
+       Install `sudo' in DIR [EPREFIX/bin]
+
+  --sbindir=DIR
+       Install `visudo' in DIR [EPREFIX/sbin]
+
+  --sysconfdir=DIR
+       Install `sudoers' file in DIR [/etc]
+
+  --mandir=DIR
+       Install man pages in DIR [PREFIX/man]
+
+  --srcdir=DIR
+       Find the sources in DIR [configure dir or ..]
+
+Special features/options:
+  --with-CC=PATH
+       Specifies path to C compiler you wish to use.
+
+  --with-incpath=DIR
+        Adds the specified directory (or directories) to CPPFLAGS
+        so configure and the compiler will look there for include
+        files.  Multiple directories may be specified as long as
+        they are space separated.
+       Eg: --with-incpath="/usr/local/include /opt/include"
+
+  --with-libpath=DIR
+        Adds the specified directory (or directories_ to SUDO_LDFLAGS
+        and VISUDO_LDFLAGS so configure and the compiler will look
+        there for libraries.  Multiple directories may be specified
+        as with --with-incpath.
+
+  --with-libraries=LIBRARY
+        Adds the specified library (or libaries) to SUDO_LIBS and
+        and VISUDO_LIBS so sudo will link against them.  If the
+        library doesn't start with `-l' or end in `.a' or `.o' a
+        `-l' will be prepended to it.  Multiple libraries may be
+        specified as long as they are space separated.
+
+  --with-csops
+       Add CSOps standard options.  You probably aren't interested in this.
+
+  --with-skey
+       Enable S/Key OTP (One Time Password) support.
+
+  --with-opie
+       Enable NRL OPIE OTP (One Time Password) support.
+
+  --with-SecurID[=DIR]
+       Enable SecurID support.  If specified, DIR is directory containing
+       sdiclient.a, sdi_athd.h, sdconf.h, and sdacmvls.h.
+
+  --with-fwtk[=DIR]
+       Enable TIS Firewall Toolkit (FWTK) 'authsrv' support. If specified,
+       DIR is the base directory containing the compiled FWTK package
+       (or at least the library and header files).
+
+  --with-kerb4
+       Enable kerberos v4 support.  Tested only with the Cygnus Network
+       Security package (CNS).  This uses kerberos passphrases for
+       authentication but does not use the kerberos cookie scheme.
+
+  --with-kerb5
+       Enable kerberos v5 support.  Tested against MIT Kerberos V,
+       release 1.1, although also expected to work against CNS.  This
+       This uses kerberos passphrases for authentication but does not
+       use the kerberos cookie scheme.  Will not work for Kerberos V
+       older than version 1.1.
+
+  --with-authenticate
+       Enable support for the AIX 4.x general authentication function.
+       This will use the authentication scheme specified for the user
+       on the machine.
+
+  --with-pam
+       Enable PAM support.  Tested on:
+           Redhat Linux 5.x, 6.0, and 6.1
+           Solaris 2.6 and 7
+           HP-UX 11.0
+        NOTE: on RedHat Linux you *must* install an /etc/pam.d/sudo file.
+       You may either use the sample.pam file included with sudo or use
+       /etc/pam.d/su as a reference.  On Solaris and HP-UX 11 systems
+       you should check (and understand) the contents of /etc/pam.conf.
+       Do a "man pam.conf" for more information and consider using the
+       "debug" option, if available, with your PAM libraries in
+       /etc/pam.conf to obtain syslog output for debugging purposes.
+
+  --with-AFS
+       Enable AFS support with kerberos authentication.  Should work under
+       AFS 3.3.  If your AFS doesn't have -laudit you should be able to
+       link without it.
+
+  --with-DCE
+       Enable DCE support.  Known to work on HP-UX 9.X, 10.X, and 11.0.
+       The use of PAM is recommended for HP-UX 11.X systems, since PAM is
+       fully implemented (this is not true for 10.20 and earlier versions).
+       Check to see that your 11.X (or other) system uses DCE via PAM by
+       looking at /etc/pam.conf to see if "libpam_dce" libraries are 
+       referenced there.  Other platforms may require source code and/or 
+       `configure' changes; you should check to see if your platform can 
+       access DCE via PAM before using this option.
+
+  --with-logincap
+       Enable support for BSD login classes where available (OS-dependent).
+       This adds support for the login classes specified in /etc/login.conf.
+       By default, a login class is not applied unless the 'use_loginclass'
+       option is defined in sudoers or the user specifies a class on the
+       command line.
+
+  --with-bsdauth
+        Enable support for BSD authentication on BSD/OS and OpenBSD.
+        This option implies --with-logincap.  It is not possible
+        to mix BSD authentication with other authentication methods
+        (and there really should be no need to do so).  Note that
+        only the newer BSD authentication API is supported.  If you
+        don't have /usr/include/bsd_auth.h then you cannot use this.
+
+  --disable-root-mailer
+        By default sudo will run the mailer as root when tattling
+        on a user so as to prevent that user from killing the mailer.
+        With this option, sudo will run the mailer as the invoking
+        user which some people consider to be safer.
+
+  --disable-saved-ids
+        Disable use of POSIX saved IDs.  Normally, sudo will try
+        to use POSIX saved IDs if they are supported.  However,
+        some implementations are broken.
+
+  --disable-setreuid
+        Disable use of the setreuid() function for operating systems
+        where it is broken.  4.4BSD has setreuid() but it doesn't
+        really work.
+
+  --disable-sia
+        Disable SIA support.  This is the "Security Integration
+        Architecture" on Digital UNIX. If you disable SIA sudo will
+        use its own authentication routines.
+
+  --disable-shadow
+        Disable shadow password support.  Normally, sudo will compile
+        in shadow password support and use a shadow password if it
+        exists.
+
+  --with-sudoers-mode=MODE
+        File mode for the sudoers file (octal).  Note that if you
+        wish to NFS-mount the sudoers file this must be group
+        readable.  Also note that this is actually set in the
+        Makefile.  The default mode is 0440.
+
+  --with-sudoers-uid=UID
+        User id that "owns" the sudoers file.  Note that this is
+        the numeric id, *not* the symbolic name.  Also note that
+        this is actually set in the Makefile.  The default is 0.
+
+  --with-sudoers-gid=GID
+        Group id that "owns" the sudoers file.  Note that this is
+        the numeric id, *not* the symbolic name.  Also note that
+        this is actually set in the Makefile.  The default is 0.
+
+  --with-execv
+       Use execv() to exec the command instead of execvp().  I can't think of
+       a reason to actually do this since execvp() is passed a fully qualified
+       pathname but someone might thoroughly distrust execvp().  Note that if
+       you define this you lose the ability to exec scripts that are missing
+       the '#!/bin/sh' cookie (like /bin/kill on SunOS and /etc/fastboot on
+       4.3BSD).  This is off by default.
+
+  --without-interfaces
+        This option keeps sudo from trying to glean the ip address
+        from each attached ethernet interface.  It is only useful
+        on a machine where sudo's interface reading support does
+        not work, which may be the case on some SysV-based OS's
+        using STREAMS.
+
+  --without-passwd
+        This option excludes authentication via the passwd (or
+        shadow) file.  It should only be used when another, alternate,
+        authentication scheme is in use.
+
+  --with-otp-only
+        This option is now just an alias for --without-passwd.
+
+The following options are also configurable at runtime:
+
+  --with-long-otp-prompt
+        When validating with a One Time Password scheme (S/Key or
+        OPIE), a two-line prompt is used to make it easier to cut
+        and paste the challenge to a local window.  It's not as
+        pretty as the default but some people find it more convenient.
+
+  --with-logging=TYPE
+        How you want to do your logging.  You may choose "syslog",
+        "file", or "both".  Setting this to "syslog" is nice because
+        you can keep all of your sudo logs in one place (see the
+        sample.syslog.conf file).  The default is "syslog".
+
+  --with-logfac=FACILITY
+        Determines which syslog facility to log to.  This requires
+        a 4.3BSD or later version of syslog.  You can still set
+        this for ancient syslogs but it will have no effect.  The
+        following facilities are supported: authpriv (if your OS
+        supports it), auth, daemon, user, local0, local1, local2,
+        local3, local4, local5, local6, and local7.
+
+  --with-goodpri=PRIORITY
+        Determines which syslog priority to log successfully
+        authenticated commands.  The following priorities are
+        supported: alert, crit, debug, emerg, err, info, notice,
+        and warning.
+
+  --with-badpri=PRIORITY
+        Determines which syslog priority to log unauthenticated
+        commands and errors.  The following priorities are supported:
+        alert, crit, debug, emerg, err, info, notice, and warning.
+
+  --with-logpath=PATH
+        Override the default location of the sudo log file and use
+        "path" instead.  By default will use /var/log/sudo.log if
+        there is a /var/log dir, falling back to /var/adm/sudo.log
+        or /usr/adm/sudo.log if not.
+
+  --with-loglen=NUMBER
+       Number of characters per line for the file log.  This is only used if
+       you are to "file" or "both".  This value is used to decide when to wrap
+       lines for nicer log files.  The default is 80.  Setting this to 0
+       will disable the wrapping.
+
+  --with-ignore-dot
+       If set, sudo will ignore '.' or '' (current dir) in $PATH.
+       The $PATH itself is not modified.
+
+  --with-mailto=USER|MAIL_ALIAS
+       User (or mail alias) that mail from sudo is sent to.
+       This should go to a sysadmin at your site.  The default is "root".
+
+  --with-mailsubject="SUBJECT OF MAIL"
+       Subject of the mail sent to the "mailto" user. The token "%h"
+       will expand to the hostname of the machine.
+       Default is "*** SECURITY information for %h ***".
+
+  --without-mail-if-no-user
+       Normally, sudo will mail to the "alertmail" user if the user invoking
+       sudo is not in the sudoers file.  This option disables that behavior.
+
+  --with-mail-if-no-host
+       Send mail to the "alermail" user if the user exists in the sudoers
+       file, but is not allowed to run commands on the current host.
+
+  --with-mail-if-noperms
+       Send mail to the "alermail" user if the user is allowed to use sudo but
+       the command they are trying is not listed in their sudoers file entry.
+
+  --with-passprompt="PASSWORD PROMPT"
+       Default prompt to use when asking for a password; can be overridden
+       via the -p option and the SUDO_PROMPT environment variable. Supports
+       two escapes: "%u" expands to the user's login name and "%h" expands
+       to the local hostname.  Default is "Password:".
+
+  --with-badpass-message="BAD PASSWORD MESSAGE"
+       Message that is displayed if a user enters an incorrect password.
+       The default is "Sorry, try again." unless insults are turned on.
+
+  --with-fqdn
+        Define this if you want to put fully qualified hostnames in the sudoers
+       file.  Ie: instead of myhost you would use myhost.mydomain.edu.  You may
+       still use the short form if you wish (and even mix the two).  Beware
+       that turning FQDN on requires sudo to make DNS lookups which may make
+       sudo unusable if your DNS is totally hosed.  Also note that you must
+       use the host's official name as DNS knows it.  That is, you may not use
+       a host alias (CNAME entry) due to performance issues and the fact that
+       there is no way to get all aliases from DNS.
+
+  --with-timedir=PATH
+       Override the default location of the sudo timestamp directory and
+       use "path" instead.
+
+  --with-sendmail=PATH
+       Override configure's guess as to the location of sendmail.
+
+  --without-sendmail
+       Do not use sendmail to mail messages to the "mailto" user.
+       Use only if don't run sendmail or the equivalent.
+
+  --with-umask=MASK
+       Umask to use when running the root command.  The default is 0022.
+
+  --without-umask
+       Preserves the umask of the user invoking sudo.
+
+  --with-runas-default=USER
+       The default user to run commands as if the -u flag is not specified
+       on the command line.  This defaults to "root".
+
+  --with-exempt=GROUP
+       Users in the specified group don't need to enter a password when
+       running sudo.  This may be useful for sites that don't want their
+       "core" sysadmins to have to enter a password but where Jr. sysadmins
+       need to.  You should probably use NOPASSWD in sudoers instead.
+
+  --with-passwd-tries=NUMBER
+       Number of tries a user gets to enter his/her password before sudo logs
+       the failure and exits.  The default is 3.
+
+  --with-timeout=NUMBER
+       Number of minutes that can elapse before sudo will ask for a passwd
+       again.  The default is 5, set this to 0 to always prompt for a password.
+
+  --with-password-timeout=NUMBER
+       Number of minutes before the sudo password prompt times out.
+       The default is 5, set this to 0 for no password timeout.
+
+  --with-tty-tickets
+       This makes sudo use a different ticket file for each user/tty combo.
+       Ie: instead of the ticket path being "username" it is "username/tty".
+       This is useful for "shared" accounts like "operator".  Note that this
+       means that there will be more files in the timestamp dir.  This is not
+       a problem if your system has a cron job to remove of files from /tmp
+       (or wherever you specified the timestamp dir to be).
+
+  --with-insults
+       Define this if you want to be insulted for typing an incorrect password
+       just like the original sudo(8).  This is off by default.
+
+  --with-all-insults
+       Include all the insult sets listed below.  You must either specify
+       --with-insults or enable insults in the sudoers file for this to
+       have any effect.
+
+  --with-classic-insults
+       Uses insults from sudo "classic."  If you just specify --with-insults
+       you will get the classic and CSOps insults.  This is on by default if
+       --with-insults is given.
+
+  --with-csops-insults
+       Insults the user with an extra set of insults (some quotes, some
+       original) from a sysadmin group at CU (CSOps).  You must specify
+       --with-insults as well for this to have any effect.  This is on by
+       default if --with-insults is given.
+
+  --with-hal-insults
+       Uses 2001-like insults when an incorrect password is entered.
+       You must either specify --with-insults or enable insults in the
+       sudoers file for this to have any effect.
+
+  --with-goons-insults
+       Insults the user with lines from the "Goon Show" when an incorrect
+       password is entered.  You must either specify --with-insults or
+       enable insults in the sudoers file for this to have any effect.
+
+  --with-secure-path[=PATH]
+       Path used for every command run from sudo(8).  If you don't trust the
+       people running sudo to have a sane 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."  You will need to customize the path
+       for your site.  NOTE: this is not applied to users in the group
+       specified by --with-exemptgroup.  If you do not specify a path,
+       "/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" is used.
+
+  --without-lecture
+       Don't print the lecture the first time a user runs sudo.
+
+  --with-editor=PATH
+       Specify the default editor path for use by visudo.  This may be
+       a single pathname or a colon-separated list of editors.  In
+       the latter case, visudo will choose the editor that matches
+       the user's USER environment variable or the first editor in
+       the list that exists.  The default is the path to vi on your system.
+
+  --with-env-editor
+       Makes visudo consult the EDITOR and VISUAL environment variables before
+       falling back on the default editor list (as specified by --with-editor).
+       Note that this may create a security hole as it allows the user to
+       run any arbitrary command as root without logging.  A safer alternative
+       is to use a colon-separated list of editors with the --with-env-editor
+       option.  visudo will then only use the EDITOR or VISUAL if they match
+       a value specified via --with-editor.
+
+  --disable-authentication
+        By default, sudo requires the user to authenticate via a
+        password or similar means.  This options causes sudo to
+        *not* require authentication.  It is possible to turn
+        authentication back on in sudoers via the PASSWD attribute.
+
+  --disable-root-sudo
+       Don't let root run sudo.  This can be used to prevent people from
+       "chaining" sudo commands to get a root shell by doing something
+       like "sudo sudo /bin/sh".
+
+  --enable-log-host
+       Log the hostname in the log file.
+
+  --enable-noargs-shell
+       If sudo is invoked with no arguments it acts as if the "-s" flag had
+       been given.  That is, it runs a shell as root (the shell is determined
+       by the SHELL environment variable, falling back on the shell listed
+       in the invoking user's /etc/passwd entry).
+
+  --enable-shell-sets-home
+       If sudo is invoked with the "-s" flag the HOME environment variable
+       will be set to the home directory of the target user (which is root
+       unless the "-u" option is used).  This option effectively makes the
+       "-s" flag imply "-H".
+
+  --disable-path-info
+       Normally, sudo will tell the user when a command could not be found
+       in their $PATH.  Some sites may wish to disable this as it could
+       be used to gather information on the location of executables that
+       the normal user does not have access to.  The disadvantage is that
+       if the executable is simply not in the user's path, sudo will tell
+       the user that they are not allowed to run it, which can be confusing.
+
+Shadow password and C2 support
+==============================
+
+Shadow passwords (also included with most C2 security packages) are
+supported on most major platforms for which they exist.  The
+`configure' script will attempt to determine if your system can use
+shadow passwords and include support for them if so.  Shadow password
+support is now compiled in by default (it doesn't hurt anything if you
+don't have them configured).  To disable the shadow password support,
+use the --disable-shadow option to configure.
+
+Shadow passwords are known to work on the following platforms:
+
+    SunOS 4.x
+    Solaris 2.x
+    HP-UX >= 9.x
+    Ultrix 4.x
+    Digital UNIX
+    IRIX >= 5.x
+    AIX >= 3.2.x
+    ConvexOS with C2 security (not tested recently)
+    Linux
+    SCO >= 3.2.2
+    Pyramid DC/OSx
+    UnixWare
+    SVR4 (and variants using standard SVR4 shadow passwords)
+    4.4BSD based systems (including OpenBSD, NetBSD, FreeBSD, and BSD/OS)
+    OS's using SecureWare's C2 security.
+
+OS dependent notes
+==================
+
+OpenBSD < 2.2 and NetBSD < 1.2.1:
+    The fdesc filesystem has a bug wrt /dev/tty handling that
+    causes sudo to hang at the password prompt.  The workaround
+    is to run configure with --with-password-timeout=0
+
+Solaris 2.x:
+    You need to have a C compiler in order to build sudo.
+    Since Solaris 2.x does not come with one by default this
+    means that you either need to have purchased the unbundled Sun
+    C compiler or have a copy of the GNU C compiler (gcc).
+    The SunSoft Catalyst CD should contain gcc binaries for
+    Solaris.  You can also get them from various places on the
+    net, including http://www.sunfreeware.com/
+    NOTE: sudo will *not* build with the sun C compiler in BSD
+          compatibility mode (/usr/ucb/cc).  Sudo is designed to
+          compile with the standard C compiler (or gcc) and will
+          not build correctly with /usr/ucb/cc.  You can use the
+          `--with-CC' option to point `configure' to the non-ucb
+          compiler if it is not the first cc in your path.  Some
+          sites link /usr/ucb/cc to gcc; configure will not notice
+          this an still refuse to use /usr/ucb/cc, so make sure gcc
+          is also in your path if your site is setup this way.
+    Also: Many versions of Solaris come with a broken syslogd.
+         If you have having problems with sudo logging you should
+         make sure you have the latest syslogd patch installed.
+         This is a problem for Solaris 2.4 and 2.5 at least.
+
+AIX 3.2.x:
+    I've had various problems with the AIX C compiler producing
+    incorrect code when the -O flag was used.  When optimization
+    is not used, the problems go away.  Gcc does not appear
+    to have this problem.
+
+    Also, the AIX 3.2.x lex will not work with sudo's parse.lex.
+    This should not be a problem as sudo comes shipped with
+    a pre-generated lex.yy.c (created by flex).  If you want
+    to modify the lex tokenizer, make sure you grab a copy of
+    flex from ftp.ee.lbl.gov (also available on most GNU mirrors)
+    and sudo will use that instead.
+
+Ultrix 4.x:
+    Ultrix still ships with the 4.2BSD syslog(3) which does not
+    allow things like logging different facilities to different
+    files, redirecting logs to a single loghost and other niceties.
+    You may want to just grab and install:
+       ftp://gatekeeper.dec.com/pub/DEC/jtkohl-syslog-complete.tar.Z
+    (available via anonymous ftp) which is a port if the 4.3BSD
+    syslog/syslogd that is backwards compatible with the Ultrix version.
+    I recommend it highly.  If you do not do this you probably want
+    to run configure with --with-logging=file
+
+Digital UNIX:
+    By default, sudo will use SIA (Security Integration Architecture)
+    to validate a user.  If you want to use an alternate authentication
+    method that does not go through SIA, you need to use the
+    --disable-sia option to configure.  If you use gcc to compile
+    you will get warnings when building interfaces.c.  These are
+    harmless but if they really bug you, you can edit
+    /usr/include/net/if.h around line 123, right after the comment:
+       /* forward decls for C++ */
+    change the line:
+       #ifdef __cplusplus
+    to:
+       #if defined(__cplusplus) || defined(__GNUC__)
+    If you don't like the idea of editing the system header file
+    you can just make a copy in gcc's private include tree and
+    edit that.
+
+Linux:
+    NOTE: Reportedly, Linux's execvp(3) doesn't always execute
+         scripts that lack the "#!/some/shell" header correctly.
+         The workaround is to give all your scripts a proper
+         header.
+    Versions of glibc 2.x previous to 2.0.7 have a broken lsearch().
+    You will need to either upgrade to glibc-2.0.7 or use sudo's
+    version of lsearch().  To use sudo's lsearch(), comment out
+    the "#define HAVE_LSEARCH 1" line in config.h and add lsearch.o
+    to the LIBOBJS line in the Makefile.
+
+    If you are using a Linux kernel older than 2.4 it is not possible
+    to access the sudoers file via NFS.  This is due to a bug in
+    the Linux client-side NFS implementation that has since been
+    fixed.  There is a workaround on the sudo ftp site, linux_nfs.patch,
+    if you need to NFS-mount sudoers on older Linux kernels.
+
+    Linux kernels 2.2.16-2.2.19 appear to have broken POSIX saved
+    ID support.  You must run configure with the --disable-saved-ids
+    flag to get a working sudo.
+
+Mac OS X:
+    It has been reported that for sudo to work on Mac OS X it must
+    either be built with the --with-password-timeout=0 option or the
+    password timeout must be disabled in the Defaults line in the
+    sudoers file.  If sudo just hangs when you try to enter a password,
+    you need to disable the password timeout (Note: this is not a bug
+    in sudo).
+
+SCO ODT:
+    You'll probably need libcrypt_i.a available via anonymous ftp
+    from sosco.sco.com.  The necessary files are /SLS/lng225b.Z
+    and /SLS/lng225b.ltr.Z.
+
+Dynix:
+    Some people have experienced problems building sudo with gcc
+    on Dynix.  If you experience problems compiling sudo using gcc
+    on Dynix, try using the native compiler (cc).  You can do so
+    by removing the config.cache file and then re-running configure
+    with the --with-CC=cc option.
diff --git a/INSTALL.configure b/INSTALL.configure
new file mode 100644 (file)
index 0000000..a2c8722
--- /dev/null
@@ -0,0 +1,181 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..9756b3d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,65 @@
+Sudo is distributed under the following BSD-style license:
+
+   Copyright (c) 1994-1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+   3. The name of the author may not be used to endorse or promote products
+      derived from this software without specific prior written permission
+      from the author.
+
+   4. Products derived from this software may not be called "Sudo" nor
+      may "Sudo" appear in their names without specific prior written
+      permission from the author.
+
+   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+   THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Additionally, lsearch.c, fnmatch.c, getcwd.c, snprintf.c, strcasecmp.c
+and fnmatch.3 bear the following UCB license:
+
+   Copyright (c) 1987, 1989, 1990, 1991, 1993, 1994
+       The Regents of the University of California.  All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+   3. Neither the name of the University nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..1a5f76f
--- /dev/null
@@ -0,0 +1,368 @@
+#
+# Copyright (c) 1996, 1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission
+#    from the author.
+#
+# 4. Products derived from this software may not be called "Sudo" nor
+#    may "Sudo" appear in their names without specific prior written
+#    permission from the author.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# @configure_input@
+#
+# $Sudo: Makefile.in,v 1.225 2002/04/18 15:41:30 millert Exp $
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+authdir = $(srcdir)/auth
+VPATH = @srcdir@
+
+# Compiler & tools to use
+CC = @CC@
+LEX = flex
+YACC = @YACC@
+NROFF = nroff
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(srcdir)/install-sh -c
+
+# Libraries
+LIBS = @LIBS@
+NET_LIBS = @NET_LIBS@
+SUDO_LIBS = @SUDO_LIBS@ @AFS_LIBS@ $(LIBS) $(NET_LIBS)
+
+# C preprocessor flags
+CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+SUDO_LDFLAGS = @SUDO_LDFLAGS@ $(LDFLAGS)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+mandir = @mandir@
+
+# Directory in which to install sudo.
+sudodir = $(bindir)
+
+# Directory in which to install visudo
+visudodir = $(sbindir)
+
+# Directory in which to install the sudoers file
+sudoersdir = $(sysconfdir)
+
+# Directory in which to install the man page
+mantype = @MANTYPE@
+mansectsu = @mansectsu@
+mansectform = @mansectform@
+mandirsu = $(mandir)/$(mantype)$(mansectsu)
+mandirform = $(mandir)/$(mantype)$(mansectform)
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# User, group, and mode the sudoers file should be "owned" by (configure)
+sudoers_uid = @SUDOERS_UID@
+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)
+
+#### End of system configuration section. ####
+
+SHELL = /bin/sh
+
+PROGS = @PROGS@
+
+SRCS = alloc.c alloca.c check.c def_data.c defaults.c env.c fileops.c \
+       find_path.c fnmatch.c getcwd.c getspwuid.c goodpath.c \
+       interfaces.c lex.yy.c lsearch.c logging.c parse.c parse.lex \
+       parse.yacc set_perms.c sigaction.c snprintf.c strcasecmp.c strerror.c \
+       sudo.c sudo.tab.c testsudoers.c tgetpass.c utime.c visudo.c \
+       $(AUTH_SRCS)
+
+AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
+           auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
+           auth/secureware.c auth/securid.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/fnmatch.h emul/search.h emul/utime.h
+
+AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
+
+PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o
+
+SUDOBJS = check.o env.o getspwuid.o goodpath.o fileops.o find_path.o \
+         interfaces.o logging.o parse.o set_perms.o sudo.o tgetpass.o \
+         $(AUTH_OBJS) $(PARSEOBJS)
+
+VISUDOBJS = visudo.o fileops.o goodpath.o find_path.o $(PARSEOBJS)
+
+TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS)
+
+LIBOBJS = @LIBOBJS@ @ALLOCA@
+
+VERSION = 1.6.6
+
+DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES HISTORY INSTALL INSTALL.configure \
+           LICENSE Makefile.in PORTING README RUNSON TODO TROUBLESHOOTING \
+           UPGRADE aclocal.m4 aixcrypt.exp config.guess config.h.in \
+            config.sub configure configure.in def_data.in fnmatch.3 indent.pro \
+           install-sh mkdefaults mkinstalldirs pathnames.h.in sample.pam \
+           sample.syslog.conf sample.sudoers sudo.cat sudo.man.in sudo.pod \
+           sudoers sudoers.cat sudoers.man.in sudoers.pod visudo.cat \
+           visudo.man.in visudo.pod auth/API
+
+BINFILES= BUGS CHANGES HISTORY LICENSE README TODO 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
+
+SUDODEP = $(srcdir)/sudo.h $(srcdir)/compat.h $(srcdir)/defaults.h \
+         $(srcdir)/logging.h config.h def_data.h pathnames.h
+
+AUTHDEP = $(SUDODEP) $(authdir)/sudo_auth.h
+
+INSDEP = $(srcdir)/ins_2001.h $(srcdir)/ins_classic.h $(srcdir)/ins_csops.h \
+        $(srcdir)/ins_goons.h $(srcdir)/insults.h
+
+all: $(PROGS)
+
+.SUFFIXES: .o .c .h .lex .yacc .man .cat
+
+.c.o:
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $<
+
+.man.cat:
+       @rm -f $(srcdir)/$@
+       $(NROFF) -man $< > $(srcdir)/$@
+
+sudo: $(SUDOBJS) $(LIBOBJS)
+       $(CC) -o $@ $(SUDOBJS) $(LIBOBJS) $(SUDO_LDFLAGS) $(SUDO_LIBS)
+
+visudo: $(VISUDOBJS) $(LIBOBJS)
+       $(CC) -o $@ $(VISUDOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
+
+testsudoers: $(TESTOBJS) $(LIBOBJS)
+       $(CC) -o $@ $(TESTOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
+
+# Uncomment the following if you want "make clean" to clean the parser
+@DEV@PARSESRCS = sudo.tab.h sudo.tab.c lex.yy.c
+
+# Uncomment the following if you intend to modify parse.yacc
+@DEV@sudo.tab.c sudo.tab.h: parse.yacc
+@DEV@  rm -f sudo.tab.h sudo.tab.c
+@DEV@  $(YACC) -d -b sudo $(srcdir)/parse.yacc
+
+# 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 following if you intend to modify def_data.in
+@DEV@def_data.h def_data.c: 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)
+env.o: env.c $(SUDODEP)
+fileops.o: fileops.c $(SUDODEP)
+find_path.o: find_path.c $(SUDODEP)
+getspwuid.o: getspwuid.c $(SUDODEP)
+goodpath.o: goodpath.c $(SUDODEP)
+logging.o: logging.c $(SUDODEP)
+set_perms.o: set_perms.c $(SUDODEP)
+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
+lsearch.o: lsearch.c config.h compat.h emul/search.h
+snprintf.o: snprintf.c config.h compat.h
+strcasecmp.o: strcasecmp.c config.h
+strerror.o: strerror.c config.h
+utime.o: utime.c config.h pathnames.h compat.h emul/utime.h
+
+# Authentication functions live in "auth" dir and so need extra care
+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)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/afs.c
+aix_auth.o: $(authdir)/aix_auth.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/aix_auth.c
+bsdauth.o: $(authdir)/bsdauth.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/bsdauth.c
+dce.o: $(authdir)/dce.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/dce.c
+fwtk.o: $(authdir)/fwtk.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/fwtk.c
+kerb4.o: $(authdir)/kerb4.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/kerb4.c
+kerb5.o: $(authdir)/kerb5.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/kerb5.c
+pam.o: $(authdir)/pam.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/pam.c
+passwd.o: $(authdir)/passwd.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/passwd.c
+rfc1938.o: $(authdir)/rfc1938.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/rfc1938.c
+secureware.o: $(authdir)/secureware.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/secureware.c
+securid.o: $(authdir)/securid.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/securid.c
+sia.o: $(authdir)/sia.c $(AUTHDEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/sia.c
+
+sudo.man.in: $(srcdir)/sudo.pod
+       @rm -f $(srcdir)/$@
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" > $@ )
+
+sudo.man: sudo.man.in
+       CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
+
+sudo.cat: sudo.man
+
+visudo.man.in: $(srcdir)/visudo.pod
+       @rm -f $(srcdir)/$@
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" > $@ )
+
+visudo.man: visudo.man.in
+       CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
+
+visudo.cat: visudo.man
+
+sudoers.man.in: $(srcdir)/sudoers.pod
+       @rm -f $(srcdir)/$@
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" > $@ )
+
+sudoers.man:: sudoers.man.in
+       CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
+
+sudoers.cat: sudoers.man
+
+install: install-dirs install-binaries install-sudoers install-man
+
+install-dirs:
+       $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(sudodir) \
+           $(DESTDIR)$(visudodir) $(DESTDIR)$(sudoersdir) \
+           $(DESTDIR)$(mandirsu) $(DESTDIR)$(mandirform)
+
+install-binaries: $(PROGS)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 4111 -s sudo $(DESTDIR)$(sudodir)/sudo
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s visudo $(DESTDIR)$(visudodir)/visudo
+
+install-sudoers:
+       test -f $(DESTDIR)$(sudoersdir)/sudoers || \
+           $(INSTALL) -O $(sudoers_uid) -G $(sudoers_gid) -M $(sudoers_mode) \
+               $(srcdir)/sudoers $(DESTDIR)$(sudoersdir)/sudoers
+
+install-man:
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(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)
+@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
+
+mostlyclean: clean
+
+distclean: clean
+       -rm -f Makefile *.man pathnames.h config.h config.status config.cache \
+              config.log $(PARSESRCS)
+
+clobber: distclean
+
+realclean: distclean
+       rm -f TAGS tags
+
+cleandir: realclean
+
+dist:
+       rm -f ../sudo-$(VERSION).tar.gz
+       ( cd .. ; TF="/tmp/sudo.dist$$$$" ; rm -f $$TF ; for i in $(DISTFILES) ; \
+         do echo sudo-$(VERSION)/$$i >> $$TF ; done ; \
+         tar Ocf sudo-$(VERSION).tar \
+         `cat $$TF` && gzip --best sudo-$(VERSION).tar && rm -f $$TF)
+       ls -l ../sudo-$(VERSION).tar.gz
+
+bindist:
+       @mkdir tmp.`arch -l`
+       @mkdir tmp.`arch -l`/sudo-$(VERSION)
+       ( \
+         tdir=tmp.`arch -l`/sudo-$(VERSION) ; \
+         for i in $(BINFILES) ; 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 ; \
+         cp $(srcdir)/INSTALL.binary $$tdir/INSTALL ; \
+         sed -e 's/@_MANTYPE@/$(mantype)/g' -e 's/@_mansectsu@/$(mansectsu)/g' \
+             -e 's/@_mansectform@/$(mansectform)/g' $(srcdir)/Makefile.binary \
+             > $$tdir/Makefile ; \
+       )  
+       strip sudo
+       strip visudo
+       ( cd tmp.`arch -l` && tar Ocf ../sudo-$(VERSION)-`arch -l`.tar sudo-$(VERSION) )
+       gzip --best sudo-$(VERSION)-`arch -l`.tar
+       rm -rf tmp.`arch -l`
diff --git a/PORTING b/PORTING
new file mode 100644 (file)
index 0000000..1d42ebd
--- /dev/null
+++ b/PORTING
@@ -0,0 +1,91 @@
+Sudo porting hints
+==================
+
+Before trying to port sudo to a new architecture, please join the
+sudo-workers mailing list (see the README file) and ask if anyone
+has a port working or in-progress.  Sudo should be fairly easy to
+port.  Since it uses a configure script, most of the work is often
+done for you.  As long as your operating system is reasonably POSIX
+compliant porting should be easy.  If your operating system has a
+separate library for POSIX compatibility you may need to add it by
+using configure's --with-libraries option.
+
+If your OS is an SVR4 derivative (or some approximation thereof), it may
+be sufficient to tell configure you are runnng SVR4, something like:
+    configure foo-bar-sysv4
+where foo is the hardware architecture and bar is the vendor.
+
+A possible pitfall is getdtablesize(2) which is used to get the
+maximum number of open files the process can have.  If an OS has
+the POSIX sysconf(2) it will be used instead of getdtablesize(2).
+ulimit(2) or getrlimit(2) can also be used on some OS's.  If all
+else fails you can use the value of NOFILE in <sys/param.h>.
+
+Also, some operating systems have a broken implementation of POSIX
+saved IDs.  If sudo prints the error message "seteuid(0) failed,
+your operating system may have broken POSIX saved ID support" this
+means saved IDs are not implemented properly.  You should run
+configure with the "--disable-saved-ids" option and rebuild sudo.
+
+Sudo tries to clear the environment of dangerous environment variables
+such as LD_* to prevent shared library spoofing.  If you are porting
+sudo to a new OS that has shared libraries you'll want to mask out
+the variables that allow one to change the shared library path.
+See initial_badenv_table() in env.c to see how this is done for
+various operating systems.
+
+It is possible that on a really weird system, tgetpass() may not
+compile.  (The most common cause for this is that the "fd_set" type
+is not defined in a place that sudo expects it to be.  If you can
+find the header file where "fd_set" is typedef'd, have tgetpass.c
+include it and send in a bug report.)
+Alternately, tgetpass.c may compile but not work (nothing happens
+at the Password: prompt).  It is possible that your C library
+contains a broken or unusable crypt() function--try linking with
+-lcrypt if that exists.  Another possibility is that select() is
+not fully functional; running configure with --with-password-timeout=0
+will disable the use of select().  If sudo prompts you for a
+password but never accepts it, see below.
+
+Sudo detects and recognizes most common shadow password schemes
+automatically.  If you find that sudo is not accepting your password
+and you are sure that it has been typed in correctly there are two
+likely problems.  One possibility is that your C library has a
+broken crypt() function (see above).  The other is that your operating
+system is using shadow passwords and sudo has not detected that
+fact.  Look in config.h to see what, if any, shadow password scheme
+was detected.  The most common are SVR4 (HAVE_GETSPNAM will be
+defined) and SecureWare (HAVE_GETPRPWNAM will be defined).  Check
+the manual pages on your system for "getspnam" and "getprpwnam".
+If one of those exist but the appropriate define does not exist in
+config.h then the problem is most likely that those routines live
+in a library that sudo does not know to link against.  The manual
+page should tell you what library this is.  You can then use the
+--with-libraries option to configure to tell sudo to link with the
+library in question.  For example:
+    --with-libraries='-lgen'
+would cause sudo to link in libgen which contains "getspnam" on SCO
+systems.
+
+If you are trying to port to a system without standard Berkeley
+networking you may find that interfaces.c will not compile.  This
+is most likely on OS's with STREAMS-based networking.  It should
+be possible to make it work by modifying the ISC streams support
+(see the _ISC #ifdef's).  However, if you don't care about ip address
+and network address support, you can just run configure with the
+--without-interfaces flag to get a do-nothing load_interfaces()
+stub function.
+
+Sudo wants POSIX signals (sigaction and friends).  If your system
+lacks sigaction but has the 4.3BSD sigvec() function, sigvec() will
+be used instead via the wrapper functions in sigaction.c.  It is
+not currently possible to use the old SVR3 and 4.2BSD signals, but
+this is due more to my lack of a test machine than anything else.
+
+If you port sudo to a new architecture, please send the output of
+"configure", the config.log file and your changes to:
+    sudo@courtesan.com
+
+If you are unable to get sudo working, and you are willing to
+give me an account on a machine, send mail to sudo@courtesan.com.
+Note, however, that I can't make any promises.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9ab603d
--- /dev/null
+++ b/README
@@ -0,0 +1,100 @@
+This is Sudo version 1.6.6
+
+The sudo philosophy
+===================
+Sudo is a program designed to allow a sysadmin to give limited root privileges
+to users and log root activity.  The basic philosophy is to give as few
+privileges as possible but still allow people to get their work done.
+
+Where to find sudo
+==================
+Before you try and build sudo, *please* make sure you have the current
+version.  The latest sudo may always be gotten via anonymous ftp
+from ftp.sudo.ws in the directory /pub/sudo/.
+The distribution is sudo-M.m.tar.gz where `M' is the major
+version number and `m' is the minor version number.
+BETA versions of sudo may also be available.  If you join
+the `sudo-workers' mailing list you will get the BETA announcements
+(see the `Mailing lists' section below).
+
+What's new
+==========
+For a history of sudo please see the HISTORY file that came with this
+release.
+
+For a complete list of changes, see the CHANGES file.  For a summary,
+see the web page, http://www.sudo.ws/sudo/.
+
+If you are upgrading from an earlier version of Sudo, please see
+the UPGRADE file.
+
+NOTE: Starting with sudo 1.5.7 the configuration method has changed
+      significantly as compared to previous versions.  All options
+      are now set via the configure script.  See the `INSTALL' file
+      for a list of all the configure options.
+
+System requirements
+===================
+To build sudo from the source distribution you need a machine running
+UN*X (most flavors of BSD, SYSV, or POSIX will do), a working C
+compiler, and the make utility.
+
+If you wish to modify the parser then you will need flex version
+2.5.2 or later and either bison or byacc (sudo comes with a pre-flex'd
+tokenizer and pre-yacc'd grammar parser).  You'll also have to
+uncomment a few lines from the Makefile or run configure with the
+--with-devel option.  You can get flex via anonymous ftp from
+ftp://ftp.ee.lbl.gov/pub/flex* as well as any GNU mirror.  You can
+get GNU bison from ftp://prep.ai.mit.edu/pub/gnu/bison* or any GNU
+mirror.
+
+Building the release
+====================
+Please read the installation guide in the `INSTALL' file before
+trying to build sudo.  The `RUNSON' file contains a list of of
+platforms that this version of sudo is known to work on.  If you
+can add to this list, please send mail to sudo@sudo.ws.  If
+something goes wrong you may want to refer to the `TROUBLESHOOTING'
+file.
+
+Copyright
+=========
+Sudo is distributed under a BSD-style license.
+Please refer to the `LICENSE' file included with the release for details.
+
+Mailing lists
+=============
+sudo-announce  This list receives announcements whenever a new version
+               of sudo is released.
+               http://www.sudo.ws/mailman/listinfo/sudo-announce
+
+sudo-users     This list is for questions and general discussion about sudo.
+               http://www.sudo.ws/mailman/listinfo/sudo-users
+
+sudo-workers   This list is for people working on and porting sudo.
+               http://www.sudo.ws/mailman/listinfo/sudo-workers
+
+To subscribe to a list, visit its url (as listed above) and enter
+your email address to subscribe.  Digest versions are available but
+these are fairly low traffic lists so the digest versions are not
+a significant win.
+
+Mailing list archives are also available.  See the mailing list web sites
+for the appropriate links.
+
+Web page
+========
+There is a sudo `web page' at http://www.sudo.ws/sudo/
+that contains an overview of sudo as well as pointers to BETA versions
+and other useful info.
+
+Bug reports
+===========
+A list of known bugs may be found in the `BUGS' file.  If you have
+found what you believe to be a bug, you can file a bug report with
+the sudo bug database, on at web at http://www.sudo.ws/bugs/.
+
+Please read over the `TROUBLESHOOTING' file *before* submitting a
+bug report.  When reporting bugs, please be sure to include the
+version of sudo you are using as well as the platform you are running
+it on.
diff --git a/RUNSON b/RUNSON
new file mode 100644 (file)
index 0000000..d0de749
--- /dev/null
+++ b/RUNSON
@@ -0,0 +1,158 @@
+Systems that Sudo is known to run on.
+Just because a specific version of your OS is not listed with
+the current version of sudo does not mean it won't work...
+
+ Op. System    CPU     Compilers       Sudo    Reported         Special
+Name   Rev     Arch    Used            Version By               Options
+=======        ======= ======= =============== ======= ===============  ===============
+Auspex 1.6.1   sun4    bundled cc      1.3.4   Alek Komarnitsky none
+SunOS  4.1.3   sun4    bundled cc      1.6.6   Todd Miller      none
+SunOS  4.1.3   sun4    gcc2.9.5.2      1.6.6   Todd Miller      none
+SunOS  4.1.3   sun4    gcc2.7.2.1      1.5.3   Todd Miller      --with-kerb4
+SunOS  4.1.3   sun4    gcc2.9.5.2      1.6.6   Todd Miller      --with-skey
+Solaris        2.5.1   sparc   SC4.0           1.5.6p1 Brian Jackson    none 
+Solaris        2.5.1   sun4u   gcc2.7.2.3      1.5.4   Leon von Stauber none
+Solaris        2.5.1   i386    gcc2.7.2        1.5.4   Leon von Stauber none
+Solaris        2.6     sparc   gcc2.9.5.2      1.6.3   Todd Miller      none
+Solaris        2.6     sparc   gcc2.9.5.2      1.6.3   Todd Miller      --with-pam
+Solaris        2.6     i386    gcc2.9.5.2      1.6.3   Todd Miller      none
+Solaris        2.6     i386    gcc2.9.5.2      1.6.3   Todd Miller      --with-pam
+Solaris        2.6     sun4u   Workshop 6.2    1.6.3p7 Donna Dickerson  none
+Solaris        2.6     i386    unbundled cc    1.5.8p2 Udo Keller       none
+Solaris        7       i386    gcc 2.8.1       1.6.1   Ido Dubrawsky    none
+Solaris        7       i386    Workshop 5.0    1.6     Brian Jackson    none
+Solaris        7       sun4u   egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+Solaris        7       sparc   SC4.2           1.6.6   Todd Miller      none
+Solaris        7       sun4u   Workshop 6.2    1.6.3p7 Donna Dickerson  none
+Solaris        7       sparc   2.95.2          1.6.6   Todd Miller      --with-skey
+Solaris        2.6     sun4u   egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+Solaris        8       sparc   2.95.2          1.6.6   Todd Miller      --with-skey
+Solaris        8       sparc   SC4.2           1.6.6   Todd Miller      none
+Solaris        8       sun4u   Workshop 6.2    1.6.3p7 Donna Dickerson  none
+ISC    4.0     i386    bundled cc      1.4     Andy Smith       none
+ISC    4.0     i386    gcc2.7.0        1.4     Andy Smith       none
+ISC    4.1     i386    bundled cc      1.4     Andy Smith       none
+ISC    4.1     i386    gcc2.7.0        1.4     Andy Smith       none
+RISCos 4_52    mips    bundled cc      1.3.7   Andy Smith       --with-getpass
+SCO    3.2.2   i386    bundled cc      1.3.4   David Meleedy    --with-getpass
+SCO    5.0.5   i386    gcc 98q2        1.6.3p7 Alan Pittman     none
+HP-UX  9.05    hp700   gcc2.7.2.1      1.5.3   Todd Miller      none
+HP-UX  9.05    hp700   gcc2.7.2.1      1.5.3   Todd Miller      --with-kerb4
+HP-UX  9.07    hp700   unbundled cc    1.5     Alek Komarnitsky --with-C2
+HP-UX  9.05    hp700   unbundled cc    1.4     Todd Miller      none
+HP-UX  10.10   hp700   unbundled cc    1.6.6   Todd Miller      --with-skey
+HP-UX  10.20   hp700   gcc2.9.5.2      1.6.6   Todd Miller      --with-skey
+HP-UX  10.20   hp700   bundled cc      1.6.6   Todd Miller      none
+HP-UX  10.20   hp700   gcc 2.95.2      1.6.2   Jeff Earickson   --with-DCE
+HP-UX  11.00   hp700   ansi-c          1.5.5b1 Alek Komarnitsky --with-C2
+HP-UX  11.00   hp700   bundled cc      1.5.5p5 Lynn Osburn      none
+HP-UX  11.00   hp700   HP C compiler   1.6.2   Jeff Earickson   --with-pam
+HP-UX  11.11   hp800   HP C compiler   1.6.5p2 Bill Marmagas    --with-pam
+Ultrix 4.3     mips    bundled cc      1.6.3b2 Todd Miller      none
+Ultrix 4.3     mips    gcc2.7.2.1      1.5.9   Todd Miller      --with-skey
+IRIX   4.05H   mips    gcc2.6.3        1.5.3   Todd Miller      none
+IRIX   4.05H   mips    unbundled cc    1.4     Todd Miller      none
+IRIX   5.2     mips    MipsPro C       1.5.6p1 Brian Jackson    none 
+IRIX   5.3     mips    MipsPro C       1.5.6p1 Brian Jackson    none 
+IRIX   6.2     mips    MipsPro C       1.5.6p1 Brian Jackson    none 
+IRIX   6.5     mips    MipsPro C       1.5.6p1 Brian Jackson    none 
+IRIX   5.3     mips    unbundled cc    1.6.6   Todd Miller      none
+IRIX   5.3     mips    gcc2.9.5.2      1.6.6   Todd Miller      --with-skey
+IRIX   5.3     mips    gcc2.7.2.1      1.5.3   Todd Miller      --with-kerb4
+IRIX   5.3     mips    unbundled cc    1.4     Wallace Winfrey  --with-C2
+IRIX   6.2     mips    unbundled cc    1.5     Alek Komarnitsky --with-C2
+IRIX   6.2     mips    MipsPro C       1.6     Brian Jackson    none
+IRIX   6.3     mips    MipsPro C       1.6     Brian Jackson    none
+IRIX   6.4     mips    MipsPro C       1.58p2  Brian Jackson    none
+IRIX   6.4     mips    egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+IRIX   6.5     mips    unbundled cc    1.5.4   Brian Jackson    --with-C2
+IRIX   6.5     mips    MipsPro 7.2.1   1.6     Brian Jackson    none
+IRIX   6.5     mips    gcc 2.8.1       1.6rc1  Jordan Baker     none
+IRIX   6.5     mips    egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+IRIX   6.5     mips    MipsPRO 7.3.1   1.6.5p2 David Kaelbling  --with-pam
+IRIX   6.5     mips    MipsPRO 7.3.1   1.6.5p2 David Kaelbling  --with-C2
+NEXTSTEP 2.1   m68k    bundled cc      1.3.7   Todd Miller      none
+NEXTSTEP 3.2   m68k    bundled cc      1.5.5b4 Todd Miller      --with-skey
+NEXTSTEP 3.2   i386    bundled cc      1.3.2   Jonathan Adams   none
+NEXTSTEP 3.3   i386    bundled cc      1.4     Jonathan Adams   none
+NEXTSTEP 3.3   sparc   bundled cc      1.5.3   Mike Kienenberger none
+DEC UNIX 3.2c  alpha   bundled cc      1.5.3   Todd Miller      none
+DEC UNIX 4.0D  alpha   bundled cc      1.6.6   Todd Miller      --with-skey
+DEC UNIX 4.0   alpha   gcc-2.7.2.1     1.5.3   Todd Miller      --with-kerb4
+DEC UNIX 4.0D  alpha   bundled cc      1.5.3   Randall R. Cable --with-C2
+DEC UNIX 4.0E  alpha   bundled cc      1.5.9p2 Vangelis Haniotakis none
+Tru64  5.1     alpha   bundled cc      1.6.6   Todd Miller      none
+AIX    3.2.X   rs6000  bundled cc      1.4     Todd Miller      none
+AIX    4.1.3   PowerPC gcc-2.7.0       1.4     Bob Shair        none
+AIX    4.1.4   rs6000  gcc-2.8.1       1.6.2p2 Todd Miller      none
+AIX    4.1.4   rs6000  gcc-2.8.1       1.6.2p2 Todd Miller      --with-authenticate
+AIX    4.1.5   rs6000  gcc-2.7.2.3     1.4.4   Daniel Robitaille none
+AIX    4.1.X   rs6000  bundled cc      1.5.3   Robin Jackson    --with-AFS
+AIX    4.1.X   PowerPC bundled cc      1.5.3   Robin Jackson    --with-AFS
+AIX    4.2.1   rs6000  bundled cc      1.5.7p4 Sam Mabjish      none
+AIX    4.2.1   rs6000  egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+AIX    4.3     rs6000  bundled cc      1.5.4   Leon von Stauber none
+AIX    4.3.2   rs6000  egcs 1.1.2      1.5.9p4 Scott Kinnane    none
+ConvexOS 9.1   convex  bundled cc      1.3.6   Todd Miller      none
+ConvexOS 9.1   convex  gcc2.4.5        1.3.6   Todd Miller      none
+BSD/OS 4.1     i386    cc              1.6.3   Todd Miller      --with-skey
+OpenBSD        2.X     all     gcc-2.95.2      1.6.6   Todd Miller      none
+OpenBSD        3.0     all     gcc-2.95.3      1.6.6   Todd Miller      none
+FreeBSD        1.1     i386    gcc             1.3.2   Dworkin Muller   none
+FreeBSD        2.0.5   i386    gcc             1.3.4   Dworkin Muller   none
+FreeBSD        3.2     i386    gcc 2.7.2.1     1.6     Brian Jackson    none
+Linux  1.2.13  i486    gcc-2.7.0       1.4     Michael Forman   none
+Linux  1.2.8   i486    gcc-2.5.8       1.3.5   Ted Coady        --with-C2
+Linux  2.0.15  i586    gcc-2.7.2.1     1.5     Danny Barron     none
+Linux  2.0.34  i586    egcs-2.91.57    1.5.6p2 Darrin Chandler  none
+Linux  2.0.36  i586    gcc-2.7.2.3     1.5.7p4 Nathan Haney     none
+Linux  2.0.33pl1 m68k  gcc 2.7.2.3     1.5.6   James Troup      none
+Linux  2.2.12  i586    gcc-2.95.2      1.6.3   Todd Miller      --with-pam
+Linux  2.4.9   i686    gcc-2.96        1.6.6   Todd Miller      --with-pam
+Linux  2.2.13  alpha   egcs-2.91.66    1.6.3   Todd Miller      --with-pam
+Linux  2.2.6-15 ppc    egcs-1.1.2      1.5.9p4 Barbara Schelkle none
+Linux  2.0.34  mips    gcc-2.7.2       1.6     Tristan Roddis   none
+UnixWare 1.1.4 i386    gcc-2.7.2       1.4     Michael Hancock  none
+UnixWare 7.1.1 i686    cc              1.6.5p1 Mike Petkau      none
+Pyramid DC/OSx 1.1     bundled cc      1.4     Les Schuettpelz  none
+ATT    SVR4.x  i486    Metaware CC     1.4     Chris Ellington  none
+SINIX  5.42    R4000   bundled cc      1.4     Paul Tuininga    none
+SINIX  5.43    mips    PyrC 5.0A00     1.5.6p2 Brian Jackson    none
+SINIX  5.43    mips    CDS++ V1        1.58p2  Brian Jackson    none
+SINIX  5.44    mips    PyrC 5.0A00     1.5.6p2 Brian Jackson    none
+ReliantUNIX 5.43 mips  CDS++ V1        1.6     Brian Jackson    none
+ReliantUNIX 5.44 mips  CDS++ V1        1.6     Brian Jackson    none
+ReliantUNIX 5.45 mips  CDS++ V1        1.6     Brian Jackson    none
+NCR    2.03    3400    bundled cc      1.4     Mark Rauschkolb  --with-getpass
+NCR    3.00    5100    bundled cc      1.4     Mark Rauschkolb  --with-getpass
+Unicos/mk 2.0.2.19 T3E  bundled cc     1.5.3   Mike Kienenberger none
+Unicos  9.0.2.2  YMP   bundled cc      1.5.4   Mike Kienenberger none
+Unicos  10.0.0.1 J90   bundled cc      1.5.4   Mike Kienenberger none
+DG/UX  R4.11MU03 i686  gcc             1.5.3   Ramesh Vasudevan none
+DG/UX  R4.20MU02 x86   cc              v1.5.6p5 Jared Crapo     none
+DG/UX  R4.20MU07 x86   gcc             1.6.3p7 Rob Tocher       none
+NetBSD  1.2[A-G] x86   gcc-2.7.2.{1,2} 1.5.3   Jason R. Thorpe  none
+NetBSD  1.2[A-G] m68k  gcc-2.7.2.{1,2} 1.5.3   Jason R. Thorpe  none
+NetBSD  1.2[A-G] sparc  gcc-2.7.2.{1,2} 1.5.3  Jason R. Thorpe  none
+NetBSD 1.3.2   alpha   gcc-2.7.2.2     1.5.4p1 Ted Spradley     none
+MacOSX Server  ppc     cc              1.5.9p4 Matt Warner      --with-password-timeout=0
+Dynix/ptx 4.1.5        i386    gcc2.7.2        1.5.4   Leon von Stauber none
+Dynix/ptx 4.4.2        Sequent bundled cc      1.5.4p1 Larry Mascarenhas none
+Dynix/ptx 4.4.3        Sequent bundled cc      1.5.6p2 Sandra Birgerson none
+Dynix/ptx 4.4.4        Sequent bundled cc      1.5.9p2 Jason Merritt    none
+Dynix/ptx 4.4.6        Sequent bundled cc      1.6     Larry Mascarenhase none
+Dynix/ptx 4.4.7        Sequent bundled cc      1.6.2p1 Dana Kaempen     --with-CC=cc
+DC-OSx 1.1-9x  mips    PyrC 4.0A20     1.5.6p2 Brian Jackson    none
+HI-UX/MPP 02-03        sr2201  bundled cc      1.5.4   Ben Edgington    none
+SVR4   4.4     m88k    bundled gcc     1.6rc1  Gerry Belanger   CFLAGS=
+NonStop-UX B32 CO-1475 cc              1.5.9p3 Andrei Panfilenko none
+MacOS  X       ppc     bundled cc      1.6.3p7 Gary Danko       none
+
+Systems on which Sudo is expected to run on but hasn't been tested.
+If you can verify any of these, please send mail to sudo@courtesan.com
+
+ Op. System    CPU     Compilers       Sudo    Reported         Special
+Name   Rev     Arch    Used            Version By               Options
+=======        ======= ======= =============== ======= ===============  ===============
+ConvexOS 9.1   convex  cc or gcc       1.5.6   YOUR NAME HERE   --with-C2
+Ultrix 4.x     mips    cc or gcc       1.5.6   YOUR NAME HERE   --with-C2
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..8bfda23
--- /dev/null
+++ b/TODO
@@ -0,0 +1,114 @@
+TODO list (most will be addressed in sudo 2.0)
+
+01) Redo parsing to be more like op(8) with true command aliases where
+    can specify uid, gid(s) and part/all of the environment.
+
+02) Add a SHELLS reserved word that checks against /etc/shells.
+
+03) Make the sudoers file accessible via NIS, Hesiod, and maybe NetInfo.
+
+04) Add a -h (?) flag to sudo for a history mechanism.
+
+05) Add an option to set LD_LIBRARY_PATH?
+
+06) Add Prog_Alias facility (Prog_Alias VI = /usr/secure/bin/vi +args).
+
+07) check for <net/errno.h> in configure and include it in sudo.c if it exists.
+
+08) Add generic STREAMS support for getting interfaces and netmasks.
+
+09) Add support for "safe scripts" by checking for shell script
+    cookie (first two bytes are "#!") and execing the shell outselves
+    after doing the stat to guard against spoofing.  This should avoid
+    the race condition caused by going through namei() twice...
+
+10) Overhaul testsudoers to use things from parse.o so we don't reimplement
+    things.
+
+11) Make runas_user a struct "runas" with user and group components.
+    (maybe uid and gid too???)
+
+12) Add -g group/gid option.
+
+13) Should be able to mix Cmnd_Alias's and command args.  Ie:
+       pete   ALL=PASSWD [A-z]*,!PASSWD root
+    where PASSWD was defined to be /usr/bin/passwd.
+    This requires the arg parsing to happen in the yacc grammer.
+    At the very least, commands and args have to become separate
+    tokens in the lexer.
+
+14) Add a per-tty restriction?  Ie: only can run foo from /dev/console.
+
+15) Add test for how to read ether interfaces in configure script
+
+16) Add configure check for $(CC) -R and use it in addition to -L
+
+17) An option to make "sudo -s" use the target user's shell might be nice
+    (and more like su).  Overlaps with the upcoming -i option.
+
+18) Add configure option to enable old behavior of visudo (O_EXCL)?
+    --without-sudoers-lock?
+
+19) Profile sudo again (is the yacc grammar optimal?)
+
+20) Zero out encrypted passwords after use.  Use an Exit function or
+    some such (have to hook in to emalloc() and friends).
+    Hard (impossible?) to be thorough w/ atexit/on_exit.
+
+21) Make 'sudo -l user' if run as root do a "sudo -l" output for the specified
+    user.
+
+22) Use strtol() and strtoul(), not atoi()
+
+23) In parse.yacc get rid of unneeded '{ ; }'
+
+24) Look into %e, %p, %k in parse.lex
+
+25) Make syslog stuff work on vanilla ultrix
+
+26) Implement date_format and log_format options.
+
+27) Add support for: Default:user@host
+
+28) Do login-style -sh hack for sudo -s? (new option or do it always?)
+
+29) Make visudo rcs-aware
+
+30) Add support for parsing multiple sudoers files.  Basically make
+    _PATH_SUDOERS be a colon-separated list of pathname like EDITOR.
+    Requires _PATH_SUDOERS_TMP chages (perhaps "%s.tmp").
+
+31) Add -i (simulate initial login) option as per 946 +sudo
+    (requires two-pass parser).  Also add "default_path" Defaults option
+    to go with it.  (See MINUS_I.patch)
+
+32) Some people want to be able to specify a special password in sudoers
+    in addition or instead of the normal one.  The best argument for
+    this so far is to be able to use separate passwords for the
+    target users that are not the passwd file ones.
+
+33) Add support for trusted users.  E.g. allow user to run a certain
+    command regardless of what dir it is in if it is owned by the
+    trusted user.
+
+34) Add mechanism to choose logfile based on RunasUser
+
+35) Split the parser into two stages.  The first parse checks for
+    syntax and sets the Defaults options and sets up the
+    data structures to check a user.  The second stage does
+    the actual user check.
+
+36) Add a flag similar to '-l' but that spits out sudo commands in
+    a format suitable for cut & paste (requires parser overhaul first).
+
+37) Someone wants a recursive version of the dir specifier.  Ie:
+    SOME_MODIFIER:/usr/local/ to allow anything under /usr/local to be run.
+
+38) An option to set the shell to the target user would make sense.
+    See other target user-related issues above.
+
+39) Add an option (-D) to dump the defaults after the sudoers file
+    has been parsed.  Should only be available to root and should
+    allow a -u user modifier.
+
+40) For sudo 1.7 wipe out the environment by default.
diff --git a/TROUBLESHOOTING b/TROUBLESHOOTING
new file mode 100644 (file)
index 0000000..6e54d78
--- /dev/null
@@ -0,0 +1,175 @@
+Troubleshooting tips and FAQ for Sudo
+=====================================
+
+Q) When I run configure, it says "C compiler cannot create executables".
+A) This usually means you either don't have a working compiler.  This
+   could be due to the lack of a license or that some component of the
+   compiler suite could not be found.  Check config.log for clues as
+   to why this is happening.  On many systems, compiler components live
+   in /usr/ccs/bin which may not be in your PATH environment variable.
+
+Q) Sudo compiles but when I run it I get "Sorry, sudo must be setuid root."
+   and sudo quits.
+A) Sudo must be setuid root to do its work.  You need to do something like
+   `chmod 4111 /usr/local/bin/sudo'.  Also, the filesystem sudo resides
+   on must *not* be mounted with the nosuid mount option or sudo will
+   not be able to work.  Another possibility is you may have '.' in
+   your $PATH before the directory containing sudo.  If you are going
+   to have '.' in your path you should make sure it is at the end.
+
+Q) Sudo compiles but when I run it I get "seteuid(0) failed, your operating
+   system may have broken POSIX saved ID support\nTry running configure with
+   --disable-saved-ids" and sudo quits.
+A) The operating system you are running probably has broken support for
+   POSIX saved IDs.  You should run configure with the "--disable-saved-ids"
+   option and rebuild sudo.
+
+Q) Sudo never gives me a chance to enter a password using PAM, it just
+   says 'Sorry, try again.' three times and quits.
+A) You didn't setup PAM to work with sudo.  On Linux this generally
+   means installing sample.pam as /etc/pam.d/sudo.
+
+Q) Sudo is setup to log via syslog(3) but I'm not getting any log
+   messages.
+A) Make sure you have an entry in your syslog.conf file to save
+   the sudo messages (see the sample.syslog.conf file).  The default
+   log facility is local2 (changeable via configure).  Don't forget
+   to send a SIGHUP to your syslogd so that it re-reads its conf file.
+   Also, remember that syslogd does *not* create log files, you need to
+   create the file before syslogd will log to it (ie: touch /var/log/sudo).
+   Note:  the facility ("local2.debug") must be separated from the 
+         destination ("/var/adm/sudo.log" or "@loghost") by
+         tabs, *not* spaces.  This is a common error.
+
+Q) When sudo asks me for my password it never accepts what I enter even
+   though I know I entered my password correctly.
+A) If your system uses shadow passwords, it is possible that sudo
+   didn't detect this.  Take a look at the generated config.h file
+   and verify that the C function used for shadow password lookups
+   was detected.  For instance, for SVR4-style shadow passwords,
+   HAVE_GETSPNAM should be defined (you can search for the string
+   "shadow passwords" in config.h with your editor).  Note that
+   there is no define for 4.4BSD-based shadow passwords since that
+   just uses the standard getpw* routines.
+
+Q) I don't want the sudoers file in /etc, how can I specify where it
+   should go?
+A) Use the --sysconfdir option to configure.  Ie:
+   configure --sysconfdir=/dir/you/want/sudoers/in
+
+Q) Can I put the sudoers file in NIS/NIS+ or do I have to have a
+   copy on each machine?
+A) There is no support for making an NIS/NIS+ map/table out of
+   the sudoers file at this time.  A good way to distribute the
+   sudoers file is via rdist(1).  It is also possible to NFS-mount
+   the sudoers file.
+
+Q) I don't run sendmail on my machine.  Does this mean that I cannot
+   use sudo?
+A) No, you just need to run use the --without-sendmail argument to configure
+   or add "!mailerpath" to the Defaults line in /etc/sudoers.
+
+Q) When I run visudo it uses vi as the editor and I hate vi.  How
+   can I make it use another editor?
+A) Your best bet is to run configure with the --with-env-editor switch.
+   This will make visudo use the editor specified by the user's
+   EDITOR environment variable.  Alternately, you can run configure
+   with the --with-editor=/path/to/another/editor.
+
+Q) Sudo appears to be removing some variables from my environment, why?
+A) Sudo removes the following "dangerous" environment variables
+   to guard against shared library spoofing, shell voodoo, and
+   kerberos server spoofing.
+     IFS
+     LOCALDOMAIN
+     RES_OPTIONS
+     HOSTALIASES
+     NLSPATH
+     PATH_LOCALE
+     TERMINFO
+     TERMINFO_DIRS
+     TERMPATH
+     TERMCAP
+     ENV
+     BASH_ENV
+     LC_ (if it contains a '/' or '%')
+     LANG (if it contains a '/' or '%')
+     LANGUAGE (if it contains a '/' or '%')
+     LD_*
+     _RLD_*
+     SHLIB_PATH (HP-UX only)
+     LIBPATH (AIX only)
+     KRB_CONF (kerb4 only)
+     KRBCONFDIR (kerb4 only)
+     KRBTKFILE (kerb4 only)
+     KRB5_CONFIG (kerb5 only)
+     VAR_ACE (SecurID only)
+     USR_ACE (SecurID only)
+     DLC_ACE (SecurID only)
+
+Q) How can I keep sudo from asking for a password?
+A) To specify this on a per-user (and per-command) basis, use the 'NOPASSWD'
+   tag right before the command list in sudoers.  See the sudoers man page
+   and sample.sudoers for details.  To disable passwords completely,
+   run configure with the --without-passwd option or add "!authenticate"
+   to the Defaults line in /etc/sudoers.  You can also turn off authentication
+   on a per-user or per-host basis using a user or host-specific Defaults
+   entry in sudoers.
+
+Q) When I run configure, it dies with the following error:
+   "no acceptable cc found in $PATH".
+A) /usr/ucb/cc was the only C compiler that configure could find.
+   You need to tell configure the path to the "real" C compiler
+   via the --with-CC option.  On Solaris, the path is probably
+   something like "/opt/SUNWspro/SC4.0/bin/cc".  If you have gcc
+   that will also work.
+
+Q) When I run configure, it dies with the following error:
+   Fatal Error: config.cache exists from another platform!
+   Please remove it and re-run configure.
+A) configure caches the results of its tests in a file called
+   config.cache to make re-running configure speedy.  However,
+   if you are building sudo for a different platform the results
+   in config.cache will be wrong so you need to remove config.cache.
+   You can do this by "rm config.cache" or "make realclean".
+   Note that "make realclean" will also remove any object files
+   and configure temp files that are laying around as well.
+
+Q) I built sudo on a Solaris >= 2.6 machine but the resulting binary
+   doesn't work on Solaris <= 2.5.1.  Why?
+A) Starting with Solaris 2.6, snprintf(3) is included in the standard
+   C library.  To build a version of sudo on a >= 2.6 machine that
+   will run on a <= 2.5.1 machine, edit config.h and comment out the lines:
+       #define HAVE_SNPRINTF 1
+       #define HAVE_VSNPRINTF 1
+   and run make.
+
+Q) When I run "visudo" it says "sudoers file busy, try again later."
+   and doesn't do anything.
+A) Someone else is currently editing the sudoers file with visudo.
+
+Q) When I try to use "cd" with sudo it says "cd: command not found".
+A) "cd" is a shell builtin, you can't run it as a command since
+   a child process (sudo) cannot affect the current working directory
+   of the parent (your shell).
+
+Q) When I try to use "cd" with sudo the command completes without
+   errors but nothing happens.
+A) Some SVR4-derived OS's include a /usr/bin/cd command for reasons
+   unfathomable.  A "cd" command is totally useless since a child process
+   cannot affect the current working directory of the parent (your shell).
+
+Q) When I run sudo it says I am not alllowed to run the command as root
+   but I don't want to run it as root, I want to run it as another user.
+   My sudoers file entry looks like:
+    bob        ALL=(oracle) ALL
+A) The default user sudo tries to run things as is always root, even if
+   the invoking user can only run commands as a single, specific user.
+   This may change in the future but at the present time you have to
+   work around this using the 'runas_default' option in sudoers.
+   For example:
+    Defaults:bob       runas_default=oracle
+   would achieve the desired result ofr the preceding sudoers fragment.
+
+Q) How do you pronounce `sudo'?
+A) soo-doo (for superuser do).
diff --git a/UPGRADE b/UPGRADE
new file mode 100644 (file)
index 0000000..1b04e60
--- /dev/null
+++ b/UPGRADE
@@ -0,0 +1,60 @@
+Notes on upgrading from an older release
+========================================
+
+o Upgrading from a version prior to 1.6:
+
+    As of sudo 1.6, parsing of runas entries and the NOPASSWD tag
+    has changed.  Prior to 1.6, a runas specifier applied only to
+    a single command directly following it.  Likewise, the NOPASSWD
+    tag only allowed the command directly following it to be run
+    without a password.  Starting with sudo 1.6, both the runas
+    specifier and the NOPASSWD tag are "sticky" for an entire
+    command list.  So, given the following line in sudo < 1.6
+
+       millert ALL=(daemon) NOPASSWD:/usr/bin/whoami,/bin/ls
+
+    millert would be able to run /usr/bin/whoami as user daemon
+    without a password and /bin/ls as root with a password.
+
+    As of sudo 1.6, the same line now means that millert is able
+    to run run both /usr/bin/whoami and /bin/ls as user daemon
+    without a password.  To expand on this, take the following
+    example:
+
+       millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, (root) /bin/ls, \
+           /sbin/dump
+
+    millert can run /usr/bin/whoami as daemon and /bin/ls and
+    /sbin/dump as root.  No password need be given for either
+    command.  In other words, the "(root)" sets the default runas
+    user to root for the rest of the list.  If we wanted to require
+    a password for /bin/ls and /sbin/dump the line could be written
+    thusly:
+
+       millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, \
+           (root) PASSWD:/bin/ls, /sbin/dump
+
+    Additionally, sudo now uses a per-user timestamp directory
+    instead of a timestamp file.  This allows tty timestamps to
+    simply be files within the user's timestamp dir.  For the
+    default, non-tty case, the timestamp on the directory itself
+    is used.
+
+    Also, the temporary file used by visudo is now /etc/sudoers.tmp
+    since some versions of vipw on systems with shadow passwords use
+    /etc/stmp for the temporary shadow file.
+
+o Upgrading from a version prior to 1.5:
+
+    By default, sudo expects the sudoers file to be mode 0440 and
+    to be owned by user and group 0.  This differs from version 1.4
+    and below which expected the sudoers file to be mode 0400 and
+    to be owned by root.  Doing a `make install' will set the sudoers
+    file to the new mode and group.  If sudo encounters a sudoers
+    file with the old permissions it will attempt to update it to
+    the new scheme.  You cannot, however, use a sudoers file with
+    the new permissions with an old sudo binary.  It is suggested
+    that if have a means of distributing sudo you distribute the
+    new binaries first, then the new sudoers file (or you can leave
+    sudoers as is and sudo will fix the permissions itself as long
+    as sudoers is on a local filesystem).
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..8a156b0
--- /dev/null
@@ -0,0 +1,346 @@
+dnl Local m4 macors for autoconf (used by sudo)
+dnl
+dnl Copyright (c) 1994-1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl
+dnl XXX - should cache values in all cases!!!
+dnl
+dnl checks for programs
+
+dnl
+dnl check for sendmail
+dnl
+AC_DEFUN(SUDO_PROG_SENDMAIL, [AC_MSG_CHECKING(for sendmail)
+if test -f "/usr/sbin/sendmail"; then
+    AC_MSG_RESULT(/usr/sbin/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/sbin/sendmail")
+elif test -f "/usr/lib/sendmail"; then
+    AC_MSG_RESULT(/usr/lib/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/lib/sendmail")
+elif test -f "/usr/etc/sendmail"; then
+    AC_MSG_RESULT(/usr/etc/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/etc/sendmail")
+elif test -f "/usr/ucblib/sendmail"; then
+    AC_MSG_RESULT(/usr/ucblib/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/ucblib/sendmail")
+elif test -f "/usr/local/lib/sendmail"; then
+    AC_MSG_RESULT(/usr/local/lib/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/local/lib/sendmail")
+elif test -f "/usr/local/bin/sendmail"; then
+    AC_MSG_RESULT(/usr/local/bin/sendmail)
+    SUDO_DEFINE(_PATH_SUDO_SENDMAIL, "/usr/local/bin/sendmail")
+else
+    AC_MSG_RESULT(not found)
+fi
+])dnl
+
+dnl
+dnl check for vi
+dnl
+AC_DEFUN(SUDO_PROG_VI, [AC_MSG_CHECKING(for vi)
+if test -f "/usr/bin/vi"; then
+    AC_MSG_RESULT(/usr/bin/vi)
+    SUDO_DEFINE(_PATH_VI, "/usr/bin/vi")
+elif test -f "/usr/ucb/vi"; then
+    AC_MSG_RESULT(/usr/ucb/vi)
+    SUDO_DEFINE(_PATH_VI, "/usr/ucb/vi")
+elif test -f "/usr/bsd/vi"; then
+    AC_MSG_RESULT(/usr/bsd/vi)
+    SUDO_DEFINE(_PATH_VI, "/usr/bsd/vi")
+elif test -f "/bin/vi"; then
+    AC_MSG_RESULT(/bin/vi)
+    SUDO_DEFINE(_PATH_VI, "/bin/vi")
+elif test -f "/usr/local/bin/vi"; then
+    AC_MSG_RESULT(/usr/local/bin/vi)
+    SUDO_DEFINE(_PATH_VI, "/usr/local/bin/vi")
+else
+    AC_MSG_RESULT(not found)
+fi
+])dnl
+
+dnl
+dnl check for mv
+dnl
+AC_DEFUN(SUDO_PROG_MV, [AC_MSG_CHECKING(for mv)
+if test -f "/usr/bin/mv"; then
+    AC_MSG_RESULT(/usr/bin/mv)
+    SUDO_DEFINE(_PATH_MV, "/usr/bin/mv")
+elif test -f "/bin/mv"; then
+    AC_MSG_RESULT(/bin/mv)
+    SUDO_DEFINE(_PATH_MV, "/bin/mv")
+elif test -f "/usr/ucb/mv"; then
+    AC_MSG_RESULT(/usr/ucb/mv)
+    SUDO_DEFINE(_PATH_MV, "/usr/ucb/mv")
+elif test -f "/usr/sbin/mv"; then
+    AC_MSG_RESULT(/usr/sbin/mv)
+    SUDO_DEFINE(_PATH_MV, "/usr/sbin/mv")
+else
+    AC_MSG_RESULT(not found)
+fi
+])dnl
+
+dnl
+dnl check for bourne shell
+dnl
+AC_DEFUN(SUDO_PROG_BSHELL, [AC_MSG_CHECKING(for bourne shell)
+if test -f "/bin/sh"; then
+    AC_MSG_RESULT(/bin/sh)
+    SUDO_DEFINE(_PATH_BSHELL, "/bin/sh")
+elif test -f "/usr/bin/sh"; then
+    AC_MSG_RESULT(/usr/bin/sh)
+    SUDO_DEFINE(_PATH_BSHELL, "/usr/bin/sh")
+elif test -f "/sbin/sh"; then
+    AC_MSG_RESULT(/sbin/sh)
+    SUDO_DEFINE(_PATH_BSHELL, "/sbin/sh")
+elif test -f "/usr/sbin/sh"; then
+    AC_MSG_RESULT(/usr/sbin/sh)
+    SUDO_DEFINE(_PATH_BSHELL, "/usr/sbin/sh")
+elif test -f "/bin/ksh"; then
+    AC_MSG_RESULT(/bin/ksh)
+    SUDO_DEFINE(_PATH_BSHELL, "/bin/ksh")
+elif test -f "/usr/bin/ksh"; then
+    AC_MSG_RESULT(/usr/bin/ksh)
+    SUDO_DEFINE(_PATH_BSHELL, "/usr/bin/ksh")
+elif test -f "/bin/bash"; then
+    AC_MSG_RESULT(/bin/bash)
+    SUDO_DEFINE(_PATH_BSHELL, "/bin/bash")
+elif test -f "/usr/bin/bash"; then
+    AC_MSG_RESULT(/usr/bin/bash)
+    SUDO_DEFINE(_PATH_BSHELL, "/usr/bin/bash")
+else
+    AC_MSG_RESULT(not found)
+fi
+])dnl
+
+dnl
+dnl Where the log file goes, use /var/log if it exists, else /{var,usr}/adm
+dnl
+AC_DEFUN(SUDO_LOGFILE, [AC_MSG_CHECKING(for log file location)
+if test -n "$with_logpath"; then
+    AC_MSG_RESULT($with_logpath)
+    SUDO_DEFINE_UNQUOTED(_PATH_SUDO_LOGFILE, "$with_logpath")
+elif test -d "/var/log"; then
+    AC_MSG_RESULT(/var/log/sudo.log)
+    SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/var/log/sudo.log")
+elif test -d "/var/adm"; then
+    AC_MSG_RESULT(/var/adm/sudo.log)
+    SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/var/adm/sudo.log")
+elif test -d "/usr/adm"; then
+    AC_MSG_RESULT(/usr/adm/sudo.log)
+    SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/usr/adm/sudo.log")
+else
+    AC_MSG_RESULT(unknown, you will have to set _PATH_SUDO_LOGFILE by hand)
+fi
+])dnl
+
+dnl
+dnl Where the log file goes, use /var/log if it exists, else /{var,usr}/adm
+dnl
+AC_DEFUN(SUDO_TIMEDIR, [AC_MSG_CHECKING(for timestamp file location)
+if test -n "$with_timedir"; then
+    AC_MSG_RESULT($with_timedir)
+    SUDO_DEFINE_UNQUOTED(_PATH_SUDO_TIMEDIR, "$with_timedir")
+    timedir="$with_timedir"
+elif test -d "/var/run"; then
+    AC_MSG_RESULT(/var/run/sudo)
+    SUDO_DEFINE(_PATH_SUDO_TIMEDIR, "/var/run/sudo")
+    timedir="/var/run/sudo"
+else
+    AC_MSG_RESULT(/tmp/.odus)
+    SUDO_DEFINE(_PATH_SUDO_TIMEDIR, "/tmp/.odus")
+    timedir="/tmp/.odus"
+fi
+])dnl
+
+dnl
+dnl check for fullly working void
+dnl
+AC_DEFUN(SUDO_FULL_VOID, [AC_MSG_CHECKING(for full void implementation)
+AC_TRY_COMPILE(, [void *foo;
+foo = (void *)0; (void *)"test";], AC_DEFINE(VOID, void, [Define to "void" if your compiler supports void pointers, else use "char"].)
+AC_MSG_RESULT(yes), AC_DEFINE(VOID, char)
+AC_MSG_RESULT(no))])
+
+dnl
+dnl SUDO_CHECK_TYPE(TYPE, DEFAULT)
+dnl XXX - should require the check for unistd.h...
+dnl
+AC_DEFUN(SUDO_CHECK_TYPE,
+[AC_REQUIRE([AC_HEADER_STDC])dnl
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(sudo_cv_type_$1,
+[AC_EGREP_CPP($1, [#include <sys/types.h>
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif], sudo_cv_type_$1=yes, sudo_cv_type_$1=no)])dnl
+AC_MSG_RESULT($sudo_cv_type_$1)
+if test $sudo_cv_type_$1 = no; then
+  AC_DEFINE($1, $2, [Define if your system lacks the $1 type.])
+fi
+])
+
+dnl
+dnl Check for size_t declation
+dnl
+AC_DEFUN(SUDO_TYPE_SIZE_T,
+[SUDO_CHECK_TYPE(size_t, int)])
+
+dnl
+dnl Check for ssize_t declation
+dnl
+AC_DEFUN(SUDO_TYPE_SSIZE_T,
+[SUDO_CHECK_TYPE(ssize_t, int)])
+
+dnl
+dnl Check for dev_t declation
+dnl
+AC_DEFUN(SUDO_TYPE_DEV_T,
+[SUDO_CHECK_TYPE(dev_t, int)])
+
+dnl
+dnl Check for ino_t declation
+dnl
+AC_DEFUN(SUDO_TYPE_INO_T,
+[SUDO_CHECK_TYPE(ino_t, unsigned int)])
+
+dnl
+dnl check for POSIX utime() using struct utimbuf
+dnl
+AC_DEFUN(SUDO_FUNC_UTIME_POSIX,
+[AC_MSG_CHECKING(for POSIX utime)
+AC_CACHE_VAL(sudo_cv_func_utime_posix,
+[rm -f conftestdata; > conftestdata
+AC_TRY_RUN([#include <sys/types.h>
+#include <sys/time.h>
+#include <utime.h>
+main() {
+struct utimbuf ut;
+ut.actime = ut.modtime = time(0);
+utime("conftestdata", &ut);
+exit(0);
+}], sudo_cv_func_utime_posix=yes, sudo_cv_func_utime_posix=no,
+  sudo_cv_func_utime_posix=no)
+rm -f core core.* *.core])dnl
+AC_MSG_RESULT($sudo_cv_func_utime_posix)
+if test $sudo_cv_func_utime_posix = yes; then
+  AC_DEFINE(HAVE_UTIME_POSIX, 1, [Define if you have a POSIX utime() (uses struct utimbuf).])
+fi
+])
+
+dnl
+dnl check for working fnmatch(3)
+dnl
+AC_DEFUN(SUDO_FUNC_FNMATCH,
+[AC_MSG_CHECKING(for working fnmatch with FNM_CASEFOLD)
+AC_CACHE_VAL(sudo_cv_func_fnmatch,
+[rm -f conftestdata; > conftestdata
+AC_TRY_RUN([#include <fnmatch.h>
+main() { exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", FNM_CASEFOLD)); }
+], sudo_cv_func_fnmatch=yes, sudo_cv_func_fnmatch=no,
+  sudo_cv_func_fnmatch=no)
+rm -f core core.* *.core])dnl
+AC_MSG_RESULT($sudo_cv_func_fnmatch)
+if test $sudo_cv_func_fnmatch = yes; then
+  [$1]
+else
+  [$2]
+fi
+])
+
+dnl
+dnl check for isblank(3)
+dnl
+AC_DEFUN([SUDO_FUNC_ISBLANK],
+  [AC_CACHE_CHECK([for isblank], sudo_cv_func_isblank,
+    [AC_TRY_LINK([#include <ctype.h>], [(void)isblank(1);],
+    sudo_cv_func_isblank=yes, sudo_cv_func_isblank=no)])
+] [
+  if test "$sudo_cv_func_isblank" = "yes"; then
+    AC_DEFINE(HAVE_ISBLANK, 1, [Define if you have isblank(3).])
+  fi
+])
+
+dnl
+dnl check for sa_len field in struct sockaddr
+dnl
+AC_DEFUN(SUDO_SOCK_SA_LEN,
+[AC_MSG_CHECKING(for sa_len field in struct sockaddr)
+AC_CACHE_VAL(sudo_cv_sock_sa_len,
+[AC_TRY_RUN([#include <sys/types.h>
+#include <sys/socket.h>
+main() {
+struct sockaddr s;
+s.sa_len = 0;
+exit(0);
+}], sudo_cv_sock_sa_len=yes, sudo_cv_sock_sa_len=no,
+  sudo_cv_sock_sa_len=no)
+rm -f core core.* *.core])dnl
+AC_MSG_RESULT($sudo_cv_sock_sa_len)
+if test $sudo_cv_sock_sa_len = yes; then
+  AC_DEFINE(HAVE_SA_LEN, 1, [Define if your struct sockadr has an sa_len field.])
+fi
+])
+
+dnl
+dnl check for max length of uid_t in string representation.
+dnl we can't really trust UID_MAX or MAXUID since they may exist
+dnl only for backwards compatibility.
+dnl
+AC_DEFUN(SUDO_UID_T_LEN,
+[AC_REQUIRE([AC_TYPE_UID_T])
+AC_MSG_CHECKING(max length of uid_t)
+AC_CACHE_VAL(sudo_cv_uid_t_len,
+[rm -f conftestdata
+AC_TRY_RUN(
+[#include <stdio.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/param.h>
+main() {
+  FILE *f;
+  char b[1024];
+  uid_t u = (uid_t) -1;
+
+  if ((f = fopen("conftestdata", "w")) == NULL)
+    exit(1);
+
+  (void) sprintf(b, "%u", u);
+  (void) fprintf(f, "%d\n", strlen(b));
+  (void) fclose(f);
+  exit(0);
+}], sudo_cv_uid_t_len=`cat conftestdata`, sudo_cv_uid_t_len=10)
+])
+rm -f conftestdata
+AC_MSG_RESULT($sudo_cv_uid_t_len)
+AC_DEFINE_UNQUOTED(MAX_UID_T_LEN, $sudo_cv_uid_t_len, [Define to the max length of a uid_t in string context (excluding the NUL).])
+])
+
+dnl
+dnl check for "long long"
+dnl XXX hard to cache since it includes 2 tests
+dnl
+AC_DEFUN(SUDO_LONG_LONG, [AC_MSG_CHECKING(for long long support)
+AC_TRY_LINK(, [long long foo = 1000; foo /= 10;], AC_DEFINE(HAVE_LONG_LONG, 1, [Define if your compiler supports the "long long" type.])
+[AC_TRY_RUN([main() {if (sizeof(long long) == sizeof(long)) exit(0); else exit(1);}], AC_DEFINE(LONG_IS_QUAD, 1, [Define if sizeof(long) == sizeof(long long).]))]
+AC_MSG_RESULT(yes), AC_MSG_RESULT(no))])
+
+dnl
+dnl private versions of AC_DEFINE and AC_DEFINE_UNQUOTED that don't support
+dnl tracing that we use to define paths for pathnames.h so autoheader doesn't
+dnl put them in config.h.in.  An awful hack.
+dnl
+m4_define([SUDO_DEFINE],
+[cat >>confdefs.h <<\EOF
+[@%:@define] $1 m4_if($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+])
+
+m4_define([SUDO_DEFINE_UNQUOTED],
+[cat >>confdefs.h <<EOF
+[@%:@define] $1 m4_if($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+])
diff --git a/aixcrypt.exp b/aixcrypt.exp
new file mode 100644 (file)
index 0000000..5ee024e
--- /dev/null
@@ -0,0 +1,4 @@
+#!
+__setkey
+__encrypt
+__crypt
diff --git a/alloc.c b/alloc.c
new file mode 100644 (file)
index 0000000..ed872b9
--- /dev/null
+++ b/alloc.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1999-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: alloc.c,v 1.11 2002/01/09 16:56:04 millert Exp $";
+#endif /* lint */
+
+extern char **Argv;            /* from sudo.c */
+
+/*
+ * emalloc() calls the system malloc(3) and exits with an error if
+ * malloc(3) fails.
+ */
+VOID *
+emalloc(size)
+    size_t size;
+{
+    VOID *ptr;
+
+    if ((ptr = (VOID *) malloc(size)) == NULL) {
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+    return(ptr);
+}
+
+/*
+ * erealloc() calls the system realloc(3) and exits with an error if
+ * realloc(3) fails.  You can call erealloc() with a NULL pointer even
+ * if the system realloc(3) does not support this.
+ */
+VOID *
+erealloc(ptr, size)
+    VOID *ptr;
+    size_t size;
+{
+
+    ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
+    if (ptr == NULL) {
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+    return(ptr);
+}
+
+/*
+ * estrdup() is like strdup(3) except that it exits with an error if
+ * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
+ */
+char *
+estrdup(src)
+    const char *src;
+{
+    char *dst = NULL;
+
+    if (src != NULL) {
+       dst = (char *) emalloc(strlen(src) + 1);
+       (void) strcpy(dst, src);
+    }
+    return(dst);
+}
+
+/*
+ * easprintf() calls vasprintf() and exits with an error if vasprintf()
+ * returns -1 (out of memory).
+ */
+int
+#ifdef __STDC__
+easprintf(char **ret, const char *fmt, ...)
+#else
+easprintf(va_alist)
+    va_dcl
+#endif
+{
+    int len;
+    va_list ap;
+#ifdef __STDC__
+    va_start(ap, fmt);
+#else
+    char **ret;
+    const char *fmt;
+
+    va_start(ap);
+    ret = va_arg(ap, char **);
+    fmt = va_arg(ap, const char *);
+#endif
+    len = vasprintf(ret, fmt, ap);
+    va_end(ap);
+
+    if (len == -1) {
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+    return(len);
+}
+
+/*
+ * evasprintf() calls vasprintf() and exits with an error if vasprintf()
+ * returns -1 (out of memory).
+ */
+int
+evasprintf(ret, format, args)
+    char **ret;
+    const char *format;
+    va_list args;
+{
+    int len;
+
+    if ((len = vasprintf(ret, format, args)) == -1) {
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+    return(len);
+}
diff --git a/alloca.c b/alloca.c
new file mode 100644 (file)
index 0000000..be98a41
--- /dev/null
+++ b/alloca.c
@@ -0,0 +1,457 @@
+/* alloca.c -- allocate automatically reclaimed memory
+   (Mostly) portable public-domain implementation -- D A Gwyn
+
+   This implementation of the PWB library alloca function,
+   which is used to allocate space off the run-time stack so
+   that it is automatically reclaimed upon procedure exit,
+   was inspired by discussions with J. Q. Johnson of Cornell.
+   J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+   There are some preprocessor constants that can
+   be defined when compiling for your specific system, for
+   improved efficiency; however, the defaults should be okay.
+
+   The general concept of this implementation is to keep
+   track of all alloca-allocated blocks, and reclaim any
+   that are found to be deeper in the stack than the current
+   invocation.  This heuristic does not reclaim storage as
+   soon as it becomes invalid, but it will do so eventually.
+
+   As a special case, alloca(0) reclaims storage without
+   allocating any.  It is a good idea to use alloca(0) in
+   your main control loop, etc. to force garbage collection.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* If compiling with GCC 2, this file's not needed.  */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+   there must be some other way alloca is supposed to work.  */
+#ifndef alloca
+
+/* If your stack is a linked list of frames, you have to
+   provide an "address metric" ADDRESS_FUNCTION macro.  */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#ifndef NULL
+#define        NULL    0
+#endif
+
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+   growth for your system; otherwise it will be automatically
+   deduced at run-time.
+
+   STACK_DIRECTION > 0 => grows toward higher addresses
+   STACK_DIRECTION < 0 => grows toward lower addresses
+   STACK_DIRECTION = 0 => direction of growth unknown  */
+
+#ifndef STACK_DIRECTION
+#define        STACK_DIRECTION 0       /* Direction unknown.  */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define        STACK_DIR       STACK_DIRECTION /* Known at compile-time.  */
+
+#else /* STACK_DIRECTION == 0; need run-time code.  */
+
+static int stack_dir;          /* 1 or -1 once known.  */
+#define        STACK_DIR       stack_dir
+
+static void
+find_stack_direction ()
+{
+  static char *addr = NULL;    /* Address of first `dummy', once known.  */
+  auto char dummy;             /* To get stack address.  */
+
+  if (addr == NULL)
+    {                          /* Initial entry.  */
+      addr = ADDRESS_FUNCTION (dummy);
+
+      find_stack_direction (); /* Recurse once.  */
+    }
+  else
+    {
+      /* Second entry.  */
+      if (ADDRESS_FUNCTION (dummy) > addr)
+       stack_dir = 1;          /* Stack grew upward.  */
+      else
+       stack_dir = -1;         /* Stack grew downward.  */
+    }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+   (a) chain together all alloca'ed blocks;
+   (b) keep track of stack depth.
+
+   It is very important that sizeof(header) agree with malloc
+   alignment chunk size.  The following default should work okay.  */
+
+#ifndef        ALIGN_SIZE
+#define        ALIGN_SIZE      sizeof(double)
+#endif
+
+typedef union hdr
+{
+  char align[ALIGN_SIZE];      /* To force sizeof(header).  */
+  struct
+    {
+      union hdr *next;         /* For chaining headers.  */
+      char *deep;              /* For stack depth measure.  */
+    } h;
+} header;
+
+static header *last_alloca_header = NULL;      /* -> last alloca header.  */
+
+/* Return a pointer to at least SIZE bytes of storage,
+   which will be automatically reclaimed upon exit from
+   the procedure that called alloca.  Originally, this space
+   was supposed to be taken from the current stack frame of the
+   caller, but that method cannot be made to work for some
+   implementations of C, for example under Gould's UTX/32.  */
+
+pointer
+alloca (size)
+     unsigned size;
+{
+  auto char probe;             /* Probes stack depth: */
+  register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+  if (STACK_DIR == 0)          /* Unknown growth direction.  */
+    find_stack_direction ();
+#endif
+
+  /* Reclaim garbage, defined as all alloca'd storage that
+     was allocated from deeper in the stack than currently. */
+
+  {
+    register header *hp;       /* Traverses linked list.  */
+
+    for (hp = last_alloca_header; hp != NULL;)
+      if ((STACK_DIR > 0 && hp->h.deep > depth)
+         || (STACK_DIR < 0 && hp->h.deep < depth))
+       {
+         register header *np = hp->h.next;
+
+         free ((pointer) hp);  /* Collect garbage.  */
+
+         hp = np;              /* -> next header.  */
+       }
+      else
+       break;                  /* Rest are not deeper.  */
+
+    last_alloca_header = hp;   /* -> last valid storage.  */
+  }
+
+  if (size == 0)
+    return NULL;               /* No allocation required.  */
+
+  /* Allocate combined header + user data storage.  */
+
+  {
+    register pointer new = malloc (sizeof (header) + size);
+    /* Address of header.  */
+
+    ((header *) new)->h.next = last_alloca_header;
+    ((header *) new)->h.deep = depth;
+
+    last_alloca_header = (header *) new;
+
+    /* User storage begins just after header.  */
+
+    return (pointer) ((char *) new + sizeof (header));
+  }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+  {
+    long shgrow:32;            /* Number of times stack has grown.  */
+    long shaseg:32;            /* Size of increments to stack.  */
+    long shhwm:32;             /* High water mark of stack.  */
+    long shsize:32;            /* Current size of stack (all segments).  */
+  };
+
+/* The stack segment linkage control information occurs at
+   the high-address end of a stack segment.  (The stack
+   grows from low addresses to high addresses.)  The initial
+   part of the stack segment linkage control information is
+   0200 (octal) words.  This provides for register storage
+   for the routine which overflows the stack.  */
+
+struct stack_segment_linkage
+  {
+    long ss[0200];             /* 0200 overflow words.  */
+    long sssize:32;            /* Number of words in this segment.  */
+    long ssbase:32;            /* Offset to stack base.  */
+    long:32;
+    long sspseg:32;            /* Offset to linkage control of previous
+                                  segment of stack.  */
+    long:32;
+    long sstcpt:32;            /* Pointer to task common address block.  */
+    long sscsnm;               /* Private control structure number for
+                                  microtasking.  */
+    long ssusr1;               /* Reserved for user.  */
+    long ssusr2;               /* Reserved for user.  */
+    long sstpid;               /* Process ID for pid based multi-tasking.  */
+    long ssgvup;               /* Pointer to multitasking thread giveup.  */
+    long sscray[7];            /* Reserved for Cray Research.  */
+    long ssa0;
+    long ssa1;
+    long ssa2;
+    long ssa3;
+    long ssa4;
+    long ssa5;
+    long ssa6;
+    long ssa7;
+    long sss0;
+    long sss1;
+    long sss2;
+    long sss3;
+    long sss4;
+    long sss5;
+    long sss6;
+    long sss7;
+  };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+   returned by the STKSTAT library routine.  */
+struct stk_stat
+  {
+    long now;                  /* Current total stack size.  */
+    long maxc;                 /* Amount of contiguous space which would
+                                  be required to satisfy the maximum
+                                  stack demand to date.  */
+    long high_water;           /* Stack high-water mark.  */
+    long overflows;            /* Number of stack overflow ($STKOFEN) calls.  */
+    long hits;                 /* Number of internal buffer hits.  */
+    long extends;              /* Number of block extensions.  */
+    long stko_mallocs;         /* Block allocations by $STKOFEN.  */
+    long underflows;           /* Number of stack underflow calls ($STKRETN).  */
+    long stko_free;            /* Number of deallocations by $STKRETN.  */
+    long stkm_free;            /* Number of deallocations by $STKMRET.  */
+    long segments;             /* Current number of stack segments.  */
+    long maxs;                 /* Maximum number of stack segments so far.  */
+    long pad_size;             /* Stack pad size.  */
+    long current_address;      /* Current stack segment address.  */
+    long current_size;         /* Current stack segment size.  This
+                                  number is actually corrupted by STKSTAT to
+                                  include the fifteen word trailer area.  */
+    long initial_address;      /* Address of initial segment.  */
+    long initial_size;         /* Size of initial segment.  */
+  };
+
+/* The following structure describes the data structure which trails
+   any stack segment.  I think that the description in 'asdef' is
+   out of date.  I only describe the parts that I am sure about.  */
+
+struct stk_trailer
+  {
+    long this_address;         /* Address of this block.  */
+    long this_size;            /* Size of this block (does not include
+                                  this trailer).  */
+    long unknown2;
+    long unknown3;
+    long link;                 /* Address of trailer block of previous
+                                  segment.  */
+    long unknown5;
+    long unknown6;
+    long unknown7;
+    long unknown8;
+    long unknown9;
+    long unknown10;
+    long unknown11;
+    long unknown12;
+    long unknown13;
+    long unknown14;
+  };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+   I doubt that "lint" will like this much. */
+
+static long
+i00afunc (address)
+     long *address;
+{
+  struct stk_stat status;
+  struct stk_trailer *trailer;
+  long *block, size;
+  long result = 0;
+
+  /* We want to iterate through all of the segments.  The first
+     step is to get the stack status structure.  We could do this
+     more quickly and more directly, perhaps, by referencing the
+     $LM00 common block, but I know that this works.  */
+
+  STKSTAT (&status);
+
+  /* Set up the iteration.  */
+
+  trailer = (struct stk_trailer *) (status.current_address
+                                   + status.current_size
+                                   - 15);
+
+  /* There must be at least one stack segment.  Therefore it is
+     a fatal error if "trailer" is null.  */
+
+  if (trailer == 0)
+    abort ();
+
+  /* Discard segments that do not contain our argument address.  */
+
+  while (trailer != 0)
+    {
+      block = (long *) trailer->this_address;
+      size = trailer->this_size;
+      if (block == 0 || size == 0)
+       abort ();
+      trailer = (struct stk_trailer *) trailer->link;
+      if ((block <= address) && (address < (block + size)))
+       break;
+    }
+
+  /* Set the result to the offset in this segment and add the sizes
+     of all predecessor segments.  */
+
+  result = address - block;
+
+  if (trailer == 0)
+    {
+      return result;
+    }
+
+  do
+    {
+      if (trailer->this_size <= 0)
+       abort ();
+      result += trailer->this_size;
+      trailer = (struct stk_trailer *) trailer->link;
+    }
+  while (trailer != 0);
+
+  /* We are done.  Note that if you present a bogus address (one
+     not in any segment), you will get a different number back, formed
+     from subtracting the address of the first block.  This is probably
+     not what you want.  */
+
+  return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+   Determine the number of the cell within the stack,
+   given the address of the cell.  The purpose of this
+   routine is to linearize, in some sense, stack addresses
+   for alloca.  */
+
+static long
+i00afunc (address)
+     long address;
+{
+  long stkl = 0;
+
+  long size, pseg, this_segment, stack;
+  long result = 0;
+
+  struct stack_segment_linkage *ssptr;
+
+  /* Register B67 contains the address of the end of the
+     current stack segment.  If you (as a subprogram) store
+     your registers on the stack and find that you are past
+     the contents of B67, you have overflowed the segment.
+
+     B67 also points to the stack segment linkage control
+     area, which is what we are really interested in.  */
+
+  stkl = CRAY_STACKSEG_END ();
+  ssptr = (struct stack_segment_linkage *) stkl;
+
+  /* If one subtracts 'size' from the end of the segment,
+     one has the address of the first word of the segment.
+
+     If this is not the first segment, 'pseg' will be
+     nonzero.  */
+
+  pseg = ssptr->sspseg;
+  size = ssptr->sssize;
+
+  this_segment = stkl - size;
+
+  /* It is possible that calling this routine itself caused
+     a stack overflow.  Discard stack segments which do not
+     contain the target address.  */
+
+  while (!(this_segment <= address && address <= stkl))
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+      if (pseg == 0)
+       break;
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      this_segment = stkl - size;
+    }
+
+  result = address - this_segment;
+
+  /* If you subtract pseg from the current end of the stack,
+     you get the address of the previous stack segment's end.
+     This seems a little convoluted to me, but I'll bet you save
+     a cycle somewhere.  */
+
+  while (pseg != 0)
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      result += size;
+    }
+  return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
diff --git a/auth/API b/auth/API
new file mode 100644 (file)
index 0000000..d586c64
--- /dev/null
+++ b/auth/API
@@ -0,0 +1,128 @@
+NOTE: the Sudo auth API is subject to change
+
+Purpose: to provide a simple API for authentication methods that
+         encapsulates things nicely without turning into a maze
+        of #ifdef's
+
+The sudo_auth struct looks like this:
+
+typedef struct sudo_auth {
+    short flags;                /* various flags, see below */
+    short status;               /* status from verify routine */
+    char *name;                        /* name of the method in string form */
+    VOID *data;                 /* method-specific data pointer */
+
+    int (*init) __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+    int (*setup) __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+    int (*verify) __P((struct passwd *pw, char *p, sudo_auth *auth));
+    int (*cleanup) __P((struct passwd *pw, sudo_auth *auth));
+} sudo_auth;
+
+The variables in the struct are as follows:
+    flags      Bitwise binary flags, see below.
+
+    status     Contains the return value from the last run of
+               the "verify" function.  Starts out as AUTH_FAILURE.
+
+    name       The name of the authentication method as a C string.
+
+    data       A pointer to method-specific data.  This is passed to
+               all the functions of an auth method and is usually
+               initialized in the "init" or "setup" routines.
+
+Possible values of sudo_auth.flags:
+    FLAG_USER          Whether or not the auth functions should run with
+                       the euid of the invoking user instead of 0.
+
+    FLAG_CONFIGURED    If set then the auth method is assumed to have been
+                       configured successfully.  All auth methods start out
+                       with this set.  If an "init" or "setup" function
+                       fails, this bit is cleared.
+
+    FLAG_ONEANDONLY    If set, this indicates that the method is the
+                       only one in use.  Can be used by auth functions
+                       to determine whether to return a fatal or nonfatal
+                       error.
+
+The member functions can return the following values:
+    AUTH_SUCCESS       Function succeeded.  For a ``verify'' function
+                       this means the user correctly authenticated.
+
+    AUTH_FAILURE       Function failed.  If this is an ``init'' or
+                       ``setup'' routine, the auth method will be
+                       marked as !configured.
+
+    AUTH_FATAL         A fatal error occurred.  The routine should have
+                       written an error message to stderr and optionally
+                       sent mail to the administrator.  (If log_error()
+                       is called to do this, the NO_EXIT flag must be used.)
+                       When verify_user() gets AUTH_FATAL from an auth
+                       function it does an exit(1).
+
+The functions in the struct are as follows:
+
+    int init(struct passwd *pw, char **prompt, sudo_auth *auth)
+        Function to do any one-time initialization for the auth
+        method.  All of the "init" functions are run before anything
+        else.  A pointer to the prompt string may be used to add
+        method-specific info to the prompt.
+
+    int setup(struct passwd *pw, char **prompt, sudo_auth *auth)
+        Function to do method-specific setup.  All the "setup"
+        routines are run before any of the "verify" routines.  A
+        pointer to the prompt string may be used to add method-specific
+        info to the prompt.
+
+    int verify(struct passwd *pw, char *p, sudo_auth *auth)
+        Function to do user verification for this auth method.  For
+        standalone auth methods ``p'' is the prompt string.  For
+        normal auth methods, ``p'' is the password the user entered.
+        Note that standalone auth methods are responsible for
+        rerading the password themselves.
+
+    int cleanup(struct passwd *pw, sudo_auth *auth)
+        Function to do per-auth method cleanup.  This is only run
+        at the end of the authentication process, after the user
+        has completely failed or succeeded to authenticate.
+       The ``auth->status'' variable contains the result of the
+       last authentication attempt which may be interesting.
+
+A note about standalone methods.  Some authentication methods can't
+coexist with any others.  This may be because they encapsulate other
+methods (pam, sia) or because they have a special way of interacting
+with the user (securid).
+
+Adding a new authentication method:
+
+Each method should live in its own file.  Add prototypes for the functions
+in sudo_auth.h.
+
+If this is a standalone method, add it to the standalone #if cascade
+in sudo_auth.h.  For instance, for a method, ``fooauth'', add:
+
+#elif defined(HAVE_FOOAUTH)
+#  define AUTH_STANDALONE \
+        AUTH_ENTRY(0, "foo", \
+           foo_init, foo_setup, foo_verify, foo_cleanup)
+
+If the method needs to run as the user, not root, replace the first
+parameter to AUTH_ENTRY (0) with FLAG_USER.  If you don't have a
+init/setup/cleanup routine, just use a NULL for that field.
+
+For a normal authentication method, add it to the ``auth_switch'' in
+sudo_auth.c.  If ``fooauth'' is a normal auth method, its entry
+would look like:
+
+#  ifdef HAVE_FOOAUTH
+    AUTH_ENTRY(0, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
+#  endif
+
+Again, if the method doesn't need to run as root, replace the 0 with
+FLAG_USER.  Likewise, if you don't have a init/setup/cleanup routine,
+just use a NULL for that field.
+
+NOTE:  You should not make a method both ``standalone'' and
+       ``normal''.  Just use the --without-passwd configure argument
+       to disable passwd/shadow file checking and then have your
+       auth routines check the FLAG_ONEANDONLY flag to see if
+       they are running standalone and act accordingly.
diff --git a/auth/afs.c b/auth/afs.c
new file mode 100644 (file)
index 0000000..e00e690
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#undef VOID
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: afs.c,v 1.7 2002/04/18 15:39:19 millert Exp $";
+#endif /* lint */
+
+int
+afs_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    struct ktc_encryptionKey afs_key;
+    struct ktc_token afs_token;
+
+    /* Try to just check the password */
+    ka_StringToKey(pass, NULL, &afs_key);
+    if (ka_GetAdminToken(pw->pw_name,          /* name */
+                        NULL,                  /* instance */
+                        NULL,                  /* realm */
+                        &afs_key,              /* key (contains password) */
+                        0,                     /* lifetime */
+                        &afs_token,            /* token */
+                        0) == 0)               /* new */
+       return(AUTH_SUCCESS);
+
+    /* Fall back on old method XXX - needed? */
+    setpag();
+    if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG,
+                                  pw->pw_name, /* name */
+                                  NULL,        /* instance */
+                                  NULL,        /* realm */
+                                  pass,        /* password */
+                                  0,           /* lifetime */
+                                  NULL,        /* expiration ptr (unused) */
+                                  0,           /* spare */
+                                  NULL) == 0)  /* reason */
+       return(AUTH_SUCCESS);
+
+    return(AUTH_FAILURE);
+}
diff --git a/auth/aix_auth.c b/auth/aix_auth.c
new file mode 100644 (file)
index 0000000..4ae2f5a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: aix_auth.c,v 1.12 2002/01/21 22:25:14 millert Exp $";
+#endif /* lint */
+
+int
+aixauth_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    char *message, *pass;
+    int reenter = 1;
+    int rval = AUTH_FAILURE;
+
+    pass = tgetpass(prompt, def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags);
+    if (pass) {
+       if (authenticate(pw->pw_name, pass, &reenter, &message) == 0)
+           rval = AUTH_SUCCESS;
+       memset(pass, 0, strlen(pass));
+    }
+    return(rval);
+}
diff --git a/auth/bsdauth.c b/auth/bsdauth.c
new file mode 100644 (file)
index 0000000..2bfc6f0
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2000-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+#include <pwd.h>
+#include <signal.h>
+
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: bsdauth.c,v 1.8 2002/01/22 03:37:55 millert Exp $";
+#endif /* lint */
+
+extern char *login_style;              /* from sudo.c */
+
+int
+bsdauth_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static auth_session_t *as;
+    extern login_cap_t *lc;                    /* from sudo.c */
+
+    if ((as = auth_open()) == NULL) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, 
+           "unable to begin bsd authentication");
+       return(AUTH_FATAL);
+    }
+
+    /* XXX - maybe sanity check the auth style earlier? */
+    login_style = login_getstyle(lc, login_style, "auth-sudo");
+    if (login_style == NULL) {
+       log_error(NO_EXIT|NO_MAIL, "invalid authentication type");
+       auth_close(as);
+       return(AUTH_FATAL);
+    }
+
+     if (auth_setitem(as, AUTHV_STYLE, login_style) < 0 ||
+       auth_setitem(as, AUTHV_NAME, pw->pw_name) < 0 ||
+       auth_setitem(as, AUTHV_CLASS, login_class) < 0) {
+       log_error(NO_EXIT|NO_MAIL, "unable to setup authentication");
+       auth_close(as);
+       return(AUTH_FATAL);
+    }
+
+    auth->data = (VOID *) as;
+    return(AUTH_SUCCESS);
+}
+
+int
+bsdauth_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    char *s, *pass;
+    size_t len;
+    int authok = 0;
+    sigaction_t sa, osa;
+    auth_session_t *as = (auth_session_t *) auth->data;
+    extern int nil_pw;
+
+    /* save old signal handler */
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = SIG_DFL;
+    (void) sigaction(SIGCHLD, &sa, &osa);
+
+    /*
+     * If there is a challenge then print that instead of the normal
+     * prompt.  If the user just hits return we prompt again with echo
+     * turned on, which is useful for challenge/response things like
+     * S/Key.
+     */
+    if ((s = auth_challenge(as)) == NULL) {
+       pass = tgetpass(prompt, def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags);
+    } else {
+       pass = tgetpass(s, def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags);
+       if (pass && *pass == '\0') {
+           if ((prompt = strrchr(s, '\n')))
+               prompt++;
+           else
+               prompt = s;
+
+           /*
+            * Append '[echo on]' to the last line of the challenge and
+            * reprompt with echo turned on.
+            */
+           len = strlen(prompt) - 1;
+           while (isspace(prompt[len]) || prompt[len] == ':')
+               prompt[len--] = '\0';
+           easprintf(&s, "%s [echo on]: ", prompt);
+           pass = tgetpass(s, def_ival(I_PASSWD_TIMEOUT) * 60,
+               tgetpass_flags | TGP_ECHO);
+           free(s);
+       }
+    }
+
+    if (!pass || *pass == '\0')                /* ^C or empty password */
+       nil_pw = 1;
+
+    if (pass) {
+       authok = auth_userresponse(as, pass, 1);
+       memset(pass, 0, strlen(pass));
+    }
+
+    /* restore old signal handler */
+    (void) sigaction(SIGCHLD, &osa, NULL);
+
+    if (authok)
+       return(AUTH_SUCCESS);
+
+    if ((s = auth_getvalue(as, "errormsg")) != NULL)
+       log_error(NO_EXIT|NO_MAIL, "%s", s);
+    return(AUTH_FAILURE);
+}
+
+int
+bsdauth_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+    auth_session_t *as = (auth_session_t *) auth->data;
+
+    auth_close(as);
+
+    return(AUTH_SUCCESS);
+}
diff --git a/auth/dce.c b/auth/dce.c
new file mode 100644 (file)
index 0000000..8d4115b
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2001
+ *     Todd C. Miller <Todd.Miller@courtesan.com>.  All rights reserved.
+ *
+ * This code is derived from software contributed by Jeff Earickson
+ * of Colby College, Waterville, ME <jaearick@colby.edu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ *  The code below basically comes from the examples supplied on
+ *  the OSF DCE 1.0.3 manpages for the sec_login routines, with
+ *  enough additional polishing to make the routine work with the
+ *  rest of sudo.
+ *
+ *  This code is known to work on HP 700 and 800 series systems
+ *  running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE.
+ *  (aka, OSF DCE 1.0.3) or with HP's version 1.4 of DCE (aka, OSF
+ *  DCE 1.1).
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include <dce/rpc.h>
+#include <dce/sec_login.h>
+#include <dce/dce_error.h> /* required to call dce_error_inq_text routine */
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: dce.c,v 1.8 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+static int check_dce_status __P((error_status_t, char *));
+
+int
+dce_verify(pw, plain_pw, auth)
+    struct passwd *pw;
+    char *plain_pw;
+    sudo_auth *auth;
+{
+    struct passwd              temp_pw;
+    sec_passwd_rec_t           password_rec;
+    sec_login_handle_t         login_context;
+    boolean32                  reset_passwd;
+    sec_login_auth_src_t       auth_src;
+    error_status_t             status;
+
+    /*
+     * Create the local context of the DCE principal necessary
+     * to perform authenticated network operations.  The network
+     * identity set up by this operation cannot be used until it
+     * is validated via sec_login_validate_identity().
+     */
+    if (sec_login_setup_identity((unsigned_char_p_t) pw->pw_name,
+       sec_login_no_flags, &login_context, &status)) {
+
+       if (check_dce_status(status, "sec_login_setup_identity(1):"))
+           return(AUTH_FAILURE);
+
+       password_rec.key.key_type = sec_passwd_plain;
+       password_rec.key.tagged_union.plain = (idl_char *) plain_pw;
+       password_rec.pepper = NULL;
+       password_rec.version_number = sec_passwd_c_version_none;
+
+       /* Validate the login context with the password */
+       if (sec_login_validate_identity(login_context, &password_rec,
+           &reset_passwd, &auth_src, &status)) {
+
+           if (check_dce_status(status, "sec_login_validate_identity(1):"))
+               return(AUTH_FAILURE);
+
+           /*
+            * Certify that the DCE Security Server used to set
+            * up and validate a login context is legitimate.  Makes
+            * sure that we didn't get spoofed by another DCE server.
+            */
+           if (!sec_login_certify_identity(login_context, &status)) {
+               (void) fprintf(stderr, "Whoa! Bogus authentication server!\n");
+               (void) check_dce_status(status,"sec_login_certify_identity(1):");
+               return(AUTH_FAILURE);
+           }
+           if (check_dce_status(status, "sec_login_certify_identity(2):"))
+               return(AUTH_FAILURE);
+
+           /*
+            * Sets the network credentials to those specified
+            * by the now validated login context.
+            */
+           sec_login_set_context(login_context, &status);
+           if (check_dce_status(status, "sec_login_set_context:"))
+               return(AUTH_FAILURE);
+
+           /*
+            * Oops, your credentials were no good. Possibly
+            * caused by clock times out of adjustment between
+            * DCE client and DCE security server...
+            */
+           if (auth_src != sec_login_auth_src_network) {
+                   (void) fprintf(stderr,
+                       "You have no network credentials.\n");
+                   return(AUTH_FAILURE);
+           }
+           /* Check if the password has aged and is thus no good */
+           if (reset_passwd) {
+                   (void) fprintf(stderr,
+                       "Your DCE password needs resetting.\n");
+                   return(AUTH_FAILURE);
+           }
+
+           /*
+            * We should be a valid user by this point.  Pull the
+            * user's password structure from the DCE security
+            * server just to make sure.  If we get it with no
+            * problems, then we really are legitimate...
+            */
+           sec_login_get_pwent(login_context, (sec_login_passwd_t) &temp_pw,
+               &status);
+           if (check_dce_status(status, "sec_login_get_pwent:"))
+               return(AUTH_FAILURE);
+
+           /*
+            * If we get to here, then the pwent above properly fetched
+            * the password structure from the DCE registry, so the user
+            * must be valid.  We don't really care what the user's
+            * registry password is, just that the user could be
+            * validated.  In fact, if we tried to compare the local
+            * password to the DCE entry at this point, the operation
+            * would fail if the hidden password feature is turned on,
+            * because the password field would contain an asterisk.
+            * Also go ahead and destroy the user's DCE login context
+            * before we leave here (and don't bother checking the
+            * status), in order to clean up credentials files in
+            * /opt/dcelocal/var/security/creds.  By doing this, we are
+            * assuming that the user will not need DCE authentication
+            * later in the program, only local authentication.  If this
+            * is not true, then the login_context will have to be
+            * returned to the calling program, and the context purged
+            * somewhere later in the program.
+            */
+           sec_login_purge_context(&login_context, &status);
+           return(AUTH_SUCCESS);
+       } else {
+           if(check_dce_status(status, "sec_login_validate_identity(2):"))
+               return(AUTH_FAILURE);
+           sec_login_purge_context(&login_context, &status);
+           if(check_dce_status(status, "sec_login_purge_context:"))
+               return(AUTH_FAILURE);
+       }
+    }
+    (void) check_dce_status(status, "sec_login_setup_identity(2):");
+    return(AUTH_FAILURE);
+}
+
+/* Returns 0 for DCE "ok" status, 1 otherwise */
+static int
+check_dce_status(input_status, comment)
+    error_status_t input_status;
+    char *comment;
+{
+    int error_stat;
+    unsigned char error_string[dce_c_error_string_len];
+
+    if (input_status == rpc_s_ok)
+       return(0);
+    dce_error_inq_text(input_status, error_string, &error_stat);
+    (void) fprintf(stderr, "%s %s\n", comment, error_string);
+    return(1);
+}
diff --git a/auth/fwtk.c b/auth/fwtk.c
new file mode 100644 (file)
index 0000000..9eedda4
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include <auth.h>
+#include <firewall.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: fwtk.c,v 1.15 2002/01/21 22:25:14 millert Exp $";
+#endif /* lint */
+
+int
+fwtk_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static Cfg *confp;                 /* Configuration entry struct */
+    char resp[128];                    /* Response from the server */
+
+    if ((confp = cfg_read("sudo")) == (Cfg *)-1) {
+       (void) fprintf(stderr, "%s: cannot read fwtk config.\n", Argv[0]);
+       return(AUTH_FATAL);
+    }
+
+    if (auth_open(confp)) {
+       (void) fprintf(stderr, "%s: cannot connect to authentication server.\n",
+           Argv[0]);
+       return(AUTH_FATAL);
+    }
+
+    /* Get welcome message from auth server */
+    if (auth_recv(resp, sizeof(resp))) {
+       (void) fprintf(stderr,
+           "%s: lost connection to authentication server.\n", Argv[0]);
+       return(AUTH_FATAL);
+    }
+    if (strncmp(resp, "Authsrv ready", 13) != 0) {
+       (void) fprintf(stderr,
+           "%s: authentication server error.\n%s\n", Argv[0], resp);
+       return(AUTH_FATAL);
+    }
+
+    return(AUTH_SUCCESS);
+}
+
+int
+fwtk_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    char *pass;                                /* Password from the user */
+    char buf[SUDO_PASS_MAX + 12];      /* General prupose buffer */
+    char resp[128];                    /* Response from the server */
+    int error;
+    extern int nil_pw;
+
+    /* Send username to authentication server. */
+    (void) snprintf(buf, sizeof(buf), "authorize %s 'sudo'", pw->pw_name);
+    if (auth_send(buf) || auth_recv(resp, sizeof(resp))) {
+       (void) fprintf(stderr,
+           "%s: lost connection to authentication server.\n", Argv[0]);
+       return(AUTH_FATAL);
+    }
+
+    /* Get the password/response from the user. */
+    if (strncmp(resp, "challenge ", 10) == 0) {
+       (void) snprintf(buf, sizeof(buf), "%s\nResponse: ", &resp[10]);
+       pass = tgetpass(buf, def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags);
+       if (pass && *pass == '\0') {
+           pass = tgetpass("Response [echo on]: ",
+               def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags | TGP_ECHO);
+       }
+    } else if (strncmp(resp, "password", 8) == 0) {
+       pass = tgetpass(prompt, def_ival(I_PASSWD_TIMEOUT) * 60,
+           tgetpass_flags);
+    } else {
+       (void) fprintf(stderr, "%s: %s\n", Argv[0], resp);
+       return(AUTH_FATAL);
+    }
+    if (!pass) {                       /* ^C or error */
+       nil_pw = 1;
+       return(AUTH_FAILURE);
+    } else if (*pass == '\0')          /* empty password */
+       nil_pw = 1;
+
+    /* Send the user's response to the server */
+    (void) snprintf(buf, sizeof(buf), "response '%s'", pass);
+    if (auth_send(buf) || auth_recv(resp, sizeof(resp))) {
+       (void) fprintf(stderr,
+           "%s: lost connection to authentication server.\n", Argv[0]);
+       error = AUTH_FATAL;
+       goto done;
+    }
+
+    if (strncmp(resp, "ok", 2) == 0) {
+       error = AUTH_SUCCESS;
+       goto done;
+    }
+
+    /* Main loop prints "Permission Denied" or insult. */
+    if (strcmp(resp, "Permission Denied.") != 0)
+       fprintf(stderr, "%s: %s\n", Argv[0], resp);
+    error = AUTH_FAILURE;
+done:
+    memset(pass, 0, strlen(pass));
+    memset(buf, 0, strlen(buf));
+    return(error);
+}
+
+int
+fwtk_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+
+    auth_close();
+    return(AUTH_SUCCESS);
+}
diff --git a/auth/kerb4.c b/auth/kerb4.c
new file mode 100644 (file)
index 0000000..fd64aab
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <krb.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: kerb4.c,v 1.6 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+int
+kerb4_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static char realm[REALM_SZ];
+
+    /* Don't try to verify root */
+    if (pw->pw_uid == 0)
+       return(AUTH_FAILURE);
+
+    /* Get the local realm, or retrun failure (no krb.conf) */
+    if (krb_get_lrealm(realm, 1) != KSUCCESS)
+       return(AUTH_FAILURE);
+
+    /* Stash a pointer to the realm (used in kerb4_verify) */
+    auth->data = (VOID *) realm;
+
+    return(AUTH_SUCCESS);
+}
+
+int
+kerb4_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    char tkfile[sizeof(_PATH_SUDO_TIMEDIR) + 4 + MAX_UID_T_LEN];
+    char *realm = (char *) auth->data;
+    int error;
+
+    /*
+     * Set the ticket file to be in sudo sudo timedir so we don't
+     * wipe out other (real) kerberos tickets.
+     */
+    (void) sprintf(tkfile, "%s/tkt%ld", _PATH_SUDO_TIMEDIR, (long) pw->pw_uid);
+    (void) krb_set_tkt_string(tkfile);
+
+    /* Convert the password to a ticket given. */
+    error = krb_get_pw_in_tkt(pw->pw_name, "", realm, "krbtgt", realm,
+       DEFAULT_TKT_LIFE, pass);
+
+    switch (error) {
+       case INTK_OK:
+           dest_tkt();                 /* we are done with the temp ticket */
+           return(AUTH_SUCCESS);
+           break;
+       case INTK_BADPW:
+       case KDC_PR_UNKNOWN:
+           break;
+       default:
+           (void) fprintf(stderr, "Warning: Kerberos error: %s\n",
+               krb_err_txt[error]);
+    }
+
+    return(AUTH_FAILURE);
+}
diff --git a/auth/kerb5.c b/auth/kerb5.c
new file mode 100644 (file)
index 0000000..1992c1d
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Frank Cusack
+ * <fcusack@fcusack.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <krb5.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: kerb5.c,v 1.11 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+static int verify_krb_v5_tgt __P((krb5_context, krb5_ccache, char *));
+static struct _sudo_krb5_data {
+    krb5_context       sudo_context;
+    krb5_principal     princ;
+    krb5_ccache                ccache;
+} sudo_krb5_data = { NULL, NULL, NULL };
+typedef struct _sudo_krb5_data *sudo_krb5_datap;
+
+extern krb5_cc_ops krb5_mcc_ops;
+
+int
+kerb5_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    krb5_context       sudo_context;
+    krb5_ccache                ccache;
+    krb5_principal     princ;
+    krb5_error_code    error;
+    char               cache_name[64];
+    char               *pname;
+
+    auth->data = (VOID *) &sudo_krb5_data; /* Stash all our data here */
+
+    if (error = krb5_init_context(&(sudo_krb5_data.sudo_context))) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to initialize context: %s", auth->name,
+                 error_message(error));
+       return(AUTH_FAILURE);
+    }
+    sudo_context = sudo_krb5_data.sudo_context;
+
+    if (error = krb5_parse_name(sudo_context, pw->pw_name,
+       &(sudo_krb5_data.princ))) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to parse '%s': %s", auth->name, pw->pw_name,
+                 error_message(error));
+       return(AUTH_FAILURE);
+    }
+    princ = sudo_krb5_data.princ;
+
+    /*
+     * Really, we need to tell the caller not to prompt for password.
+     * The API does not currently provide this unless the auth is standalone.
+     */
+#if 1
+    if (error = krb5_unparse_name(sudo_context, princ, &pname)) {
+       log_error(NO_EXIT|NO_MAIL,
+                 "%s: unable to unparse princ ('%s'): %s", auth->name,
+                 pw->pw_name, error_message(error));
+       return(AUTH_FAILURE);
+    }
+
+    /* Only rewrite prompt if user didn't specify their own. */
+    /*if (!strcmp(prompt, PASSPROMPT)) { */
+       easprintf(promptp, "Password for %s: ", pname);
+    /*}*/
+    free(pname);
+#endif
+
+    /* For CNS compatibility */
+    if (error = krb5_cc_register(sudo_context, &krb5_mcc_ops, FALSE)) {
+       if (error != KRB5_CC_TYPE_EXISTS) {
+           log_error(NO_EXIT|NO_MAIL, 
+                     "%s: unable to use Memory ccache: %s", auth->name,
+                     error_message(error));
+           return(AUTH_FAILURE);
+       }
+    }
+
+    (void) snprintf(cache_name, sizeof(cache_name), "MEMORY:sudocc_%ld",
+                   (long) getpid());
+    if (error = krb5_cc_resolve(sudo_context, cache_name,
+       &(sudo_krb5_data.ccache))) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to resolve ccache: %s", auth->name,
+                 error_message(error));
+       return(AUTH_FAILURE);
+    }
+    ccache = sudo_krb5_data.ccache;
+
+    if (error = krb5_cc_initialize(sudo_context, ccache, princ)) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to initialize ccache: %s", auth->name,
+                 error_message(error));
+       return(AUTH_FAILURE);
+    }
+
+    return(AUTH_SUCCESS);
+}
+
+int
+kerb5_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    krb5_context       sudo_context;
+    krb5_principal     princ;
+    krb5_ccache                ccache;
+    krb5_creds         creds;
+    krb5_error_code    error;
+    krb5_get_init_creds_opt opts;
+    char               cache_name[64];
+
+    sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+    princ = ((sudo_krb5_datap) auth->data)->princ;
+    ccache = ((sudo_krb5_datap) auth->data)->ccache;
+
+    /* Initialize options to defaults */
+    krb5_get_init_creds_opt_init(&opts);
+
+    /* Note that we always obtain a new TGT to verify the user */
+    if (error = krb5_get_init_creds_password(sudo_context, &creds, princ,
+                                            pass, krb5_prompter_posix,
+                                            NULL, 0, NULL, &opts)) {
+       if (error == KRB5KRB_AP_ERR_BAD_INTEGRITY) /* Bad password */
+           return(AUTH_FAILURE);
+       /* Some other error */
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to get credentials: %s", auth->name,
+                 error_message(error));
+       return(AUTH_FAILURE);
+    }
+
+    /* Stash the TGT so we can verify it. */
+    if (error = krb5_cc_store_cred(sudo_context, ccache, &creds)) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to store credentials: %s", auth->name,
+                 error_message(error));
+    } else {
+       error = verify_krb_v5_tgt(sudo_context, ccache, auth->name);
+    }
+
+    krb5_free_cred_contents(sudo_context, &creds);
+    return (error ? AUTH_FAILURE : AUTH_SUCCESS);
+}
+
+int
+kerb5_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+    krb5_context       sudo_context;
+    krb5_principal     princ;
+    krb5_ccache                ccache;
+
+    sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+    princ = ((sudo_krb5_datap) auth->data)->princ;
+    ccache = ((sudo_krb5_datap) auth->data)->ccache;
+
+    if (sudo_context) {
+       if (ccache)
+           krb5_cc_destroy(sudo_context, ccache);
+       if (princ)
+           krb5_free_principal(sudo_context, princ);
+       krb5_free_context(sudo_context);
+    }
+
+    return(AUTH_SUCCESS);
+}
+
+/*
+ * This routine with some modification is from the MIT V5B6 appl/bsd/login.c
+ *
+ * Verify the Kerberos ticket-granting ticket just retrieved for the
+ * user.  If the Kerberos server doesn't respond, assume the user is
+ * trying to fake us out (since we DID just get a TGT from what is
+ * supposedly our KDC). If the host/<host> service is unknown (i.e.,
+ * the local keytab doesn't have it), return success but log the error.
+ *
+ * This needs to run as root (to read the host service ticket).
+ *
+ * Returns 0 for successful authentication, non-zero for failure.
+ */
+static int
+verify_krb_v5_tgt(sudo_context, ccache, auth_name)
+    krb5_context       sudo_context;
+    krb5_ccache                ccache;
+    char               *auth_name; /* For error reporting */
+{
+    char               phost[BUFSIZ];
+    krb5_error_code    error;
+    krb5_principal     princ;
+    krb5_data          packet;
+    krb5_keyblock      *keyblock = 0;
+    krb5_auth_context  auth_context = NULL;
+
+    packet.data = 0;
+
+    /*
+     * Get the server principal for the local host.
+     * (Use defaults of "host" and canonicalized local name.)
+     */
+    if (error = krb5_sname_to_principal(sudo_context, NULL, NULL,
+                                       KRB5_NT_SRV_HST, &princ)) {
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: unable to get host principal: %s", auth_name,
+                 error_message(error));
+       return(-1);
+    }
+
+    /* Extract the name directly. Yow. */
+    strncpy(phost, krb5_princ_component(sudo_context, princ, 1)->data,
+           sizeof(phost) - 1);
+    phost[sizeof(phost) - 1] = '\0';
+
+    /*
+     * Do we have host/<host> keys?
+     * (use default keytab, kvno IGNORE_VNO to get the first match,
+     * and enctype is currently ignored anyhow.)
+     */
+    if (error = krb5_kt_read_service_key(sudo_context, NULL, princ, 0,
+                                        ENCTYPE_DES_CBC_MD5, &keyblock)) {
+       /* Keytab or service key does not exist. */
+       log_error(NO_EXIT,
+                 "%s: host service key not found: %s", auth_name,
+                 error_message(error));
+       error = 0;
+       goto cleanup;
+    }
+    if (keyblock)
+       krb5_free_keyblock(sudo_context, keyblock);
+
+    /* Talk to the kdc and construct the ticket. */
+    error = krb5_mk_req(sudo_context, &auth_context, 0, "host", phost,
+                       NULL, ccache, &packet);
+    if (auth_context) {
+       krb5_auth_con_free(sudo_context, auth_context);
+       auth_context = NULL;    /* setup for rd_req */
+    }
+
+    /* Try to use the ticket. */
+    if (!error)
+       error = krb5_rd_req(sudo_context, &auth_context, &packet, princ,
+                           NULL, NULL, NULL);
+cleanup:
+    if (packet.data)
+       krb5_free_data_contents(sudo_context, &packet);
+    krb5_free_principal(sudo_context, princ);
+
+    if (error)
+       log_error(NO_EXIT|NO_MAIL, 
+                 "%s: Cannot verify TGT! Possible attack!: %s", auth_name,
+                 error_message(error));
+    return(error);
+}
diff --git a/auth/pam.c b/auth/pam.c
new file mode 100644 (file)
index 0000000..28603f5
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include <security/pam_appl.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: pam.c,v 1.29 2002/01/22 16:43:23 millert Exp $";
+#endif /* lint */
+
+static int sudo_conv __P((int, PAM_CONST struct pam_message **,
+                         struct pam_response **, VOID *));
+static char *def_prompt;
+
+#ifndef PAM_DATA_SILENT
+#define PAM_DATA_SILENT        0
+#endif
+
+int
+pam_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static struct pam_conv pam_conv;
+    pam_handle_t *pamh;
+
+    /* Initial PAM setup */
+    pam_conv.conv = sudo_conv;
+    if (pam_start("sudo", pw->pw_name, &pam_conv, &pamh) != PAM_SUCCESS) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, 
+           "unable to initialize PAM");
+       return(AUTH_FATAL);
+    }
+    if (strcmp(user_tty, "unknown"))
+       (void) pam_set_item(pamh, PAM_TTY, user_tty);
+
+    auth->data = (VOID *) pamh;
+    return(AUTH_SUCCESS);
+}
+
+int
+pam_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    int error;
+    const char *s;
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
+
+    def_prompt = prompt;       /* for sudo_conv */
+
+    /* PAM_SILENT prevents the authentication service from generating output. */
+    error = pam_authenticate(pamh, PAM_SILENT);
+    switch (error) {
+       case PAM_SUCCESS:
+           return(AUTH_SUCCESS);
+       case PAM_AUTH_ERR:
+       case PAM_MAXTRIES:
+           return(AUTH_FAILURE);
+       default:
+           if ((s = pam_strerror(pamh, error)))
+               log_error(NO_EXIT|NO_MAIL, "pam_authenticate: %s", s);
+           return(AUTH_FATAL);
+    }
+}
+
+int
+pam_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
+    int status = PAM_DATA_SILENT;
+
+    /* Convert AUTH_FOO -> PAM_FOO as best we can. */
+    /* XXX - store real value somewhere in auth->data and use it */
+    switch (auth->status) {
+       case AUTH_SUCCESS:
+           status |= PAM_SUCCESS;
+           break;
+       case AUTH_FAILURE:
+           status |= PAM_AUTH_ERR;
+           break;
+       case AUTH_FATAL:
+       default:
+           status |= PAM_ABORT;
+           break;
+    }
+
+    if (pam_end(pamh, status) == PAM_SUCCESS)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
+
+int
+pam_prep_user(pw)
+    struct passwd *pw;
+{
+    struct pam_conv pam_conv;
+    pam_handle_t *pamh;
+
+    /* We need to setup a new PAM session for the user we are changing *to*. */
+    pam_conv.conv = sudo_conv;
+    if (pam_start("sudo", pw->pw_name, &pam_conv, &pamh) != PAM_SUCCESS) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, 
+           "unable to initialize PAM");
+       return(AUTH_FATAL);
+    }
+    (void) pam_set_item(pamh, PAM_RUSER, user_name);
+    if (strcmp(user_tty, "unknown"))
+       (void) pam_set_item(pamh, PAM_TTY, user_tty);
+
+    /*
+     * Set credentials (may include resource limits, device ownership, etc).
+     * We don't check the return value here because in Linux-PAM 0.75
+     * it returns the last saved return code, not the return code
+     * for the setcred module.  Because we haven't called pam_authenticate(),
+     * this is not set and so pam_setcred() returns PAM_PERM_DENIED.
+     * We can't call pam_acct_mgmt() with Linux-PAM for a similar reason.
+     */
+    (void) pam_setcred(pamh, PAM_ESTABLISH_CRED);
+
+    if (pam_end(pamh, PAM_SUCCESS) == PAM_SUCCESS)
+       return(PAM_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
+
+/*
+ * ``Conversation function'' for PAM.
+ * XXX - does not handle PAM_BINARY_PROMPT
+ */
+static int
+sudo_conv(num_msg, msg, response, appdata_ptr)
+    int num_msg;
+    PAM_CONST struct pam_message **msg;
+    struct pam_response **response;
+    VOID *appdata_ptr;
+{
+    struct pam_response *pr;
+    PAM_CONST struct pam_message *pm;
+    const char *p = def_prompt;
+    char *pass;
+    int n;
+    extern int nil_pw;
+
+    if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
+       return(PAM_CONV_ERR);
+    (void) memset(*response, 0, num_msg * sizeof(struct pam_response));
+
+    for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
+       switch (pm->msg_style) {
+           case PAM_PROMPT_ECHO_ON:
+               tgetpass_flags |= TGP_ECHO;
+           case PAM_PROMPT_ECHO_OFF:
+               /* Only override PAM prompt if it matches /^Password: ?/ */
+               if (strncmp(pm->msg, "Password:", 9) || (pm->msg[9] != '\0'
+                   && (pm->msg[9] != ' ' || pm->msg[10] != '\0')))
+                   p = pm->msg;
+               /* Read the password. */
+               pass = tgetpass(p, def_ival(I_PASSWD_TIMEOUT) * 60,
+                   tgetpass_flags);
+               pr->resp = estrdup(pass ? pass : "");
+               if (*pr->resp == '\0')
+                   nil_pw = 1;         /* empty password */
+               else
+                   memset(pass, 0, strlen(pass));
+               break;
+           case PAM_TEXT_INFO:
+               if (pm->msg)
+                   (void) puts(pm->msg);
+               break;
+           case PAM_ERROR_MSG:
+               if (pm->msg) {
+                   (void) fputs(pm->msg, stderr);
+                   (void) fputc('\n', stderr);
+               }
+               break;
+           default:
+               /* Zero and free allocated memory and return an error. */
+               for (pr = *response, n = num_msg; n--; pr++) {
+                   if (pr->resp != NULL) {
+                       (void) memset(pr->resp, 0, strlen(pr->resp));
+                       free(pr->resp);
+                       pr->resp = NULL;
+                   }
+               }
+               (void) memset(*response, 0,
+                   num_msg * sizeof(struct pam_response));
+               free(*response);
+               *response = NULL;
+               return(PAM_CONV_ERR);
+       }
+    }
+
+    return(PAM_SUCCESS);
+}
diff --git a/auth/passwd.c b/auth/passwd.c
new file mode 100644 (file)
index 0000000..98a9fdb
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: passwd.c,v 1.11 2002/01/17 15:56:15 millert Exp $";
+#endif /* lint */
+
+#define DESLEN                 13
+#define HAS_AGEINFO(p, l)      (l == 18 && p[DESLEN] == ',')
+
+int
+passwd_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+#ifdef HAVE_SKEYACCESS
+    if (skeyaccess(pw, user_tty, NULL, NULL) == 0)
+       return(AUTH_FAILURE);
+#endif
+    return(AUTH_SUCCESS);
+}
+
+int
+passwd_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    char sav, *epass;
+    size_t pw_len;
+    int error;
+
+    pw_len = strlen(pw->pw_passwd);
+
+#ifdef HAVE_GETAUTHUID
+    /* Ultrix shadow passwords may use crypt16() */
+    error = strcmp(pw->pw_passwd, (char *) crypt16(pass, pw->pw_passwd));
+    if (!error)
+       return(AUTH_SUCCESS);
+#endif /* HAVE_GETAUTHUID */
+
+    /*
+     * Truncate to 8 chars if standard DES since not all crypt()'s do this.
+     * If this turns out not to be safe we will have to use OS #ifdef's (sigh).
+     */
+    sav = pass[8];
+    if (pw_len == DESLEN || HAS_AGEINFO(pw->pw_passwd, pw_len))
+       pass[8] = '\0';
+
+    /*
+     * Normal UN*X password check.
+     * HP-UX may add aging info (separated by a ',') at the end so
+     * only compare the first DESLEN characters in that case.
+     */
+    epass = (char *) crypt(pass, pw->pw_passwd);
+    pass[8] = sav;
+    if (HAS_AGEINFO(pw->pw_passwd, pw_len) && strlen(epass) == DESLEN)
+       error = strncmp(pw->pw_passwd, epass, DESLEN);
+    else
+       error = strcmp(pw->pw_passwd, epass);
+
+    return(error ? AUTH_FAILURE : AUTH_SUCCESS);
+}
diff --git a/auth/rfc1938.c b/auth/rfc1938.c
new file mode 100644 (file)
index 0000000..0ad125d
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1994-1996, 1998-1999, 2001
+ *     Todd C. Miller <Todd.Miller@courtesan.com>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#if defined(HAVE_SKEY)
+#include <skey.h>
+#define RFC1938                        skey
+#define rfc1938challenge       skeychallenge
+#define rfc1938verify          skeyverify
+#elif defined(HAVE_OPIE)
+#include <opie.h>
+#define RFC1938                        opie
+#define rfc1938challenge       opiechallenge
+#define rfc1938verify          opieverify
+#endif
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: rfc1938.c,v 1.9 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+int
+rfc1938_setup(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    char challenge[256];
+    static char *orig_prompt = NULL, *new_prompt = NULL;
+    static int op_len, np_size;
+    static struct RFC1938 rfc1938;
+
+    /* Stash a pointer to the rfc1938 struct if we have not initialized */
+    if (!auth->data)
+       auth->data = &rfc1938;
+
+    /* Save the original prompt */
+    if (orig_prompt == NULL) {
+       orig_prompt = *promptp;
+       op_len = strlen(orig_prompt);
+
+       /* Ignore trailing colon (we will add our own) */
+       if (orig_prompt[op_len - 1] == ':')
+           op_len--;
+       else if (op_len >= 2 && orig_prompt[op_len - 1] == ' '
+           && orig_prompt[op_len - 2] == ':')
+           op_len -= 2;
+    }
+
+#ifdef HAVE_SKEY
+    /* Close old stream */
+    if (rfc1938.keyfile)
+       (void) fclose(rfc1938.keyfile);
+#endif
+
+    /*
+     * Look up the user and get the rfc1938 challenge.
+     * If the user is not in the OTP db, only post a fatal error if
+     * we are running alone (since they may just use a normal passwd).
+     */
+    if (rfc1938challenge(&rfc1938, pw->pw_name, challenge) != 0) {
+       if (IS_ONEANDONLY(auth)) {
+           (void) fprintf(stderr,
+                          "%s: You do not exist in the %s database.\n",
+                          Argv[0], auth->name);
+           return(AUTH_FATAL);
+       } else {
+           return(AUTH_FAILURE);
+       }
+    }
+
+    /* Get space for new prompt with embedded challenge */
+    if (np_size < op_len + strlen(challenge) + 7) {
+       np_size = op_len + strlen(challenge) + 7;
+       new_prompt = (char *) erealloc(new_prompt, np_size);
+    }
+
+    if (def_flag(I_LONG_OTP_PROMPT))
+       (void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt);
+    else
+       (void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt,
+           challenge);
+
+    *promptp = new_prompt;
+    return(AUTH_SUCCESS);
+}
+
+int
+rfc1938_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+
+    if (rfc1938verify((struct RFC1938 *) auth->data, pass) == 0)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
diff --git a/auth/secureware.c b/auth/secureware.c
new file mode 100644 (file)
index 0000000..4ed7297
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1998, 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#ifdef __hpux
+#  undef MAXINT
+#  include <hpsecurity.h>
+#else
+#  include <sys/security.h>
+#endif /* __hpux */
+#include <prot.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: secureware.c,v 1.8 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+int
+secureware_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+#ifdef __alpha
+    extern int crypt_type;
+
+    if (crypt_type == INT_MAX)
+       return(AUTH_FAILURE);                   /* no shadow */
+#endif
+    return(AUTH_SUCCESS);
+}
+
+int
+secureware_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+#ifdef __alpha
+    extern int crypt_type;
+
+#  ifdef HAVE_DISPCRYPT
+    if (strcmp(user_passwd, dispcrypt(pass, user_passwd, crypt_type)) == 0)
+       return(AUTH_SUCCESS);
+#  else
+    if (crypt_type == AUTH_CRYPT_BIGCRYPT) {
+       if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0)
+           return(AUTH_SUCCESS);
+    } else if (crypt_type == AUTH_CRYPT_CRYPT16) {
+       if (strcmp(user_passwd, crypt(pass, user_passwd)) == 0)
+           return(AUTH_SUCCESS);
+    }
+#  endif /* HAVE_DISPCRYPT */
+#elif defined(HAVE_BIGCRYPT)
+    if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0)
+       return(AUTH_SUCCESS);
+#endif /* __alpha */
+
+       return(AUTH_FAILURE);
+}
diff --git a/auth/securid.c b/auth/securid.c
new file mode 100644 (file)
index 0000000..9da4d5e
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Giles Todd
+ * <giles@gt.demon.co.uk>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include <sdi_athd.h>
+#include <sdconf.h>
+#include <sdacmvls.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: securid.c,v 1.8 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+union config_record configure;
+
+int
+securid_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static struct SD_CLIENT sd_dat;            /* SecurID data block */
+
+    auth->data = (VOID *) &sd_dat;             /* For method-specific data */
+
+    if (creadcfg() == 0)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FATAL);
+}
+
+int
+securid_setup(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    struct SD_CLIENT *sd = (struct SD_CLIENT *) auth->data;
+
+    /* Re-initialize SecurID every time. */
+    if (sd_init(sd) == 0) {
+       strcpy(sd->username, pw->pw_name);
+       return(AUTH_SUCCESS);
+    } else {
+       (void) fprintf(stderr, "%s: Cannot contact SecurID server\n", Argv[0]);
+       return(AUTH_FATAL);
+    }
+}
+
+int
+securid_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    struct SD_CLIENT *sd = (struct SD_CLIENT *) auth->data;
+    int rval;
+
+    rval = sd_auth(sd);
+    sd_close();
+    if (rval == ACM_OK)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
diff --git a/auth/sia.c b/auth/sia.c
new file mode 100644 (file)
index 0000000..09b67e2
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Spider Boardman
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <siad.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: sia.c,v 1.10 2001/12/14 19:52:53 millert Exp $";
+#endif /* lint */
+
+static int sudo_collect        __P((int, int, uchar_t *, int, prompt_t *));
+
+static char *def_prompt;
+
+/*
+ * Collection routine (callback) for limiting the timeouts in SIA
+ * prompts and (possibly) setting a custom prompt.
+ */
+static int
+sudo_collect(timeout, rendition, title, nprompts, prompts)
+    int timeout;
+    int rendition;
+    uchar_t *title;
+    int nprompts;
+    prompt_t *prompts;
+{
+    switch (rendition) {
+       case SIAFORM:
+       case SIAONELINER:
+           if (timeout <= 0 || timeout > def_ival(I_PASSWD_TIMEOUT) * 60)
+               timeout = def_ival(I_PASSWD_TIMEOUT) * 60;
+           /*
+            * Substitute custom prompt if a) the sudo prompt is not "Password:"
+            * and b) the SIA prompt is "Password:" (so we know it is safe).
+            * This keeps us from overwriting things like S/Key challenges.
+            */
+           if (strcmp((char *)prompts[0].prompt, "Password:") == 0 &&
+               strcmp(def_prompt, "Password:") != 0)
+               prompts[0].prompt = (unsigned char *)def_prompt;
+           break;
+       default:
+           break;
+    }
+
+    return sia_collect_trm(timeout, rendition, title, nprompts, prompts);
+}
+
+int
+sia_setup(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    SIAENTITY *siah = NULL;
+
+    if (sia_ses_init(&siah, Argc, Argv, NULL, pw->pw_name, ttyname(0), 1, NULL)
+       != SIASUCCESS) {
+
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+           "unable to initialize SIA session");
+       return(AUTH_FATAL);
+    }
+
+    auth->data = (VOID *) siah;
+    return(AUTH_SUCCESS);
+}
+
+int
+sia_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    SIAENTITY *siah = (SIAENTITY *) auth->data;
+
+    def_prompt = prompt;               /* for sudo_collect */
+
+    /* XXX - need a way to detect user hitting return or EOF at prompt */
+    if (sia_ses_reauthent(sudo_collect, siah) == SIASUCCESS)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
+
+int
+sia_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+    SIAENTITY *siah = (SIAENTITY *) auth->data;
+
+    (void) sia_ses_release(&siah);
+    return(AUTH_SUCCESS);
+}
diff --git a/auth/sudo_auth.c b/auth/sudo_auth.c
new file mode 100644 (file)
index 0000000..eb4c3c4
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <time.h>
+#include <signal.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+#include "insults.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: sudo_auth.c,v 1.25 2001/12/14 19:52:54 millert Exp $";
+#endif /* lint */
+
+sudo_auth auth_switch[] = {
+#ifdef AUTH_STANDALONE
+    AUTH_STANDALONE
+#else
+#  ifndef WITHOUT_PASSWD
+    AUTH_ENTRY(0, "passwd", passwd_init, NULL, passwd_verify, NULL)
+#  endif
+#  if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
+    AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL)
+#  endif
+#  ifdef HAVE_AFS
+    AUTH_ENTRY(0, "afs", NULL, NULL, afs_verify, NULL)
+#  endif
+#  ifdef HAVE_DCE
+    AUTH_ENTRY(0, "dce", NULL, NULL, dce_verify, NULL)
+#  endif
+#  ifdef HAVE_KERB4
+    AUTH_ENTRY(0, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
+#  endif
+#  ifdef HAVE_KERB5
+    AUTH_ENTRY(0, "kerb5", kerb5_init, NULL, kerb5_verify, kerb5_cleanup)
+#  endif
+#  ifdef HAVE_SKEY
+    AUTH_ENTRY(0, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL)
+#  endif
+#  ifdef HAVE_OPIE
+    AUTH_ENTRY(0, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL)
+#  endif
+#endif /* AUTH_STANDALONE */
+    AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL)
+};
+
+int nil_pw;            /* I hate resorting to globals like this... */
+
+void
+verify_user(pw, prompt)
+    struct passwd *pw;
+    char *prompt;
+{
+    int counter = def_ival(I_PASSWD_TRIES) + 1;
+    int success = AUTH_FAILURE;
+    int status;
+    int flags;
+    char *p;
+    sudo_auth *auth;
+    sigaction_t sa, osa;
+
+    /* Enable suspend during password entry. */
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = SIG_DFL;
+    (void) sigaction(SIGTSTP, &sa, &osa);
+
+    /* Make sure we have at least one auth method. */
+    if (auth_switch[0].name == NULL)
+       log_error(0, "%s  %s %s",
+           "There are no authentication methods compiled into sudo!",
+           "If you want to turn off authentication, use the",
+           "--disable-authentication configure option.");
+
+    /* Set FLAG_ONEANDONLY if there is only one auth method. */
+    if (auth_switch[1].name == NULL)
+       auth_switch[0].flags |= FLAG_ONEANDONLY;
+
+    /* Initialize auth methods and unconfigure the method if necessary. */
+    for (auth = auth_switch; auth->name; auth++) {
+       if (auth->init && IS_CONFIGURED(auth)) {
+           if (NEEDS_USER(auth))
+               set_perms(PERM_USER, 0);
+
+           status = (auth->init)(pw, &prompt, auth);
+           if (status == AUTH_FAILURE)
+               auth->flags &= ~FLAG_CONFIGURED;
+           else if (status == AUTH_FATAL)      /* XXX log */
+               exit(1);                /* assume error msg already printed */
+
+           if (NEEDS_USER(auth))
+               set_perms(PERM_ROOT, 0);
+       }
+    }
+
+    while (--counter) {
+       /* Do any per-method setup and unconfigure the method if needed */
+       for (auth = auth_switch; auth->name; auth++) {
+           if (auth->setup && IS_CONFIGURED(auth)) {
+               if (NEEDS_USER(auth))
+                   set_perms(PERM_USER, 0);
+
+               status = (auth->setup)(pw, &prompt, auth);
+               if (status == AUTH_FAILURE)
+                   auth->flags &= ~FLAG_CONFIGURED;
+               else if (status == AUTH_FATAL)  /* XXX log */
+                   exit(1);            /* assume error msg already printed */
+
+               if (NEEDS_USER(auth))
+                   set_perms(PERM_ROOT, 0);
+           }
+       }
+
+       /* Get the password unless the auth function will do it for us */
+       nil_pw = 0;
+#ifdef AUTH_STANDALONE
+       p = prompt;
+#else
+       p = (char *) tgetpass(prompt, def_ival(I_PASSWD_TIMEOUT) * 60,
+           tgetpass_flags);
+       if (!p || *p == '\0')
+           nil_pw = 1;
+#endif /* AUTH_STANDALONE */
+
+       /* Call authentication functions. */
+       for (auth = auth_switch; p && auth->name; auth++) {
+           if (!IS_CONFIGURED(auth))
+               continue;
+
+           if (NEEDS_USER(auth))
+               set_perms(PERM_USER, 0);
+
+           success = auth->status = (auth->verify)(pw, p, auth);
+
+           if (NEEDS_USER(auth))
+               set_perms(PERM_ROOT, 0);
+
+           if (auth->status != AUTH_FAILURE)
+               goto cleanup;
+       }
+#ifndef AUTH_STANDALONE
+       if (p)
+           (void) memset(p, 0, strlen(p));
+#endif
+
+       /* Exit loop on nil password, but give it a chance to match first. */
+       if (nil_pw) {
+           if (counter == def_ival(I_PASSWD_TRIES))
+               exit(1);
+           else
+               break;
+       }
+
+       pass_warn(stderr);
+    }
+
+cleanup:
+    /* Call cleanup routines. */
+    for (auth = auth_switch; auth->name; auth++) {
+       if (auth->cleanup && IS_CONFIGURED(auth)) {
+           if (NEEDS_USER(auth))
+               set_perms(PERM_USER, 0);
+
+           status = (auth->cleanup)(pw, auth);
+           if (status == AUTH_FATAL)   /* XXX log */
+               exit(1);                /* assume error msg already printed */
+
+           if (NEEDS_USER(auth))
+               set_perms(PERM_ROOT, 0);
+       }
+    }
+
+    switch (success) {
+       case AUTH_SUCCESS:
+           (void) sigaction(SIGTSTP, &osa, NULL);
+           return;
+       case AUTH_FAILURE:
+           if (def_flag(I_MAIL_BADPASS) || def_flag(I_MAIL_ALWAYS))
+               flags = 0;
+           else
+               flags = NO_MAIL;
+           log_error(flags, "%d incorrect password attempt%s",
+               def_ival(I_PASSWD_TRIES) - counter,
+               (def_ival(I_PASSWD_TRIES) - counter == 1) ? "" : "s");
+       case AUTH_FATAL:
+           exit(1);
+    }
+    /* NOTREACHED */
+}
+
+void
+pass_warn(fp)
+    FILE *fp;
+{
+
+#ifdef INSULT
+    if (def_flag(I_INSULTS))
+       (void) fprintf(fp, "%s\n", INSULT);
+    else
+#endif
+       (void) fprintf(fp, "%s\n", def_str(I_BADPASS_MESSAGE));
+}
+
+void
+dump_auth_methods()
+{
+    sudo_auth *auth;
+
+    (void) fputs("Authentication methods:", stdout);
+    for (auth = auth_switch; auth->name; auth++)
+        (void) printf(" '%s'", auth->name);
+    (void) putchar('\n');
+}
diff --git a/auth/sudo_auth.h b/auth/sudo_auth.h
new file mode 100644 (file)
index 0000000..f2db87d
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: sudo_auth.h,v 1.19 2001/12/14 19:55:01 millert Exp $
+ */
+
+#ifndef SUDO_AUTH_H
+#define SUDO_AUTH_H
+
+/* Auth function return values.  */
+#define AUTH_SUCCESS   0
+#define AUTH_FAILURE   1
+#define AUTH_FATAL     2
+
+typedef struct sudo_auth {
+    short flags;               /* various flags, see below */
+    short status;              /* status from verify routine */
+    char *name;                        /* name of the method as a string */
+    VOID *data;                        /* method-specific data pointer */
+    int (*init) __P((struct passwd *pw, char **prompt, struct sudo_auth *auth));
+    int (*setup) __P((struct passwd *pw, char **prompt, struct sudo_auth *auth));
+    int (*verify) __P((struct passwd *pw, char *p, struct sudo_auth *auth));
+    int (*cleanup) __P((struct passwd *pw, struct sudo_auth *auth));
+} sudo_auth;
+
+/* Values for sudo_auth.flags.  */
+/* XXX - these names are too long for my liking */
+#define FLAG_USER      0x01    /* functions must run as the user, not root */
+#define FLAG_CONFIGURED        0x02    /* method configured ok */
+#define FLAG_ONEANDONLY        0x04    /* one and only auth method */
+
+/* Shortcuts for using the flags above. */
+#define NEEDS_USER(x)          ((x)->flags & FLAG_USER)
+#define IS_CONFIGURED(x)       ((x)->flags & FLAG_CONFIGURED)
+#define IS_ONEANDONLY(x)       ((x)->flags & FLAG_ONEANDONLY)
+
+/* Prototypes for standalone methods */
+int fwtk_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int fwtk_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int fwtk_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int pam_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int pam_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int pam_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int sia_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int sia_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int sia_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int aixauth_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int bsdauth_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int bsdauth_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int bsdauth_cleanup __P((struct passwd *pw, sudo_auth *auth));
+
+/* Prototypes for normal methods */
+int passwd_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int passwd_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int secureware_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int secureware_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int rfc1938_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int rfc1938_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int afs_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int dce_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int kerb4_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int kerb4_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int kerb5_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int kerb5_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int kerb5_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int securid_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int securid_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int securid_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+
+/* Fields: need_root, name, init, setup, verify, cleanup */
+#define AUTH_ENTRY(r, n, i, s, v, c) \
+       { (r|FLAG_CONFIGURED), AUTH_FAILURE, n, NULL, i, s, v, c },
+
+/* Some methods cannots (or should not) interoperate with any others */
+#if defined(HAVE_PAM)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "pam", \
+           pam_init, NULL, pam_verify, pam_cleanup)
+#elif defined(HAVE_SECURID)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "SecurId", \
+           securid_init, securid_setup, securid_verify, NULL)
+#elif defined(HAVE_SIA)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "sia", \
+           NULL, sia_setup, sia_verify, sia_cleanup)
+#elif defined(HAVE_AUTHENTICATE)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "aixauth", \
+           NULL, NULL, aixauth_verify, NULL)
+#elif defined(HAVE_FWTK)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "fwtk", \
+           fwtk_init, NULL, fwtk_verify, fwtk_cleanup)
+#elif defined(HAVE_BSD_AUTH_H)
+#  define AUTH_STANDALONE \
+       AUTH_ENTRY(0, "bsdauth", \
+           bsdauth_init, NULL, bsdauth_verify, bsdauth_cleanup)
+#endif
+
+#endif /* SUDO_AUTH_H */
diff --git a/check.c b/check.c
new file mode 100644 (file)
index 0000000..242aa00
--- /dev/null
+++ b/check.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 1993-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <time.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: check.c,v 1.203 2002/04/25 15:30:12 millert Exp $";
+#endif /* lint */
+
+/* Status codes for timestamp_status() */
+#define TS_CURRENT             0
+#define TS_OLD                 1
+#define TS_MISSING             2
+#define TS_NOFILE              3
+#define TS_ERROR               4
+
+static void  build_timestamp   __P((char **, char **));
+static int   timestamp_status  __P((char *, char *, char *, int));
+static char *expand_prompt     __P((char *, char *, char *));
+static void  lecture           __P((void));
+static void  update_timestamp  __P((char *, char *));
+
+/*
+ * This function only returns if the user can successfully
+ * verify who he/she is.  
+ */
+void
+check_user()
+{
+    char *timestampdir = NULL;
+    char *timestampfile = NULL;
+    char *prompt;
+    int status;
+
+    if (user_uid == 0 || user_is_exempt())
+       return;
+
+    build_timestamp(&timestampdir, &timestampfile);
+    status = timestamp_status(timestampdir, timestampfile, user_name, TRUE);
+    if (status != TS_CURRENT) {
+       if (status == TS_MISSING || status == TS_ERROR)
+           lecture();          /* first time through they get a lecture */
+
+       /* Expand any escapes in the prompt. */
+       prompt = expand_prompt(user_prompt ? user_prompt : def_str(I_PASSPROMPT),
+           user_name, user_shost);
+
+       verify_user(auth_pw, prompt);
+    }
+    if (status != TS_ERROR)
+       update_timestamp(timestampdir, timestampfile);
+    free(timestampdir);
+    if (timestampfile)
+       free(timestampfile);
+}
+
+/*
+ * Standard sudo lecture.
+ * TODO: allow the user to specify a file name instead.
+ */
+static void
+lecture()
+{
+
+    if (def_flag(I_LECTURE)) {
+       (void) fputs("\n\
+We trust you have received the usual lecture from the local System\n\
+Administrator. It usually boils down to these two things:\n\
+\n\
+       #1) Respect the privacy of others.\n\
+       #2) Think before you type.\n\n",
+       stderr);
+    }
+}
+
+/*
+ * Update the time on the timestamp file/dir or create it if necessary.
+ */
+static void
+update_timestamp(timestampdir, timestampfile)
+    char *timestampdir;
+    char *timestampfile;
+{
+
+    if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
+       if (timestampfile) {
+           int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+
+           if (fd == -1)
+               log_error(NO_EXIT|USE_ERRNO, "Can't open %s", timestampfile);
+           else
+               close(fd);
+       } else {
+           if (mkdir(timestampdir, 0700) == -1)
+               log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
+       }
+    }
+}
+
+/*
+ * Expand %h and %u escapes in the prompt and pass back the dynamically
+ * allocated result.  Returns the same string if there are no escapes.
+ */
+static char *
+expand_prompt(old_prompt, user, host)
+    char *old_prompt;
+    char *user;
+    char *host;
+{
+    size_t len;
+    int subst;
+    char *p, *np, *new_prompt, lastchar;
+
+    /* How much space do we need to malloc for the prompt? */
+    subst = 0;
+    for (p = old_prompt, len = strlen(old_prompt), lastchar = '\0'; *p; p++) {
+       if (lastchar == '%') {
+           if (*p == 'h') {
+               len += strlen(user_shost) - 2;
+               subst = 1;
+           } else if (*p == 'u') {
+               len += strlen(user_name) - 2;
+               subst = 1;
+           }
+       }
+
+       if (lastchar == '%' && *p == '%') {
+           lastchar = '\0';
+           len--;
+       } else
+           lastchar = *p;
+    }
+
+    if (subst) {
+       new_prompt = (char *) emalloc(len + 1);
+       for (p = old_prompt, np = new_prompt, lastchar = '\0'; *p; p++) {
+           if (lastchar == '%' && (*p == 'h' || *p == 'u' || *p == '%')) {
+               /* substitute user/host name */
+               if (*p == 'h') {
+                   np--;
+                   strcpy(np, user_shost);
+                   np += strlen(user_shost);
+               } else if (*p == 'u') {
+                   np--;
+                   strcpy(np, user_name);
+                   np += strlen(user_name);
+               }
+           } else
+               *np++ = *p;
+
+           if (lastchar == '%' && *p == '%')
+               lastchar = '\0';
+           else
+               lastchar = *p;
+       }
+       *np = '\0';
+    } else
+       new_prompt = old_prompt;
+
+    return(new_prompt);
+}
+
+/*
+ * Checks if the user is exempt from supplying a password.
+ */
+int
+user_is_exempt()
+{
+    struct group *grp;
+    char **gr_mem;
+
+    if (!def_str(I_EXEMPT_GROUP))
+       return(FALSE);
+
+    if (!(grp = getgrnam(def_str(I_EXEMPT_GROUP))))
+       return(FALSE);
+
+    if (user_gid == grp->gr_gid)
+       return(TRUE);
+
+    for (gr_mem = grp->gr_mem; *gr_mem; gr_mem++) {
+       if (strcmp(user_name, *gr_mem) == 0)
+           return(TRUE);
+    }
+
+    return(FALSE);
+}
+
+/*
+ * Fills in timestampdir as well as timestampfile if using tty tickets.
+ */
+static void
+build_timestamp(timestampdir, timestampfile)
+    char **timestampdir;
+    char **timestampfile;
+{
+    char *dirparent;
+    int len;
+
+    dirparent = def_str(I_TIMESTAMPDIR);
+    len = easprintf(timestampdir, "%s/%s", dirparent, user_name);
+    if (len >= MAXPATHLEN)
+       log_error(0, "timestamp path too long: %s", timestampdir);
+
+    /*
+     * Timestamp file may be a file in the directory or NUL to use
+     * the directory as the timestamp.
+     */
+    if (def_flag(I_TTY_TICKETS)) {
+       char *p;
+
+       if ((p = strrchr(user_tty, '/')))
+           p++;
+       else
+           p = user_tty;
+       if (def_flag(I_TARGETPW))
+           len = easprintf(timestampfile, "%s/%s/%s:%s", dirparent, user_name,
+               p, *user_runas);
+       else
+           len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p);
+       if (len >= MAXPATHLEN)
+           log_error(0, "timestamp path too long: %s", timestampfile);
+    } else if (def_flag(I_TARGETPW)) {
+       len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name,
+           *user_runas);
+       if (len >= MAXPATHLEN)
+           log_error(0, "timestamp path too long: %s", timestampfile);
+    } else
+       *timestampfile = NULL;
+}
+
+/*
+ * Check the timestamp file and directory and return their status.
+ */
+static int
+timestamp_status(timestampdir, timestampfile, user, make_dirs)
+    char *timestampdir;
+    char *timestampfile;
+    char *user;
+    int make_dirs;
+{
+    struct stat sb;
+    time_t now;
+    char *dirparent = def_str(I_TIMESTAMPDIR);
+    int status = TS_ERROR;             /* assume the worst */
+
+    /*
+     * Sanity check dirparent and make it if it doesn't already exist.
+     * We start out assuming the worst (that the dir is not sane) and
+     * if it is ok upgrade the status to ``no timestamp file''.
+     * Note that we don't check the parent(s) of dirparent for
+     * sanity since the sudo dir is often just located in /tmp.
+     */
+    if (lstat(dirparent, &sb) == 0) {
+       if (!S_ISDIR(sb.st_mode))
+           log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
+               dirparent, sb.st_mode);
+       else if (sb.st_uid != 0)
+           log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
+               dirparent, (long) sb.st_uid);
+       else if ((sb.st_mode & 0000022))
+           log_error(NO_EXIT,
+               "%s writable by non-owner (0%o), should be mode 0700",
+               dirparent, sb.st_mode);
+       else {
+           if ((sb.st_mode & 0000777) != 0700)
+               (void) chmod(dirparent, 0700);
+           status = TS_MISSING;
+       }
+    } else if (errno != ENOENT) {
+       log_error(NO_EXIT|USE_ERRNO, "can't stat %s", dirparent);
+    } else {
+       /* No dirparent, try to make one. */
+       if (make_dirs) {
+           if (mkdir(dirparent, S_IRWXU))
+               log_error(NO_EXIT|USE_ERRNO, "can't mkdir %s",
+                   dirparent);
+           else
+               status = TS_MISSING;
+       }
+    }
+    if (status == TS_ERROR)
+       return(status);
+
+    /*
+     * Sanity check the user's ticket dir.  We start by downgrading
+     * the status to TS_ERROR.  If the ticket dir exists and is sane
+     * this will be upgraded to TS_OLD.  If the dir does not exist,
+     * it will be upgraded to TS_MISSING.
+     */
+    status = TS_ERROR;                 /* downgrade status again */
+    if (lstat(timestampdir, &sb) == 0) {
+       if (!S_ISDIR(sb.st_mode)) {
+           if (S_ISREG(sb.st_mode)) {
+               /* convert from old style */
+               if (unlink(timestampdir) == 0)
+                   status = TS_MISSING;
+           } else
+               log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
+                   timestampdir, sb.st_mode);
+       } else if (sb.st_uid != 0)
+           log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
+               timestampdir, (long) sb.st_uid);
+       else if ((sb.st_mode & 0000022))
+           log_error(NO_EXIT,
+               "%s writable by non-owner (0%o), should be mode 0700",
+               timestampdir, sb.st_mode);
+       else {
+           if ((sb.st_mode & 0000777) != 0700)
+               (void) chmod(timestampdir, 0700);
+           status = TS_OLD;            /* do date check later */
+       }
+    } else if (errno != ENOENT) {
+       log_error(NO_EXIT|USE_ERRNO, "can't stat %s", timestampdir);
+    } else
+       status = TS_MISSING;
+
+    /*
+     * If there is no user ticket dir, AND we are in tty ticket mode,
+     * AND the make_dirs flag is set, create the user ticket dir.
+     */
+    if (status == TS_MISSING && timestampfile && make_dirs) {
+       if (mkdir(timestampdir, S_IRWXU) == -1) {
+           status = TS_ERROR;
+           log_error(NO_EXIT|USE_ERRNO, "can't mkdir %s", timestampdir);
+       }
+    }
+
+    /*
+     * Sanity check the tty ticket file if it exists.
+     */
+    if (timestampfile && status != TS_ERROR) {
+       if (status != TS_MISSING)
+           status = TS_NOFILE;                 /* dir there, file missing */
+       if (lstat(timestampfile, &sb) == 0) {
+           if (!S_ISREG(sb.st_mode)) {
+               status = TS_ERROR;
+               log_error(NO_EXIT, "%s exists but is not a regular file (0%o)",
+                   timestampfile, sb.st_mode);
+           } else {
+               /* If bad uid or file mode, complain and kill the bogus file. */
+               if (sb.st_uid != 0) {
+                   log_error(NO_EXIT,
+                       "%s owned by uid %ld, should be owned by root",
+                       timestampfile, (long) sb.st_uid);
+                   (void) unlink(timestampfile);
+               } else if ((sb.st_mode & 0000022)) {
+                   log_error(NO_EXIT,
+                       "%s writable by non-owner (0%o), should be mode 0600",
+                       timestampfile, sb.st_mode);
+                   (void) unlink(timestampfile);
+               } else {
+                   /* If not mode 0600, fix it. */
+                   if ((sb.st_mode & 0000777) != 0600)
+                       (void) chmod(timestampfile, 0600);
+
+                   status = TS_OLD;    /* actually check mtime below */
+               }
+           }
+       } else if (errno != ENOENT) {
+           log_error(NO_EXIT|USE_ERRNO, "can't stat %s", timestampfile);
+           status = TS_ERROR;
+       }
+    }
+
+    /*
+     * If the file/dir exists, check its mtime.
+     */
+    if (status == TS_OLD) {
+       /* Negative timeouts only expire manually (sudo -k). */
+       if (def_ival(I_TIMESTAMP_TIMEOUT) < 0 && sb.st_mtime != 0)
+           status = TS_CURRENT;
+       else {
+           now = time(NULL);
+           if (def_ival(I_TIMESTAMP_TIMEOUT) && 
+               now - sb.st_mtime < 60 * def_ival(I_TIMESTAMP_TIMEOUT)) {
+               /*
+                * Check for bogus time on the stampfile.  The clock may
+                * have been set back or someone could be trying to spoof us.
+                */
+               if (sb.st_mtime > now + 60 * def_ival(I_TIMESTAMP_TIMEOUT) * 2) {
+                   log_error(NO_EXIT,
+                       "timestamp too far in the future: %20.20s",
+                       4 + ctime(&sb.st_mtime));
+                   if (timestampfile)
+                       (void) unlink(timestampfile);
+                   else
+                       (void) rmdir(timestampdir);
+                   status = TS_MISSING;
+               } else
+                   status = TS_CURRENT;
+           }
+       }
+    }
+
+    return(status);
+}
+
+/*
+ * Remove the timestamp ticket file/dir.
+ */
+void
+remove_timestamp(remove)
+    int remove;
+{
+    char *timestampdir;
+    char *timestampfile;
+    char *ts;
+    int status;
+
+    build_timestamp(&timestampdir, &timestampfile);
+    status = timestamp_status(timestampdir, timestampfile, user_name, FALSE);
+    if (status == TS_OLD || status == TS_CURRENT) {
+       ts = timestampfile ? timestampfile : timestampdir;
+       if (remove) {
+           if (timestampfile)
+               status = unlink(timestampfile);
+           else
+               status = rmdir(timestampdir);
+           if (status == -1 && errno != ENOENT) {
+               log_error(NO_EXIT, "can't remove %s (%s), will reset to epoch",
+                   ts, strerror(errno));
+               remove = FALSE;
+           }
+       }
+       if (!remove && touch(ts, 0) == -1) {
+           (void) fprintf(stderr, "%s: can't reset %s to epoch: %s\n",
+               Argv[0], ts, strerror(errno));
+       }
+    }
+
+    free(timestampdir);
+    if (timestampfile)
+       free(timestampfile);
+}
diff --git a/compat.h b/compat.h
new file mode 100644 (file)
index 0000000..09f95e3
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 1996, 1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: compat.h,v 1.63 2002/01/25 18:38:22 millert Exp $
+ */
+
+#ifndef _SUDO_COMPAT_H
+#define _SUDO_COMPAT_H
+
+/*
+ * Macros that may be missing on some Operating Systems
+ */
+
+/* Deal with ANSI stuff reasonably.  */
+#ifndef  __P
+# if defined (__cplusplus) || defined (__STDC__)
+#  define __P(args)            args
+# else
+#  define __P(args)            ()
+# endif
+#endif /* __P */
+
+/*
+ * Some systems (ie ISC V/386) do not define MAXPATHLEN even in param.h
+ */
+#ifndef MAXPATHLEN
+# define MAXPATHLEN            1024
+#endif
+
+/*
+ * Some systems do not define MAXHOSTNAMELEN.
+ */
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN                64
+#endif
+
+/*
+ * 4.2BSD lacks FD_* macros (we only use FD_SET and FD_ZERO)
+ */
+#ifndef FD_SETSIZE
+# define FD_SET(fd, fds)       ((fds) -> fds_bits[0] |= (1 << (fd)))
+# define FD_ZERO(fds)          ((fds) -> fds_bits[0] = 0)
+#endif /* !FD_SETSIZE */
+
+/*
+ * Posix versions for those without...
+ */
+#ifndef _S_IFMT
+# define _S_IFMT               S_IFMT
+#endif /* _S_IFMT */
+#ifndef _S_IFREG
+# define _S_IFREG              S_IFREG
+#endif /* _S_IFREG */
+#ifndef _S_IFDIR
+# define _S_IFDIR              S_IFDIR
+#endif /* _S_IFDIR */
+#ifndef _S_IFLNK
+# define _S_IFLNK              S_IFLNK
+#endif /* _S_IFLNK */
+#ifndef S_ISREG
+# define S_ISREG(m)            (((m) & _S_IFMT) == _S_IFREG)
+#endif /* S_ISREG */
+#ifndef S_ISDIR
+# define S_ISDIR(m)            (((m) & _S_IFMT) == _S_IFDIR)
+#endif /* S_ISDIR */
+
+/*
+ * Some OS's may not have this.
+ */
+#ifndef S_IRWXU
+# define S_IRWXU               0000700         /* rwx for owner */
+#endif /* S_IRWXU */
+
+/*
+ * In case this is not defined in <sys/types.h> or <sys/select.h>
+ */
+#ifndef howmany
+# define howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+
+/*
+ * These should be defined in <unistd.h> but not everyone has them.
+ */
+#ifndef STDIN_FILENO
+# define       STDIN_FILENO    0
+#endif
+#ifndef STDOUT_FILENO
+# define       STDOUT_FILENO   1
+#endif
+#ifndef STDERR_FILENO
+# define       STDERR_FILENO   2
+#endif
+
+/*
+ * These should be defined in <unistd.h> but not everyone has them.
+ */
+#ifndef SEEK_SET
+# define       SEEK_SET        0
+#endif
+#ifndef SEEK_CUR
+# define       SEEK_CUR        1
+#endif
+#ifndef SEEK_END
+# define       SEEK_END        2
+#endif
+
+/*
+ * BSD defines these in <sys/param.h> but others may not.
+ */
+#ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/*
+ * Simple isblank() macro for systems without it.
+ */
+#ifndef HAVE_ISBLANK
+# define isblank(_x)   ((_x) == ' ' || (_x) == '\t')
+#endif
+
+/*
+ * Old BSD systems lack strchr(), strrchr(), memset() and memcpy()
+ */
+#if !defined(HAVE_STRCHR) && !defined(strchr)
+# define strchr(_s, _c)        index(_s, _c)
+#endif
+#if !defined(HAVE_STRRCHR) && !defined(strrchr)
+# define strrchr(_s, _c)       rindex(_s, _c)
+#endif
+#if !defined(HAVE_MEMCPY) && !defined(memcpy)
+# define memcpy(_d, _s, _n)    (bcopy(_s, _d, _n))
+#endif
+#if !defined(HAVE_MEMSET) && !defined(memset)
+# define memset(_s, _x, _n)    (bzero(_s, _n))
+#endif
+
+/*
+ * Emulate sete[ug]id() via setres[ug]id(2) or setre[ug]id(2)
+ */
+#ifndef HAVE_SETEUID
+# ifdef __hpux
+#  define seteuid(_EUID)       (setresuid((uid_t) -1, _EUID, (uid_t) -1))
+# else
+#  define seteuid(_EUID)       (setreuid((uid_t) -1, _EUID))
+# endif /* __hpux */
+#endif /* HAVE_SETEUID */
+#ifndef HAVE_SETEGID
+# ifdef __hpux
+#  define setegid(_EGID)       (setresgid((gid_t) -1, _EGID, (gid_t) -1))
+# else
+#  define setegid(_EGID)       (setregid((gid_t) -1, _EGID))
+# endif /* __hpux */
+#endif /* HAVE_SETEGID */
+
+/*
+ * Emulate setreuid() for HP-UX via setresuid(2)
+ */
+#if !defined(HAVE_SETREUID) && defined(__hpux)
+# define setreuid(_RUID, _EUID)        (setresuid(_RUID, _EUID, (uid_t) -1))
+# define HAVE_SETREUID
+#endif /* !HAVE_SETEUID && __hpux */
+
+/*
+ * NCR's SVr4 has _innetgr(3) instead of innetgr(3) for some reason.
+ */
+#ifdef HAVE__INNETGR
+# define innetgr(n, h, u, d)   (_innetgr(n, h, u, d))
+# define HAVE_INNETGR 1
+#endif /* HAVE__INNETGR */
+
+/*
+ * On POSIX systems, O_NOCTTY is the default so some OS's may lack this define.
+ */
+#ifndef O_NOCTTY
+# define O_NOCTTY      0
+#endif /* O_NOCTTY */
+
+/*
+ * Emulate POSIX signals via sigvec(2)
+ */
+#ifndef HAVE_SIGACTION
+# define SA_ONSTACK    SV_ONSTACK
+# define SA_RESTART    SV_INTERRUPT            /* opposite effect */
+# define SA_RESETHAND  SV_RESETHAND
+# define sa_handler    sv_handler
+# define sa_mask       sv_mask
+# define sa_flags      sv_flags
+typedef struct sigvec sigaction_t;
+typedef int sigset_t;
+int sigaction __P((int sig, const sigaction_t *act, sigaction_t *oact));
+int sigemptyset __P((sigset_t *));
+int sigfillset __P((sigset_t *));
+int sigaddset __P((sigset_t *, int));
+int sigdelset __P((sigset_t *, int));
+int sigismember __P((sigset_t *, int));
+int sigprocmask __P((int, const sigset_t *, sigset_t *));
+#endif
+
+/*
+ * Extra sugar for POSIX signals to deal with the above emulation
+ * as well as the fact that SunOS has a SA_INTERRUPT flag.
+ */
+#ifdef HAVE_SIGACTION
+# ifndef HAVE_SIGACTION_T
+typedef struct sigaction sigaction_t;
+# endif
+# ifndef SA_INTERRUPT 
+#  define SA_INTERRUPT 0
+# endif
+# ifndef SA_RESTART 
+#  define SA_RESTART   0
+# endif
+#endif
+
+/*
+ * HP-UX 9.x has RLIMIT_* but no RLIM_INFINITY.
+ * Using -1 works because we only check for RLIM_INFINITY and do not set it.
+ */
+#ifndef RLIM_INFINITY
+# define RLIM_INFINITY (-1)
+#endif
+
+#endif /* _SUDO_COMPAT_H */
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..6012b39
--- /dev/null
@@ -0,0 +1,1298 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-07-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+       for c in cc gcc c89 ; do
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+         if test $? = 0 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # Netbsd (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       # Determine the machine/vendor (is the vendor relevant).
+       case "${UNAME_MACHINE}" in
+           amiga) machine=m68k-unknown ;;
+           arm32) machine=arm-unknown ;;
+           atari*) machine=m68k-atari ;;
+           sun3*) machine=m68k-sun ;;
+           mac68k) machine=m68k-apple ;;
+           macppc) machine=powerpc-apple ;;
+           hp3[0-9][05]) machine=m68k-hp ;;
+           ibmrt|romp-ibm) machine=romp-ibm ;;
+           *) machine=${UNAME_MACHINE}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE}" in
+           i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               eval $set_cc_for_build
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       eval $set_cc_for_build
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+       rm -f $dummy.c $dummy
+       fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+         big)    echo mips-unknown-linux-gnu && exit 0 ;;
+         little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+       esac
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev67 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_supported_targets=`cd /; ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       if test "${UNAME_MACHINE}" = "x86pc"; then
+               UNAME_MACHINE=pc
+       fi
+       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..281fc13
--- /dev/null
@@ -0,0 +1,535 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+#ifndef _SUDO_CONFIG_H
+#define _SUDO_CONFIG_H
+
+/* Define if the `syslog' function returns a non-zero int to denote failure.
+   */
+#undef BROKEN_SYSLOG
+
+/* Define if you want the insults from the "classic" version sudo. */
+#undef CLASSIC_INSULTS
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define if you want insults culled from the twisted minds of CSOps. */
+#undef CSOPS_INSULTS
+
+/* Define if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if you want sudo to display "command not allowed" instead of
+   "command not found" when a command cannot be found. */
+#undef DONT_LEAK_PATH_INFO
+
+/* A colon-separated list of pathnames to be used as the editor for visudo. */
+#undef EDITOR
+
+/* Define if you want visudo to honor the EDITOR and VISUAL env variables. */
+#undef ENV_EDITOR
+
+/* If defined, users in this group need not enter a passwd (ie "sudo"). */
+#undef EXEMPTGROUP
+
+/* Define if you want to require fully qualified hosts in sudoers. */
+#undef FQDN
+
+/* Define if you want insults from the "Goon Show". */
+#undef GOONS_INSULTS
+
+/* Define if you want 2001-like insults. */
+#undef HAL_INSULTS
+
+/* Define if you use AFS. */
+#undef HAVE_AFS
+
+/* Define if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define if you use AIX general authentication. */
+#undef HAVE_AUTHENTICATE
+
+/* Define if you have the `bigcrypt' function. */
+#undef HAVE_BIGCRYPT
+
+/* Define if you use BSD authentication. */
+#undef HAVE_BSD_AUTH_H
+
+/* Define if you use OSF DCE. */
+#undef HAVE_DCE
+
+/* Define if you have the <dirent.h> header file, and it defines `DIR'. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the `dispcrypt' function. */
+#undef HAVE_DISPCRYPT
+
+/* Define if you have the `flock' function. */
+#undef HAVE_FLOCK
+
+/* Define if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define if you have the `freeifaddrs' function. */
+#undef HAVE_FREEIFADDRS
+
+/* Define if you have the `fstat' function. */
+#undef HAVE_FSTAT
+
+/* Define if you use the FWTK authsrv daemon. */
+#undef HAVE_FWTK
+
+/* Define if you have the `getauthuid' function. (ULTRIX 4.x shadow passwords)
+   */
+#undef HAVE_GETAUTHUID
+
+/* Define if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the `getdomainname' function. */
+#undef HAVE_GETDOMAINNAME
+
+/* Define if you have the `getifaddrs' function. */
+#undef HAVE_GETIFADDRS
+
+/* Define if you have the `getprpwnam' function. (SecureWare-style shadow
+   passwords) */
+#undef HAVE_GETPRPWNAM
+
+/* Define if you have the `getpwanam' function. (SunOS 4.x shadow passwords)
+   */
+#undef HAVE_GETPWANAM
+
+/* Define if you have the `getspnam' function (SVR4-style shadow passwords) */
+#undef HAVE_GETSPNAM
+
+/* Define if you have the `getspwuid' function. (HP-UX <= 9.X shadow
+   passwords) */
+#undef HAVE_GETSPWUID
+
+/* Define if you have the `initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define if you have the `initprivs' function. */
+#undef HAVE_INITPRIVS
+
+/* Define if you have the `innetgr' function. */
+#undef HAVE_INNETGR
+
+/* Define if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have isblank(3). */
+#undef HAVE_ISBLANK
+
+/* Define if you have the `iscomsec' function. (HP-UX >= 10.x check for shadow
+   enabled) */
+#undef HAVE_ISCOMSEC
+
+/* Define if you have the `issecure' function. (SunOS 4.x check for shadow
+   enabled) */
+#undef HAVE_ISSECURE
+
+/* Define if you use Kerberos IV. */
+#undef HAVE_KERB4
+
+/* Define if you use Kerberos V. */
+#undef HAVE_KERB5
+
+/* Define if you have the `lockf' function. */
+#undef HAVE_LOCKF
+
+/* Define if you have the <login_cap.h> header file. */
+#undef HAVE_LOGIN_CAP_H
+
+/* Define if your compiler supports the "long long" type. */
+#undef HAVE_LONG_LONG
+
+/* Define if you have the `lsearch' function. */
+#undef HAVE_LSEARCH
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the `memchr' function. */
+#undef HAVE_MEMCHR
+
+/* Define if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <netgroup.h> header file. */
+#undef HAVE_NETGROUP_H
+
+/* Define if you use NRL OPIE. */
+#undef HAVE_OPIE
+
+/* Define if you use PAM. */
+#undef HAVE_PAM
+
+/* Define if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define if your struct sockadr has an sa_len field. */
+#undef HAVE_SA_LEN
+
+/* Define if you use SecurID. */
+#undef HAVE_SECURID
+
+/* Define if you have the `setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define if you have the `setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define if you have the `set_auth_parameters' function. */
+#undef HAVE_SET_AUTH_PARAMETERS
+
+/* Define if you use SIA. */
+#undef HAVE_SIA
+
+/* Define if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define if <signal.h> has the sigaction_t typedef. */
+#undef HAVE_SIGACTION_T
+
+/* Define if the system has the type `sig_atomic_t'. */
+#undef HAVE_SIG_ATOMIC_T
+
+/* Define if you use S/Key. */
+#undef HAVE_SKEY
+
+/* Define if your S/Key library has skeyaccess(). */
+#undef HAVE_SKEYACCESS
+
+/* Define if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define if you have the <sys/bsdtypes.h> header file. */
+#undef HAVE_SYS_BSDTYPES_H
+
+/* Define if you have the <sys/dir.h> header file, and it defines `DIR'. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <termios.h> header file and the `tcgetattr'
+   function. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the `tzset' function. */
+#undef HAVE_TZSET
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the `utime' function. */
+#undef HAVE_UTIME
+
+/* Define if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define if you have a POSIX utime() (uses struct utimbuf). */
+#undef HAVE_UTIME_POSIX
+
+/* Define if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define if you have the `wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define if you have the `_innetgr' function. */
+#undef HAVE__INNETGR
+
+/* Define if you want the hostname to be entered into the log file. */
+#undef HOST_IN_LOG
+
+/* Define if you want to ignore '.' and empty $PATH elements */
+#undef IGNORE_DOT_PATH
+
+/* The message given when a bad password is entered. */
+#undef INCORRECT_PASSWORD
+
+/* The syslog facility sudo will use. */
+#undef LOGFAC
+
+/* Define to SLOG_SYSLOG, SLOG_FILE, or SLOG_BOTH. */
+#undef LOGGING
+
+/* Define if sizeof(long) == sizeof(long long). */
+#undef LONG_IS_QUAD
+
+/* Define if you want a two line OTP (S/Key or OPIE) prompt. */
+#undef LONG_OTP_PROMPT
+
+/* The subject of the mail sent by sudo to the MAILTO user/address. */
+#undef MAILSUBJECT
+
+/* The user or email address that sudo mail is sent to. */
+#undef MAILTO
+
+/* The max number of chars per log file line (for line wrapping). */
+#undef MAXLOGFILELEN
+
+/* Define to the max length of a uid_t in string context (excluding the NUL).
+   */
+#undef MAX_UID_T_LEN
+
+/* Define if you don't want sudo to prompt for a password by default. */
+#undef NO_AUTHENTICATION
+
+/* Define if you don't want users to get the lecture the first they user sudo.
+   */
+#undef NO_LECTURE
+
+/* Define to avoid runing the mailer as root. */
+#undef NO_ROOT_MAILER
+
+/* Define if root should not be allowed to use sudo. */
+#undef NO_ROOT_SUDO
+
+/* Define to avoid using POSIX saved ids. */
+#undef NO_SAVED_IDS
+
+/* The default password prompt. */
+#undef PASSPROMPT
+
+/* The passwd prompt timeout (in minutes). */
+#undef PASSWORD_TIMEOUT
+
+/* The syslog priority sudo will use for unsuccessful attempts/errors. */
+#undef PRI_FAILURE
+
+/* The syslog priority sudo will use for successful attempts. */
+#undef PRI_SUCCESS
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* The user sudo should run commands as by default. */
+#undef RUNAS_DEFAULT
+
+/* Define to override the user's path with a builtin one. */
+#undef SECURE_PATH
+
+/* Define to send mail when the user is not not allowed to run a command. */
+#undef SEND_MAIL_WHEN_NOT_OK
+
+/* Define to send mail when the user is not not allowed to run sudo on this
+   host. */
+#undef SEND_MAIL_WHEN_NO_HOST
+
+/* Define to send mail when the user is not in the sudoers file. */
+#undef SEND_MAIL_WHEN_NO_USER
+
+/* Define if you want sudo to start a shell if given no arguments. */
+#undef SHELL_IF_NO_ARGS
+
+/* Define if you want sudo to set /home/millert in shell mode. */
+#undef SHELL_SETS_HOME
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+        STACK_DIRECTION > 0 => grows toward higher addresses
+        STACK_DIRECTION < 0 => grows toward lower addresses
+        STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if the code in interfaces.c does not compile for you. */
+#undef STUB_LOAD_INTERFACES
+
+/* The umask that the root-run prog should use. */
+#undef SUDO_UMASK
+
+/* The number of minutes before sudo asks for a password again. */
+#undef TIMEOUT
+
+/* The number of tries a user gets to enter their password. */
+#undef TRIES_FOR_PASSWORD
+
+/* Define if you wish to use execv() instead of execvp() when running
+   programs. */
+#undef USE_EXECV
+
+/* Define if you want to insult the user for entering an incorrect password.
+   */
+#undef USE_INSULTS
+
+/* Define if you want a different ticket file for each tty. */
+#undef USE_TTY_TICKETS
+
+/* Define to "void" if your compiler supports void pointers, else use "char".
+   */
+#undef VOID
+
+/* Define to avoid using the passwd/shadow file for authentication. */
+#undef WITHOUT_PASSWD
+
+/* Enable non-POSIX extensions on AIX. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Enable non-POSIX extensions on ConvexOS. */
+#ifndef _CONVEX_SOURCE
+# undef _CONVEX_SOURCE
+#endif
+
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE   1
+#endif
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define if your system lacks the dev_t type. */
+#undef dev_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define if your system lacks the ino_t type. */
+#undef ino_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `int' if <signal.h> does not define. */
+#undef sig_atomic_t
+
+/* Define if your system lacks the size_t type. */
+#undef size_t
+
+/* Define if your system lacks the ssize_t type. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+   code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
+
+/*
+ * Emulate a subset of waitpid() if we don't have it.
+ */
+#ifdef HAVE_WAITPID
+# define sudo_waitpid(p, s, o) waitpid(p, s, o)
+#else
+# ifdef HAVE_WAIT3
+#  define sudo_waitpid(p, s, o)        wait3(s, o, NULL)
+# endif
+#endif
+
+/* Solaris doesn't use const qualifiers in PAM. */
+#ifdef sun
+# define PAM_CONST
+#else
+# define PAM_CONST     const
+#endif
+
+#ifdef USE_EXECV
+# define EXEC  execv
+#else
+# define EXEC  execvp
+#endif /* USE_EXECV */
+
+/* New ANSI-style OS defs for HP-UX and ConvexOS. */
+#if defined(hpux) && !defined(__hpux)
+# define __hpux                1
+#endif /* hpux */
+
+#if defined(convex) && !defined(__convex__)
+# define __convex__    1
+#endif /* convex */
+
+/* BSD compatibility on some SVR4 systems. */
+#ifdef __svr4__
+# define BSD_COMP
+#endif /* __svr4__ */
+
+#endif /* _SUDO_CONFIG_H */
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..31600b0
--- /dev/null
@@ -0,0 +1,1379 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-06-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis | -sr2201*)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+               | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+               | pyramid | mn10200 | mn10300 | tron | a29k \
+               | 580 | i960 | h8300 \
+               | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+               | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+               | hppa64 \
+               | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+               | alphaev6[78] \
+               | we32k | ns16k | clipper | i370 | sh | sh[34] \
+               | powerpc | powerpcle \
+               | 1750a | dsp16xx | pdp10 | pdp11 \
+               | mips16 | mips64 | mipsel | mips64el \
+               | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+               | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+               | mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
+               | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+               | v850 | c4x \
+               | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+               | pj | pjl | h8500 | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       # FIXME: clean up the formatting here.
+       vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+             | arm-*  | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+             | xmp-* | ymp-* \
+             | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+             | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+             | hppa2.0n-* | hppa64-* \
+             | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+             | alphaev6[78]-* \
+             | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+             | clipper-* | orion-* \
+             | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+             | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+             | mips16-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-* \
+             | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+             | mipstx39-* | mipstx39el-* | mcore-* \
+             | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+             | [cjt]90-* \
+             | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+             | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+             | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [cjt]90)
+               basic_machine=${basic_machine}-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       sr2201*)
+               basic_machine=harp1e-hitachi
+               os=-hiuxmpp
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       pdp10-*)
+               os=-tops20
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..629bad3
--- /dev/null
+++ b/configure
@@ -0,0 +1,11640 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by Autoconf 2.52 for sudo 1.6.6.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Name of the executable.
+as_me=`echo "$0" |sed 's,.*[\\/],,'`
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+# NLS nuisances.
+$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; }
+$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; }
+$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; }
+$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; }
+$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; }
+$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; }
+$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; }
+$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; }
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; }
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+cross_compiling=no
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Identity of this package.
+PACKAGE_NAME='sudo'
+PACKAGE_TARNAME='sudo'
+PACKAGE_VERSION='1.6.6'
+PACKAGE_STRING='sudo 1.6.6'
+PACKAGE_BUGREPORT=''
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval enable_$ac_feature='$ac_optarg' ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval with_$ac_package='$ac_optarg' ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: should be removed in autoconf 3.0.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # 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 <<EOF
+\`configure' configures sudo 1.6.6 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+EOF
+
+  cat <<EOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+EOF
+
+  cat <<\EOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       build programs to run on HOST [BUILD]
+EOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of sudo 1.6.6:";;
+   esac
+  cat <<\EOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-authentication
+                          Do not require authentication by default
+  --disable-root-mailer   Don't run the mailer as root, run as the user
+  --disable-setreuid      Don't try to use the setreuid() function
+  --disable-saved-ids     Don't try to use POSIX saved ids
+  --disable-shadow        Never use shadow passwords
+  --disable-root-sudo     Don't allow root to run sudo
+  --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
+  --disable-path-info     Print 'command not allowed' not 'command not found'
+  --disable-sia           Never use SIA on Digital UNIX
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-otp-only         deprecated
+  --with-alertmail        deprecated
+  --with-CC               C compiler to use
+  --with-incpath          additional places to look for include files
+  --with-libpath          additional places to look for libraries
+  --with-libraries        additional libraries to link with
+  --with-devel            add developement options
+  --with-efence           link with -lefence for malloc() debugging
+  --with-csops            add CSOps standard options
+  --without-passwd        don't use passwd/shadow file for authentication
+  --with-skey             enable S/Key support
+  --with-opie             enable OPIE support
+  --with-long-otp-prompt  use a two line OTP (skey/opie) prompt
+  --with-SecurID          enable SecurID support
+  --with-fwtk             enable FWTK AuthSRV support
+  --with-kerb4            enable kerberos v4 support
+  --with-kerb5            enable kerberos v5 support
+  --with-authenticate     enable AIX general authentication support
+  --with-pam              enable PAM support
+  --with-AFS              enable AFS support
+  --with-DCE              enable DCE support
+  --with-logincap         enable BSD login class support
+  --with-bsdauth          enable BSD authentication support
+  --without-lecture       don't print lecture for first-time sudoer
+  --with-logging          log via syslog, file, or both
+  --with-logfac           syslog facility to log with (default is "local2")
+  --with-goodpri          syslog priority for commands (def is "notice")
+  --with-badpri           syslog priority for failures (def is "alert")
+  --with-logpath          path to the sudo log file
+  --with-loglen           maximum length of a log file line (default is 80)
+  --with-ignore-dot       ignore '.' in the PATH
+  --without-mail-if-no-user do not send mail if user not in sudoers
+  --with-mail-if-no-host  send mail if user in sudoers but not for this host
+  --with-mail-if-noperms  send mail if user not allowed to run command
+  --with-mailto           who should get sudo mail (default is "root")
+  --with-mailsubject      subject of sudo mail
+  --with-passprompt       default password prompt
+  --with-badpass-message  message the user sees when the password is wrong
+  --with-fqdn             expect fully qualified hosts in sudoers
+  --with-timedir          path to the sudo timestamp dir
+  --with-sendmail=path    set path to sendmail
+  --without-sendmail      do not send mail at all
+  --with-sudoers-mode     mode of sudoers file (defaults to 0440)
+  --with-sudoers-uid      uid that owns sudoers file (defaults to 0)
+  --with-sudoers-gid      gid that owns sudoers file (defaults to 0)
+  --with-umask            umask with which the prog should run (default is 022)
+  --without-umask         Preserves the umask of the user invoking sudo.
+  --with-runas-default    User to run commands as (default is "root")
+  --with-exempt=group     no passwd needed for users in this group
+  --with-editor=path      Default editor for visudo (defaults to vi)
+  --with-env-editor       Use the environment variable EDITOR for visudo
+  --with-passwd-tries     number of tries to enter password (default is 3)
+  --with-timeout          minutes before sudo asks for passwd again (def is 5 minutes)
+  --with-password-timeout passwd prompt timeout in minutes (default is 5 minutes)
+  --with-execv            use execv() instead of execvp()
+  --with-tty-tickets      use a different ticket file for each tty
+  --with-insults          insult the user for entering an incorrect password
+  --with-all-insults      include all the sudo insult sets
+  --with-classic-insults  include the insults from the "classic" sudo
+  --with-csops-insults    include CSOps insults
+  --with-hal-insults      include 2001-like insults
+  --with-goons-insults    include the insults from the "Goon Show"
+  --with-secure-path      override the user's path with a builtin one
+  --without-interfaces    don't try to read the ip addr of ether interfaces
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+EOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_subdir in : $ac_subdirs_all; do test "x$ac_subdir" = x: && continue
+    cd $ac_subdir
+    # A "../" for each directory in /$ac_subdir.
+    ac_dots=`echo $ac_subdir |
+             sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g'`
+
+    case $srcdir in
+    .) # No --srcdir option.  We are building in place.
+      ac_sub_srcdir=$srcdir ;;
+    [\\/]* | ?:[\\/]* ) # Absolute path.
+      ac_sub_srcdir=$srcdir/$ac_subdir ;;
+    *) # Relative path.
+      ac_sub_srcdir=$ac_dots$srcdir/$ac_subdir ;;
+    esac
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_sub_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_sub_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_sub_srcdir/configure; then
+      echo
+      $SHELL $ac_sub_srcdir/configure  --help=recursive
+    elif test -f $ac_sub_srcdir/configure.ac ||
+           test -f $ac_sub_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_subdir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\EOF
+sudo configure 1.6.6
+generated by GNU Autoconf 2.52
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+EOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<EOF
+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.6, which was
+generated by GNU Autoconf 2.52.  Invocation command line was
+
+  $ $0 $@
+
+EOF
+{
+cat <<_ASUNAME
+## ---------- ##
+## Platform.  ##
+## ---------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+PATH = $PATH
+
+_ASUNAME
+} >&5
+
+cat >&5 <<EOF
+## ------------ ##
+## Core tests.  ##
+## ------------ ##
+
+EOF
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell meta-characters.
+ac_configure_args=
+ac_sep=
+for ac_arg
+do
+  case $ac_arg in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"`
+    ac_configure_args="$ac_configure_args$ac_sep\"$ac_arg\""
+    ac_sep=" " ;;
+  *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg"
+     ac_sep=" " ;;
+  esac
+  # Get rid of the leading space.
+done
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  echo >&5
+  echo "## ----------------- ##" >&5
+  echo "## Cache variables.  ##" >&5
+  echo "## ----------------- ##" >&5
+  echo >&5
+  # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} >&5
+  sed "/^$/d" confdefs.h >conftest.log
+  if test -s conftest.log; then
+    echo >&5
+    echo "## ------------ ##" >&5
+    echo "## confdefs.h.  ##" >&5
+    echo "## ------------ ##" >&5
+    echo >&5
+    cat conftest.log >&5
+  fi
+  (echo; echo) >&5
+  test "$ac_signal" != 0 &&
+    echo "$as_me: caught signal $ac_signal" >&5
+  echo "$as_me: exit $exit_status" >&5
+  rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:947: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    cat "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:958: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:966: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:982: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:986: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:992: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:994:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:996:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.  It doesn't matter if
+  # we pass some twice (in addition to the command line arguments).
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"`
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val"
+       ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:1015: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:1017: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)      ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+echo "#! $SHELL" >conftest.sh
+echo  "exit 0"   >>conftest.sh
+chmod +x conftest.sh
+if { (echo "$as_me:1037: PATH=\".;.\"; conftest.sh") >&5
+  (PATH=".;."; conftest.sh) 2>&5
+  ac_status=$?
+  echo "$as_me:1040: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  ac_path_separator=';'
+else
+  ac_path_separator=:
+fi
+PATH_SEPARATOR="$ac_path_separator"
+rm -f conftest.sh
+
+ac_config_headers="$ac_config_headers config.h pathnames.h"
+
+echo "Configuring Sudo version 1.6.6"
+
+timeout=5
+password_timeout=5
+sudo_umask=0022
+passprompt="Password:"
+long_otp_prompt=off
+lecture=on
+logfac=local2
+goodpri=notice
+badpri=alert
+loglen=80
+ignore_dot=off
+mail_no_user=on
+mail_no_host=off
+mail_no_perms=off
+mailto=root
+mailsub='*** SECURITY information for %h ***'
+badpass_message='Sorry, try again.'
+fqdn=off
+runas_default=root
+env_editor=off
+passwd_tries=3
+tty_tickets=off
+insults=off
+PROGS="sudo visudo"
+test -n "$MANTYPE" || MANTYPE="man"
+test -n "$mansrcdir" || mansrcdir="."
+test -n "$SUDOERS_MODE" || SUDOERS_MODE=0440
+test -n "$SUDOERS_UID" || SUDOERS_UID=0
+test -n "$SUDOERS_GID" || SUDOERS_GID=0
+DEV="#"
+
+CHECKSHADOW=true
+CHECKSIA=true
+
+test "$mandir" = '${prefix}/man' && mandir='$(prefix)/man'
+test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
+test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
+test "$sysconfdir" = '${prefix}/etc' && sysconfdir='/etc'
+
+# Check whether --with-otp-only or --without-otp-only was given.
+if test "${with_otp_only+set}" = set; then
+  withval="$with_otp_only"
+  case $with_otp_only in
+    yes)       with_passwd=no
+
+cat >>confdefs.h <<\EOF
+#define WITHOUT_PASSWD 1
+EOF
+
+               { echo "$as_me:1102: WARNING: --with-otp-only option deprecated, treating as --without-passwd" >&5
+echo "$as_me: WARNING: --with-otp-only option deprecated, treating as --without-passwd" >&2;}
+               ;;
+esac
+fi;
+
+# Check whether --with-alertmail or --without-alertmail was given.
+if test "${with_alertmail+set}" = set; then
+  withval="$with_alertmail"
+  case $with_alertmail in
+    *)         with_mailto="$with_alertmail"
+               { echo "$as_me:1113: WARNING: --with-alertmail option deprecated, treating as --mailto" >&5
+echo "$as_me: WARNING: --with-alertmail option deprecated, treating as --mailto" >&2;}
+               ;;
+esac
+fi;
+
+# Check whether --with-CC or --without-CC was given.
+if test "${with_CC+set}" = set; then
+  withval="$with_CC"
+  case $with_CC in
+    yes)       { { echo "$as_me:1123: error: \"must give --with-CC an argument.\"" >&5
+echo "$as_me: error: \"must give --with-CC an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1127: error: \"illegal argument: --without-CC.\"" >&5
+echo "$as_me: error: \"illegal argument: --without-CC.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         CC=$with_CC
+               ;;
+esac
+fi;
+
+# Check whether --with-incpath or --without-incpath was given.
+if test "${with_incpath+set}" = set; then
+  withval="$with_incpath"
+  case $with_incpath in
+    yes)       { { echo "$as_me:1140: error: \"must give --with-incpath an argument.\"" >&5
+echo "$as_me: error: \"must give --with-incpath an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1144: error: \"--without-incpath not supported.\"" >&5
+echo "$as_me: error: \"--without-incpath not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         echo "Adding ${with_incpath} to CPPFLAGS"
+               for i in ${with_incpath}; do
+                   CPPFLAGS="${CPPFLAGS} -I${i}"
+               done
+               ;;
+esac
+fi;
+
+# Check whether --with-libpath or --without-libpath was given.
+if test "${with_libpath+set}" = set; then
+  withval="$with_libpath"
+  case $with_libpath in
+    yes)       { { echo "$as_me:1160: error: \"must give --with-libpath an argument.\"" >&5
+echo "$as_me: error: \"must give --with-libpath an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1164: error: \"--without-libpath not supported.\"" >&5
+echo "$as_me: error: \"--without-libpath not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         echo "Adding ${with_libpath} to LDFLAGS"
+               for i in ${with_libpath}; do
+                   LDFLAGS="${LDFLAGS} -L${i}"
+               done
+               ;;
+esac
+fi;
+
+# Check whether --with-libraries or --without-libraries was given.
+if test "${with_libraries+set}" = set; then
+  withval="$with_libraries"
+  case $with_libraries in
+    yes)       { { echo "$as_me:1180: error: \"must give --with-libraries an argument.\"" >&5
+echo "$as_me: error: \"must give --with-libraries an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1184: error: \"--without-libraries not supported.\"" >&5
+echo "$as_me: error: \"--without-libraries not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         echo "Adding ${with_libraries} to LIBS"
+               for i in ${with_libraries}; do
+                   case $i in
+                       -l*)    ;;
+                       *.a)    ;;
+                       *.o)    ;;
+                       *)      i="-l${i}";;
+                   esac
+                   LIBS="${LIBS} ${i}"
+               done
+               ;;
+esac
+fi;
+
+# Check whether --with-devel or --without-devel was given.
+if test "${with_devel+set}" = set; then
+  withval="$with_devel"
+  case $with_devel in
+    yes)       echo 'Setting up for developement: -Wall, flex, yacc'
+               PROGS="${PROGS} testsudoers"
+               OSDEFS="${OSDEFS} -DSUDO_DEVEL"
+               DEV=""
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-devel: $with_devel"
+               ;;
+esac
+fi;
+
+# Check whether --with-efence or --without-efence was given.
+if test "${with_efence+set}" = set; then
+  withval="$with_efence"
+  case $with_efence in
+    yes)       echo 'Sudo will link with -lefence (Electric Fence)'
+               LIBS="${LIBS} -lefence"
+               if test -f /usr/local/lib/libefence.a; then
+                   LDFLAGS="${LDFLAGS} -L/usr/local/lib"
+               fi
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-efence: $with_efence"
+               ;;
+esac
+fi;
+
+# Check whether --with-csops or --without-csops was given.
+if test "${with_csops+set}" = set; then
+  withval="$with_csops"
+  case $with_csops in
+    yes)       echo 'Adding CSOps standard options'
+               CHECKSIA=false
+               with_ignore_dot=yes
+               insults=on
+               with_classic_insults=yes
+               with_csops_insults=yes
+               with_env_editor=yes
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-csops: $with_csops"
+               ;;
+esac
+fi;
+
+# Check whether --with-passwd or --without-passwd was given.
+if test "${with_passwd+set}" = set; then
+  withval="$with_passwd"
+  case $with_passwd in
+    yes)       ;;
+    no)                cat >>confdefs.h <<\EOF
+#define WITHOUT_PASSWD 1
+EOF
+
+               echo "$as_me:1260: checking whether to use shadow/passwd file authentication" >&5
+echo $ECHO_N "checking whether to use shadow/passwd file authentication... $ECHO_C" >&6
+               echo "$as_me:1262: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         { { echo "$as_me:1265: error: \"Sorry, --with-passwd does not take an argument.\"" >&5
+echo "$as_me: error: \"Sorry, --with-passwd does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-skey or --without-skey was given.
+if test "${with_skey+set}" = set; then
+  withval="$with_skey"
+  case $with_skey in
+    yes)       if test -n "$with_opie"; then
+                   { { echo "$as_me:1277: error: \"cannot use both S/Key and OPIE\"" >&5
+echo "$as_me: error: \"cannot use both S/Key and OPIE\"" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+cat >>confdefs.h <<\EOF
+#define HAVE_SKEY 1
+EOF
+
+               echo "$as_me:1286: checking whether to try S/Key authentication" >&5
+echo $ECHO_N "checking whether to try S/Key authentication... $ECHO_C" >&6
+               echo "$as_me:1288: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               AUTH_OBJS="${AUTH_OBJS} rfc1938.o"
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-skey: $with_skey"
+               ;;
+esac
+fi;
+
+# Check whether --with-opie or --without-opie was given.
+if test "${with_opie+set}" = set; then
+  withval="$with_opie"
+  case $with_opie in
+    yes)       if test -n "$with_skey"; then
+                   { { echo "$as_me:1303: error: \"cannot use both S/Key and OPIE\"" >&5
+echo "$as_me: error: \"cannot use both S/Key and OPIE\"" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+cat >>confdefs.h <<\EOF
+#define HAVE_OPIE 1
+EOF
+
+               echo "$as_me:1312: checking whether to try NRL OPIE authentication" >&5
+echo $ECHO_N "checking whether to try NRL OPIE authentication... $ECHO_C" >&6
+               echo "$as_me:1314: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               AUTH_OBJS="${AUTH_OBJS} rfc1938.o"
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-opie: $with_opie"
+               ;;
+esac
+fi;
+
+# Check whether --with-long-otp-prompt or --without-long-otp-prompt was given.
+if test "${with_long_otp_prompt+set}" = set; then
+  withval="$with_long_otp_prompt"
+  case $with_long_otp_prompt in
+    yes)
+cat >>confdefs.h <<\EOF
+#define LONG_OTP_PROMPT 1
+EOF
+
+               echo "$as_me:1333: checking whether to use a two line prompt for OTP authentication" >&5
+echo $ECHO_N "checking whether to use a two line prompt for OTP authentication... $ECHO_C" >&6
+               echo "$as_me:1335: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               long_otp_prompt=on
+               ;;
+    no)                long_otp_prompt=off
+               ;;
+    *)         { { echo "$as_me:1341: error: \"--with-long-otp-prompt does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-long-otp-prompt does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-SecurID or --without-SecurID was given.
+if test "${with_SecurID+set}" = set; then
+  withval="$with_SecurID"
+  case $with_SecurID in
+    no)                ;;
+    *)
+cat >>confdefs.h <<\EOF
+#define HAVE_SECURID 1
+EOF
+
+               echo "$as_me:1358: checking whether to use SecurID for authentication" >&5
+echo $ECHO_N "checking whether to use SecurID for authentication... $ECHO_C" >&6
+               echo "$as_me:1360: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               with_passwd=no
+               AUTH_OBJS="securid.o"
+               ;;
+esac
+fi;
+
+# Check whether --with-fwtk or --without-fwtk was given.
+if test "${with_fwtk+set}" = set; then
+  withval="$with_fwtk"
+  case $with_fwtk in
+    no)                ;;
+    *)
+cat >>confdefs.h <<\EOF
+#define HAVE_FWTK 1
+EOF
+
+               echo "$as_me:1378: checking whether to use FWTK AuthSRV for authentication" >&5
+echo $ECHO_N "checking whether to use FWTK AuthSRV for authentication... $ECHO_C" >&6
+               echo "$as_me:1380: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               with_passwd=no
+               AUTH_OBJS="fwtk.o"
+               if test "$with_fwtk" != "yes"; then
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${with_fwtk}"
+                   CPPFLAGS="${CPPFLAGS} -I${with_fwtk}"
+                   with_fwtk=yes
+               fi
+               ;;
+esac
+fi;
+
+# Check whether --with-kerb4 or --without-kerb4 was given.
+if test "${with_kerb4+set}" = set; then
+  withval="$with_kerb4"
+  case $with_kerb4 in
+    yes)       echo "$as_me:1397: checking whether to try Kerberos 4 authentication" >&5
+echo $ECHO_N "checking whether to try Kerberos 4 authentication... $ECHO_C" >&6
+               echo "$as_me:1399: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1403: error: \"--with-kerb4 does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-kerb4 does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-kerb5 or --without-kerb5 was given.
+if test "${with_kerb5+set}" = set; then
+  withval="$with_kerb5"
+  case $with_kerb5 in
+    yes)       echo "$as_me:1414: checking whether to try Kerberos 5 authentication" >&5
+echo $ECHO_N "checking whether to try Kerberos 5 authentication... $ECHO_C" >&6
+               echo "$as_me:1416: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1420: error: \"--with-kerb5 does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-kerb5 does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-authenticate or --without-authenticate was given.
+if test "${with_authenticate+set}" = set; then
+  withval="$with_authenticate"
+  case $with_authenticate in
+    yes)
+cat >>confdefs.h <<\EOF
+#define HAVE_AUTHENTICATE 1
+EOF
+
+               echo "$as_me:1436: checking whether to use AIX general authentication" >&5
+echo $ECHO_N "checking whether to use AIX general authentication... $ECHO_C" >&6
+               echo "$as_me:1438: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               with_passwd=no
+               AUTH_OBJS="aix_auth.o"
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1444: error: \"--with-authenticate does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-authenticate does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-pam or --without-pam was given.
+if test "${with_pam+set}" = set; then
+  withval="$with_pam"
+  case $with_pam in
+    yes)
+cat >>confdefs.h <<\EOF
+#define HAVE_PAM 1
+EOF
+
+               echo "$as_me:1460: checking whether to use PAM authentication" >&5
+echo $ECHO_N "checking whether to use PAM authentication... $ECHO_C" >&6
+               echo "$as_me:1462: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               with_passwd=no
+               AUTH_OBJS="pam.o"
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1468: error: \"--with-pam does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-pam does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-AFS or --without-AFS was given.
+if test "${with_AFS+set}" = set; then
+  withval="$with_AFS"
+  case $with_AFS in
+    yes)
+cat >>confdefs.h <<\EOF
+#define HAVE_AFS 1
+EOF
+
+               echo "$as_me:1484: checking whether to try AFS (kerberos) authentication" >&5
+echo $ECHO_N "checking whether to try AFS (kerberos) authentication... $ECHO_C" >&6
+               echo "$as_me:1486: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               AUTH_OBJS="${AUTH_OBJS} afs.o"
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1491: error: \"--with-AFS does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-AFS does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-DCE or --without-DCE was given.
+if test "${with_DCE+set}" = set; then
+  withval="$with_DCE"
+  case $with_DCE in
+    yes)
+cat >>confdefs.h <<\EOF
+#define HAVE_DCE 1
+EOF
+
+               echo "$as_me:1507: checking whether to try DCE (kerberos) authentication" >&5
+echo $ECHO_N "checking whether to try DCE (kerberos) authentication... $ECHO_C" >&6
+               echo "$as_me:1509: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               AUTH_OBJS="${AUTH_OBJS} dce.o"
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1514: error: \"--with-DCE does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-DCE does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-logincap or --without-logincap was given.
+if test "${with_logincap+set}" = set; then
+  withval="$with_logincap"
+  case $with_logincap in
+    yes|no)    ;;
+    *)         { { echo "$as_me:1526: error: \"--with-logincap does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-logincap does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-bsdauth or --without-bsdauth was given.
+if test "${with_bsdauth+set}" = set; then
+  withval="$with_bsdauth"
+  case $with_bsdauth in
+    yes)       with_logincap=yes
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:1540: error: \"--with-bsdauth does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-bsdauth does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+echo "$as_me:1547: checking whether to lecture users the first time they run sudo" >&5
+echo $ECHO_N "checking whether to lecture users the first time they run sudo... $ECHO_C" >&6
+
+# Check whether --with-lecture or --without-lecture was given.
+if test "${with_lecture+set}" = set; then
+  withval="$with_lecture"
+  case $with_lecture in
+    yes|short) lecture=on
+               ;;
+    no|none)   lecture=off
+               ;;
+    *)         { { echo "$as_me:1558: error: \"unknown argument to --with-lecture: $with_lecture\"" >&5
+echo "$as_me: error: \"unknown argument to --with-lecture: $with_lecture\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$lecture" = "on"; then
+    echo "$as_me:1565: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+
+cat >>confdefs.h <<\EOF
+#define NO_LECTURE 1
+EOF
+
+    echo "$as_me:1573: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:1577: checking whether sudo should log via syslog or to a file by default" >&5
+echo $ECHO_N "checking whether sudo should log via syslog or to a file by default... $ECHO_C" >&6
+
+# Check whether --with-logging or --without-logging was given.
+if test "${with_logging+set}" = set; then
+  withval="$with_logging"
+  case $with_logging in
+    yes)       { { echo "$as_me:1584: error: \"must give --with-logging an argument.\"" >&5
+echo "$as_me: error: \"must give --with-logging an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1588: error: \"--without-logging not supported.\"" >&5
+echo "$as_me: error: \"--without-logging not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    syslog)
+cat >>confdefs.h <<\EOF
+#define LOGGING SLOG_SYSLOG
+EOF
+
+               echo "$as_me:1597: result: syslog" >&5
+echo "${ECHO_T}syslog" >&6
+               ;;
+    file)      cat >>confdefs.h <<\EOF
+#define LOGGING SLOG_FILE
+EOF
+
+               echo "$as_me:1604: result: file" >&5
+echo "${ECHO_T}file" >&6
+               ;;
+    both)      cat >>confdefs.h <<\EOF
+#define LOGGING SLOG_BOTH
+EOF
+
+               echo "$as_me:1611: result: both" >&5
+echo "${ECHO_T}both" >&6
+               ;;
+    *)         { { echo "$as_me:1614: error: \"unknown argument to --with-logging: $with_logging\"" >&5
+echo "$as_me: error: \"unknown argument to --with-logging: $with_logging\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+else
+  cat >>confdefs.h <<\EOF
+#define LOGGING SLOG_SYSLOG
+EOF
+ echo "$as_me:1623: result: syslog" >&5
+echo "${ECHO_T}syslog" >&6
+fi;
+
+echo "$as_me:1627: checking which syslog facility sudo should log with" >&5
+echo $ECHO_N "checking which syslog facility sudo should log with... $ECHO_C" >&6
+
+# Check whether --with-logfac or --without-logfac was given.
+if test "${with_logfac+set}" = set; then
+  withval="$with_logfac"
+  case $with_logfac in
+    yes)       { { echo "$as_me:1634: error: \"must give --with-logfac an argument.\"" >&5
+echo "$as_me: error: \"must give --with-logfac an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1638: error: \"--without-logfac not supported.\"" >&5
+echo "$as_me: error: \"--without-logfac not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    authpriv|auth|daemon|user|local0|local1|local2|local3|local4|local5|local6|local7)         logfac=$with_logfac
+               ;;
+    *)         { { echo "$as_me:1644: error: \"$with_logfac is not a supported syslog facility.\"" >&5
+echo "$as_me: error: \"$with_logfac is not a supported syslog facility.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define LOGFAC "$logfac"
+EOF
+
+echo "$as_me:1655: result: $logfac" >&5
+echo "${ECHO_T}$logfac" >&6
+
+echo "$as_me:1658: checking at which syslog priority to log commands" >&5
+echo $ECHO_N "checking at which syslog priority to log commands... $ECHO_C" >&6
+
+# Check whether --with-goodpri or --without-goodpri was given.
+if test "${with_goodpri+set}" = set; then
+  withval="$with_goodpri"
+  case $with_goodpri in
+    yes)       { { echo "$as_me:1665: error: \"must give --with-goodpri an argument.\"" >&5
+echo "$as_me: error: \"must give --with-goodpri an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1669: error: \"--without-goodpri not supported.\"" >&5
+echo "$as_me: error: \"--without-goodpri not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    alert|crit|debug|emerg|err|info|notice|warning)
+               goodpri=$with_goodpri
+               ;;
+    *)         { { echo "$as_me:1676: error: \"$with_goodpri is not a supported syslog priority.\"" >&5
+echo "$as_me: error: \"$with_goodpri is not a supported syslog priority.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define PRI_SUCCESS "$goodpri"
+EOF
+
+echo "$as_me:1687: result: $goodpri" >&5
+echo "${ECHO_T}$goodpri" >&6
+
+echo "$as_me:1690: checking at which syslog priority to log failures" >&5
+echo $ECHO_N "checking at which syslog priority to log failures... $ECHO_C" >&6
+
+# Check whether --with-badpri or --without-badpri was given.
+if test "${with_badpri+set}" = set; then
+  withval="$with_badpri"
+  case $with_badpri in
+    yes)       { { echo "$as_me:1697: error: \"must give --with-badpri an argument.\"" >&5
+echo "$as_me: error: \"must give --with-badpri an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1701: error: \"--without-badpri not supported.\"" >&5
+echo "$as_me: error: \"--without-badpri not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    alert|crit|debug|emerg|err|info|notice|warning)
+               badpri=$with_badpri
+               ;;
+    *)         { { echo "$as_me:1708: error: $with_badpri is not a supported syslog priority." >&5
+echo "$as_me: error: $with_badpri is not a supported syslog priority." >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define PRI_FAILURE "$badpri"
+EOF
+
+echo "$as_me:1719: result: badpri" >&5
+echo "${ECHO_T}badpri" >&6
+
+# Check whether --with-logpath or --without-logpath was given.
+if test "${with_logpath+set}" = set; then
+  withval="$with_logpath"
+  case $with_logpath in
+    yes)       { { echo "$as_me:1726: error: \"must give --with-logpath an argument.\"" >&5
+echo "$as_me: error: \"must give --with-logpath an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1730: error: \"--without-logpath not supported.\"" >&5
+echo "$as_me: error: \"--without-logpath not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+echo "$as_me:1737: checking how long a line in the log file should be" >&5
+echo $ECHO_N "checking how long a line in the log file should be... $ECHO_C" >&6
+
+# Check whether --with-loglen or --without-loglen was given.
+if test "${with_loglen+set}" = set; then
+  withval="$with_loglen"
+  case $with_loglen in
+    yes)       { { echo "$as_me:1744: error: \"must give --with-loglen an argument.\"" >&5
+echo "$as_me: error: \"must give --with-loglen an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1748: error: \"--without-loglen not supported.\"" >&5
+echo "$as_me: error: \"--without-loglen not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    [0-9]*)    loglen=$with_loglen
+               ;;
+    *)         { { echo "$as_me:1754: error: \"you must enter a number, not $with_loglen\"" >&5
+echo "$as_me: error: \"you must enter a number, not $with_loglen\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define MAXLOGFILELEN $loglen
+EOF
+
+echo "$as_me:1765: result: $loglen" >&5
+echo "${ECHO_T}$loglen" >&6
+
+echo "$as_me:1768: checking whether sudo should ignore '.' or '' in \$PATH" >&5
+echo $ECHO_N "checking whether sudo should ignore '.' or '' in \$PATH... $ECHO_C" >&6
+
+# Check whether --with-ignore-dot or --without-ignore-dot was given.
+if test "${with_ignore_dot+set}" = set; then
+  withval="$with_ignore_dot"
+  case $with_ignore_dot in
+    yes)       ignore_dot=on
+               ;;
+    no)                ignore_dot=off
+               ;;
+    *)         { { echo "$as_me:1779: error: \"--with-ignore-dot does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-ignore-dot does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$ignore_dot" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define IGNORE_DOT_PATH 1
+EOF
+
+    echo "$as_me:1791: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:1794: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:1798: checking whether to send mail when a user is not in sudoers" >&5
+echo $ECHO_N "checking whether to send mail when a user is not in sudoers... $ECHO_C" >&6
+
+# Check whether --with-mail-if-no-user or --without-mail-if-no-user was given.
+if test "${with_mail_if_no_user+set}" = set; then
+  withval="$with_mail_if_no_user"
+  case $with_mail_if_no_user in
+    yes)       mail_no_user=on
+               ;;
+    no)                mail_no_user=off
+               ;;
+    *)         { { echo "$as_me:1809: error: \"--with-mail-if-no-user does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-mail-if-no-user does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$mail_no_user" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define SEND_MAIL_WHEN_NO_USER 1
+EOF
+
+    echo "$as_me:1821: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:1824: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:1828: checking whether to send mail when user listed but not for this host" >&5
+echo $ECHO_N "checking whether to send mail when user listed but not for this host... $ECHO_C" >&6
+
+# Check whether --with-mail-if-no-host or --without-mail-if-no-host was given.
+if test "${with_mail_if_no_host+set}" = set; then
+  withval="$with_mail_if_no_host"
+  case $with_mail_if_no_host in
+    yes)       mail_no_host=on
+               ;;
+    no)                mail_no_host=off
+               ;;
+    *)         { { echo "$as_me:1839: error: \"--with-mail-if-no-host does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-mail-if-no-host does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$mail_no_host" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define SEND_MAIL_WHEN_NO_HOST 1
+EOF
+
+    echo "$as_me:1851: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:1854: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:1858: checking whether to send mail when a user tries a disallowed command" >&5
+echo $ECHO_N "checking whether to send mail when a user tries a disallowed command... $ECHO_C" >&6
+
+# Check whether --with-mail-if-noperms or --without-mail-if-noperms was given.
+if test "${with_mail_if_noperms+set}" = set; then
+  withval="$with_mail_if_noperms"
+  case $with_mail_if_noperms in
+    yes)       mail_noperms=on
+               ;;
+    no)                mail_noperms=off
+               ;;
+    *)         { { echo "$as_me:1869: error: \"--with-mail-if-noperms does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-mail-if-noperms does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$mail_noperms" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define SEND_MAIL_WHEN_NOT_OK 1
+EOF
+
+    echo "$as_me:1881: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:1884: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:1888: checking who should get the mail that sudo sends" >&5
+echo $ECHO_N "checking who should get the mail that sudo sends... $ECHO_C" >&6
+
+# Check whether --with-mailto or --without-mailto was given.
+if test "${with_mailto+set}" = set; then
+  withval="$with_mailto"
+  case $with_mailto in
+    yes)       { { echo "$as_me:1895: error: \"must give --with-mailto an argument.\"" >&5
+echo "$as_me: error: \"must give --with-mailto an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:1899: error: \"--without-mailto not supported.\"" >&5
+echo "$as_me: error: \"--without-mailto not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         mailto=$with_mailto
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define MAILTO "$mailto"
+EOF
+
+echo "$as_me:1912: result: $mailto" >&5
+echo "${ECHO_T}$mailto" >&6
+
+# Check whether --with-mailsubject or --without-mailsubject was given.
+if test "${with_mailsubject+set}" = set; then
+  withval="$with_mailsubject"
+  case $with_mailsubject in
+    yes)       { { echo "$as_me:1919: error: \"must give --with-mailsubject an argument.\"" >&5
+echo "$as_me: error: \"must give --with-mailsubject an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                echo "Sorry, --without-mailsubject not supported."
+               ;;
+    *)         mailsub="$with_mailsubject"
+               echo "$as_me:1926: checking sudo mail subject" >&5
+echo $ECHO_N "checking sudo mail subject... $ECHO_C" >&6
+               echo "$as_me:1928: result: Using alert mail subject: $mailsub" >&5
+echo "${ECHO_T}Using alert mail subject: $mailsub" >&6
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define MAILSUBJECT "$mailsub"
+EOF
+
+echo "$as_me:1938: checking for bad password prompt" >&5
+echo $ECHO_N "checking for bad password prompt... $ECHO_C" >&6
+
+# Check whether --with-passprompt or --without-passprompt was given.
+if test "${with_passprompt+set}" = set; then
+  withval="$with_passprompt"
+  case $with_passprompt in
+    yes)       { { echo "$as_me:1945: error: \"must give --with-passprompt an argument.\"" >&5
+echo "$as_me: error: \"must give --with-passprompt an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                echo "Sorry, --without-passprompt not supported."
+               ;;
+    *)         passprompt="$with_passprompt"
+esac
+fi;
+echo "$as_me:1954: result: $passprompt" >&5
+echo "${ECHO_T}$passprompt" >&6
+
+cat >>confdefs.h <<EOF
+#define PASSPROMPT "$passprompt"
+EOF
+
+echo "$as_me:1961: checking for bad password message" >&5
+echo $ECHO_N "checking for bad password message... $ECHO_C" >&6
+
+# Check whether --with-badpass-message or --without-badpass-message was given.
+if test "${with_badpass_message+set}" = set; then
+  withval="$with_badpass_message"
+  case $with_badpass_message in
+    yes)       { { echo "$as_me:1968: error: \"Must give --with-badpass-message an argument.\"" >&5
+echo "$as_me: error: \"Must give --with-badpass-message an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                echo "Sorry, --without-badpass-message not supported."
+               ;;
+    *)         badpass_message="$with_badpass_message"
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define INCORRECT_PASSWORD "$badpass_message"
+EOF
+
+echo "$as_me:1983: result: $badpass_message" >&5
+echo "${ECHO_T}$badpass_message" >&6
+
+echo "$as_me:1986: checking whether to expect fully qualified hosts in sudoers" >&5
+echo $ECHO_N "checking whether to expect fully qualified hosts in sudoers... $ECHO_C" >&6
+
+# Check whether --with-fqdn or --without-fqdn was given.
+if test "${with_fqdn+set}" = set; then
+  withval="$with_fqdn"
+  case $with_fqdn in
+    yes)       fqdn=on
+               ;;
+    no)                fqdn=off
+               ;;
+    *)         { { echo "$as_me:1997: error: \"--with-fqdn does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-fqdn does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$fqdn" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define FQDN 1
+EOF
+
+    echo "$as_me:2009: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:2012: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Check whether --with-timedir or --without-timedir was given.
+if test "${with_timedir+set}" = set; then
+  withval="$with_timedir"
+  case $with_timedir in
+    yes)       { { echo "$as_me:2020: error: \"must give --with-timedir an argument.\"" >&5
+echo "$as_me: error: \"must give --with-timedir an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2024: error: \"--without-timedir not supported.\"" >&5
+echo "$as_me: error: \"--without-timedir not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-sendmail or --without-sendmail was given.
+if test "${with_sendmail+set}" = set; then
+  withval="$with_sendmail"
+  case $with_sendmail in
+    yes)       with_sendmail=""
+               ;;
+    no)                ;;
+    *)         cat >>confdefs.h <<EOF
+#define _PATH_SUDO_SENDMAIL "$with_sendmail"
+EOF
+
+               ;;
+esac
+fi;
+
+# Check whether --with-sudoers-mode or --without-sudoers-mode was given.
+if test "${with_sudoers_mode+set}" = set; then
+  withval="$with_sudoers_mode"
+  case $with_sudoers_mode in
+    yes)       { { echo "$as_me:2050: error: \"must give --with-sudoers-mode an argument.\"" >&5
+echo "$as_me: error: \"must give --with-sudoers-mode an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2054: error: \"--without-sudoers-mode not supported.\"" >&5
+echo "$as_me: error: \"--without-sudoers-mode not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    [1-9]*)    SUDOERS_MODE=0${with_sudoers_mode}
+               ;;
+    0*)                SUDOERS_MODE=$with_sudoers_mode
+               ;;
+    *)         { { echo "$as_me:2062: error: \"you must use a numeric uid, not a name.\"" >&5
+echo "$as_me: error: \"you must use a numeric uid, not a name.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-sudoers-uid or --without-sudoers-uid was given.
+if test "${with_sudoers_uid+set}" = set; then
+  withval="$with_sudoers_uid"
+  case $with_sudoers_uid in
+    yes)       { { echo "$as_me:2073: error: \"must give --with-sudoers-uid an argument.\"" >&5
+echo "$as_me: error: \"must give --with-sudoers-uid an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2077: error: \"--without-sudoers-uid not supported.\"" >&5
+echo "$as_me: error: \"--without-sudoers-uid not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    [0-9]*)    SUDOERS_UID=$with_sudoers_uid
+               ;;
+    *)         { { echo "$as_me:2083: error: \"you must use a numeric uid, not a name.\"" >&5
+echo "$as_me: error: \"you must use a numeric uid, not a name.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-sudoers-gid or --without-sudoers-gid was given.
+if test "${with_sudoers_gid+set}" = set; then
+  withval="$with_sudoers_gid"
+  case $with_sudoers_gid in
+    yes)       { { echo "$as_me:2094: error: \"must give --with-sudoers-gid an argument.\"" >&5
+echo "$as_me: error: \"must give --with-sudoers-gid an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2098: error: \"--without-sudoers-gid not supported.\"" >&5
+echo "$as_me: error: \"--without-sudoers-gid not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    [0-9]*)    SUDOERS_GID=$with_sudoers_gid
+               ;;
+    *)         { { echo "$as_me:2104: error: \"you must use a numeric gid, not a name.\"" >&5
+echo "$as_me: error: \"you must use a numeric gid, not a name.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+echo "$as_me:2111: checking for umask programs should be run with" >&5
+echo $ECHO_N "checking for umask programs should be run with... $ECHO_C" >&6
+
+# Check whether --with-umask or --without-umask was given.
+if test "${with_umask+set}" = set; then
+  withval="$with_umask"
+  case $with_umask in
+    yes)       { { echo "$as_me:2118: error: \"must give --with-umask an argument.\"" >&5
+echo "$as_me: error: \"must give --with-umask an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                sudo_umask=0777
+               ;;
+    [0-9]*)    sudo_umask=$with_umask
+               ;;
+    *)         { { echo "$as_me:2126: error: \"you must enter a numeric mask.\"" >&5
+echo "$as_me: error: \"you must enter a numeric mask.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define SUDO_UMASK $sudo_umask
+EOF
+
+if test "$sudo_umask" = "0777"; then
+    echo "$as_me:2138: result: user" >&5
+echo "${ECHO_T}user" >&6
+else
+    echo "$as_me:2141: result: $sudo_umask" >&5
+echo "${ECHO_T}$sudo_umask" >&6
+fi
+
+echo "$as_me:2145: checking for default user to run commands as" >&5
+echo $ECHO_N "checking for default user to run commands as... $ECHO_C" >&6
+
+# Check whether --with-runas-default or --without-runas-default was given.
+if test "${with_runas_default+set}" = set; then
+  withval="$with_runas_default"
+  case $with_runas_default in
+    yes)       { { echo "$as_me:2152: error: \"must give --with-runas-default an argument.\"" >&5
+echo "$as_me: error: \"must give --with-runas-default an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2156: error: \"--without-runas-default not supported.\"" >&5
+echo "$as_me: error: \"--without-runas-default not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)         runas_default="$with_runas_default"
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define RUNAS_DEFAULT "$runas_default"
+EOF
+
+echo "$as_me:2169: result: $runas_default" >&5
+echo "${ECHO_T}$runas_default" >&6
+
+# Check whether --with-exempt or --without-exempt was given.
+if test "${with_exempt+set}" = set; then
+  withval="$with_exempt"
+  case $with_exempt in
+    yes)       { { echo "$as_me:2176: error: \"must give --with-exempt an argument.\"" >&5
+echo "$as_me: error: \"must give --with-exempt an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2180: error: \"--without-exempt not supported.\"" >&5
+echo "$as_me: error: \"--without-exempt not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)
+cat >>confdefs.h <<EOF
+#define EXEMPTGROUP "$with_exempt"
+EOF
+
+               echo "$as_me:2189: checking for group to be exempt from password" >&5
+echo $ECHO_N "checking for group to be exempt from password... $ECHO_C" >&6
+               echo "$as_me:2191: result: $with_exempt" >&5
+echo "${ECHO_T}$with_exempt" >&6
+               ;;
+esac
+fi;
+
+echo "$as_me:2197: checking for editor that visudo should use" >&5
+echo $ECHO_N "checking for editor that visudo should use... $ECHO_C" >&6
+
+# Check whether --with-editor or --without-editor was given.
+if test "${with_editor+set}" = set; then
+  withval="$with_editor"
+  case $with_editor in
+    yes)       { { echo "$as_me:2204: error: \"must give --with-editor an argument.\"" >&5
+echo "$as_me: error: \"must give --with-editor an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    no)                { { echo "$as_me:2208: error: \"--without-editor not supported.\"" >&5
+echo "$as_me: error: \"--without-editor not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    *)
+cat >>confdefs.h <<EOF
+#define EDITOR "$with_editor"
+EOF
+
+               echo "$as_me:2217: result: $with_editor" >&5
+echo "${ECHO_T}$with_editor" >&6
+               ;;
+esac
+else
+  cat >>confdefs.h <<\EOF
+#define EDITOR _PATH_VI
+EOF
+ echo "$as_me:2225: result: vi" >&5
+echo "${ECHO_T}vi" >&6
+fi;
+
+echo "$as_me:2229: checking whether to obey EDITOR and VISUAL environment variables" >&5
+echo $ECHO_N "checking whether to obey EDITOR and VISUAL environment variables... $ECHO_C" >&6
+
+# Check whether --with-env-editor or --without-env-editor was given.
+if test "${with_env_editor+set}" = set; then
+  withval="$with_env_editor"
+  case $with_env_editor in
+    yes)       env_editor=on
+               ;;
+    no)                env_editor=off
+               ;;
+    *)         { { echo "$as_me:2240: error: \"--with-env-editor does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-env-editor does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$env_editor" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define ENV_EDITOR 1
+EOF
+
+    echo "$as_me:2252: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:2255: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:2259: checking number of tries a user gets to enter their password" >&5
+echo $ECHO_N "checking number of tries a user gets to enter their password... $ECHO_C" >&6
+
+# Check whether --with-passwd-tries or --without-passwd-tries was given.
+if test "${with_passwd_tries+set}" = set; then
+  withval="$with_passwd_tries"
+  case $with_passwd_tries in
+    yes)       ;;
+    no)                { { echo "$as_me:2267: error: \"--without-editor not supported.\"" >&5
+echo "$as_me: error: \"--without-editor not supported.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+    [1-9]*)    passwd_tries=$with_passwd_tries
+               ;;
+    *)         { { echo "$as_me:2273: error: \"you must enter the numer of tries, > 0\"" >&5
+echo "$as_me: error: \"you must enter the numer of tries, > 0\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define TRIES_FOR_PASSWORD $passwd_tries
+EOF
+
+echo "$as_me:2284: result: $passwd_tries" >&5
+echo "${ECHO_T}$passwd_tries" >&6
+
+echo "$as_me:2287: checking time in minutes after which sudo will ask for a password again" >&5
+echo $ECHO_N "checking time in minutes after which sudo will ask for a password again... $ECHO_C" >&6
+
+# Check whether --with-timeout or --without-timeout was given.
+if test "${with_timeout+set}" = set; then
+  withval="$with_timeout"
+  echo $with_timeout; case $with_timeout in
+    yes)       ;;
+    no)                timeout=0
+               ;;
+    [0-9]*)    timeout=$with_timeout
+               ;;
+    *)         { { echo "$as_me:2299: error: \"you must enter the numer of minutes.\"" >&5
+echo "$as_me: error: \"you must enter the numer of minutes.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define TIMEOUT $timeout
+EOF
+
+echo "$as_me:2310: result: $timeout" >&5
+echo "${ECHO_T}$timeout" >&6
+
+echo "$as_me:2313: checking time in minutes after the password prompt will time out" >&5
+echo $ECHO_N "checking time in minutes after the password prompt will time out... $ECHO_C" >&6
+
+# Check whether --with-password-timeout or --without-password-timeout was given.
+if test "${with_password_timeout+set}" = set; then
+  withval="$with_password_timeout"
+  case $with_password_timeout in
+    yes)       ;;
+    no)                password_timeout=0
+               ;;
+    [0-9]*)    password_timeout=$with_password_timeout
+               ;;
+    *)         { { echo "$as_me:2325: error: \"you must enter the numer of minutes.\"" >&5
+echo "$as_me: error: \"you must enter the numer of minutes.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+cat >>confdefs.h <<EOF
+#define PASSWORD_TIMEOUT $password_timeout
+EOF
+
+echo "$as_me:2336: result: $password_timeout" >&5
+echo "${ECHO_T}$password_timeout" >&6
+
+# Check whether --with-execv or --without-execv was given.
+if test "${with_execv+set}" = set; then
+  withval="$with_execv"
+  case $with_execv in
+    yes)       echo "$as_me:2343: checking whether to use execvp or execv" >&5
+echo $ECHO_N "checking whether to use execvp or execv... $ECHO_C" >&6
+               echo "$as_me:2345: result: execv" >&5
+echo "${ECHO_T}execv" >&6
+
+cat >>confdefs.h <<\EOF
+#define USE_EXECV 1
+EOF
+
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2354: error: \"--with-execv does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-execv does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+echo "$as_me:2361: checking whether to use per-tty ticket files" >&5
+echo $ECHO_N "checking whether to use per-tty ticket files... $ECHO_C" >&6
+
+# Check whether --with-tty-tickets or --without-tty-tickets was given.
+if test "${with_tty_tickets+set}" = set; then
+  withval="$with_tty_tickets"
+  case $with_tty_tickets in
+    yes)       tty_tickets=on
+               ;;
+    no)                tty_tickets=off
+               ;;
+    *)         { { echo "$as_me:2372: error: \"--with-tty-tickets does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-tty-tickets does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$tty_tickets" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define USE_TTY_TICKETS 1
+EOF
+
+    echo "$as_me:2384: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:2387: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+echo "$as_me:2391: checking whether to include insults" >&5
+echo $ECHO_N "checking whether to include insults... $ECHO_C" >&6
+
+# Check whether --with-insults or --without-insults was given.
+if test "${with_insults+set}" = set; then
+  withval="$with_insults"
+  case $with_insults in
+    yes)       insults=on
+               with_classic_insults=yes
+               with_csops_insults=yes
+               ;;
+    no)                insults=off
+               ;;
+    *)         { { echo "$as_me:2404: error: \"--with-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+if test "$insults" = "on"; then
+
+cat >>confdefs.h <<\EOF
+#define USE_INSULTS 1
+EOF
+
+    echo "$as_me:2416: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+    echo "$as_me:2419: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Check whether --with-all-insults or --without-all-insults was given.
+if test "${with_all_insults+set}" = set; then
+  withval="$with_all_insults"
+  case $with_all_insults in
+    yes)       with_classic_insults=yes
+               with_csops_insults=yes
+               with_hal_insults=yes
+               with_goons_insults=yes
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2433: error: \"--with-all-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-all-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-classic-insults or --without-classic-insults was given.
+if test "${with_classic_insults+set}" = set; then
+  withval="$with_classic_insults"
+  case $with_classic_insults in
+    yes)
+cat >>confdefs.h <<\EOF
+#define CLASSIC_INSULTS 1
+EOF
+
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2451: error: \"--with-classic-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-classic-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-csops-insults or --without-csops-insults was given.
+if test "${with_csops_insults+set}" = set; then
+  withval="$with_csops_insults"
+  case $with_csops_insults in
+    yes)
+cat >>confdefs.h <<\EOF
+#define CSOPS_INSULTS 1
+EOF
+
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2469: error: \"--with-csops-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-csops-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-hal-insults or --without-hal-insults was given.
+if test "${with_hal_insults+set}" = set; then
+  withval="$with_hal_insults"
+  case $with_hal_insults in
+    yes)
+cat >>confdefs.h <<\EOF
+#define HAL_INSULTS 1
+EOF
+
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2487: error: \"--with-hal-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-hal-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+# Check whether --with-goons-insults or --without-goons-insults was given.
+if test "${with_goons_insults+set}" = set; then
+  withval="$with_goons_insults"
+  case $with_goons_insults in
+    yes)
+cat >>confdefs.h <<\EOF
+#define GOONS_INSULTS 1
+EOF
+
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:2505: error: \"--with-goons-insults does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-goons-insults does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi;
+
+if test "$insults" = "on"; then
+    echo "$as_me:2513: checking which insult sets to include" >&5
+echo $ECHO_N "checking which insult sets to include... $ECHO_C" >&6
+    i=""
+    test "$with_goons_insults" = "yes" && i="goons ${i}"
+    test "$with_hal_insults" = "yes" && i="hal ${i}"
+    test "$with_csops_insults" = "yes" && i="csops ${i}"
+    test "$with_classic_insults" = "yes" && i="classic ${i}"
+    echo "$as_me:2520: result: $i" >&5
+echo "${ECHO_T}$i" >&6
+fi
+
+echo "$as_me:2524: checking whether to override the user's path" >&5
+echo $ECHO_N "checking whether to override the user's path... $ECHO_C" >&6
+
+# Check whether --with-secure-path or --without-secure-path was given.
+if test "${with_secure_path+set}" = set; then
+  withval="$with_secure_path"
+  case $with_secure_path in
+    yes)
+cat >>confdefs.h <<EOF
+#define SECURE_PATH "/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc"
+EOF
+
+               echo "$as_me:2536: result: :/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" >&5
+echo "${ECHO_T}:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" >&6
+               ;;
+    no)                echo "$as_me:2539: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         cat >>confdefs.h <<EOF
+#define SECURE_PATH "$with_secure_path"
+EOF
+
+               echo "$as_me:2546: result: $with_secure_path" >&5
+echo "${ECHO_T}$with_secure_path" >&6
+               ;;
+esac
+else
+  echo "$as_me:2551: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2555: checking whether to get ip addresses from the network interfaces" >&5
+echo $ECHO_N "checking whether to get ip addresses from the network interfaces... $ECHO_C" >&6
+
+# Check whether --with-interfaces or --without-interfaces was given.
+if test "${with_interfaces+set}" = set; then
+  withval="$with_interfaces"
+  case $with_interfaces in
+    yes)       echo "$as_me:2562: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               ;;
+    no)
+cat >>confdefs.h <<\EOF
+#define STUB_LOAD_INTERFACES 1
+EOF
+
+               echo "$as_me:2570: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         { { echo "$as_me:2573: error: \"--with-interfaces does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-interfaces does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+else
+  echo "$as_me:2579: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi;
+
+echo "$as_me:2583: 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 --enable-authentication or --disable-authentication was given.
+if test "${enable_authentication+set}" = set; then
+  enableval="$enable_authentication"
+   case "$enableval" in
+    yes)       echo "$as_me:2589: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               ;;
+    no)                echo "$as_me:2592: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+cat >>confdefs.h <<\EOF
+#define NO_AUTHENTICATION 1
+EOF
+
+               ;;
+    *)         echo "$as_me:2600: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-authentication: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2607: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi;
+
+echo "$as_me:2611: checking whether to disable running the mailer as root" >&5
+echo $ECHO_N "checking whether to disable running the mailer as root... $ECHO_C" >&6
+# Check whether --enable-root-mailer or --disable-root-mailer was given.
+if test "${enable_root_mailer+set}" = set; then
+  enableval="$enable_root_mailer"
+   case "$enableval" in
+    yes)       echo "$as_me:2617: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    no)                echo "$as_me:2620: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define NO_ROOT_MAILER 1
+EOF
+
+               ;;
+    *)         echo "$as_me:2628: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-root-mailer: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2635: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+# Check whether --enable-setreuid or --disable-setreuid was given.
+if test "${enable_setreuid+set}" = set; then
+  enableval="$enable_setreuid"
+   case "$enableval" in
+    no)                BROKEN_SETREUID=1
+               ;;
+    *)         ;;
+  esac
+
+fi;
+
+echo "$as_me:2650: checking whether to disable use of POSIX saved ids" >&5
+echo $ECHO_N "checking whether to disable use of POSIX saved ids... $ECHO_C" >&6
+# Check whether --enable-saved-ids or --disable-saved-ids was given.
+if test "${enable_saved_ids+set}" = set; then
+  enableval="$enable_saved_ids"
+   case "$enableval" in
+    yes)       echo "$as_me:2656: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    no)                echo "$as_me:2659: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define NO_SAVED_IDS 1
+EOF
+
+               ;;
+    *)         echo "$as_me:2667: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-saved-ids: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2674: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2678: checking whether to disable shadow password support" >&5
+echo $ECHO_N "checking whether to disable shadow password support... $ECHO_C" >&6
+# Check whether --enable-shadow or --disable-shadow was given.
+if test "${enable_shadow+set}" = set; then
+  enableval="$enable_shadow"
+   case "$enableval" in
+    yes)       echo "$as_me:2684: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    no)                echo "$as_me:2687: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               CHECKSHADOW="false"
+               ;;
+    *)         echo "$as_me:2691: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-shadow: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2698: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2702: checking whether root should be allowed to use sudo" >&5
+echo $ECHO_N "checking whether root should be allowed to use sudo... $ECHO_C" >&6
+# Check whether --enable-root-sudo or --disable-root-sudo was given.
+if test "${enable_root_sudo+set}" = set; then
+  enableval="$enable_root_sudo"
+   case "$enableval" in
+    yes)       echo "$as_me:2708: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               ;;
+    no)
+cat >>confdefs.h <<\EOF
+#define NO_ROOT_SUDO 1
+EOF
+
+               echo "$as_me:2716: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         { { echo "$as_me:2719: error: \"--enable-root-sudo does not take an argument.\"" >&5
+echo "$as_me: error: \"--enable-root-sudo does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+  esac
+
+else
+  echo "$as_me:2726: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi;
+
+echo "$as_me:2730: checking whether to log the hostname in the log file" >&5
+echo $ECHO_N "checking whether to log the hostname in the log file... $ECHO_C" >&6
+# Check whether --enable-log-host or --disable-log-host was given.
+if test "${enable_log_host+set}" = set; then
+  enableval="$enable_log_host"
+   case "$enableval" in
+    yes)       echo "$as_me:2736: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define HOST_IN_LOG 1
+EOF
+
+               ;;
+    no)                echo "$as_me:2744: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         echo "$as_me:2747: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-log-host: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2754: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2758: checking whether to invoke a shell if sudo is given no arguments" >&5
+echo $ECHO_N "checking whether to invoke a shell if sudo is given no arguments... $ECHO_C" >&6
+# Check whether --enable-noargs-shell or --disable-noargs-shell was given.
+if test "${enable_noargs_shell+set}" = set; then
+  enableval="$enable_noargs_shell"
+   case "$enableval" in
+    yes)       echo "$as_me:2764: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define SHELL_IF_NO_ARGS 1
+EOF
+
+               ;;
+    no)                echo "$as_me:2772: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         echo "$as_me:2775: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-noargs-shell: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2782: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2786: checking whether to set \$HOME to target user in shell mode" >&5
+echo $ECHO_N "checking whether to set \$HOME to target user in shell mode... $ECHO_C" >&6
+# Check whether --enable-shell-sets-home or --disable-shell-sets-home was given.
+if test "${enable_shell_sets_home+set}" = set; then
+  enableval="$enable_shell_sets_home"
+   case "$enableval" in
+    yes)       echo "$as_me:2792: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define SHELL_SETS_HOME 1
+EOF
+
+               ;;
+    no)                echo "$as_me:2800: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    *)         echo "$as_me:2803: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-shell-sets-home: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2810: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:2814: checking whether to disable 'command not found' messages" >&5
+echo $ECHO_N "checking whether to disable 'command not found' messages... $ECHO_C" >&6
+# Check whether --enable-path_info or --disable-path_info was given.
+if test "${enable_path_info+set}" = set; then
+  enableval="$enable_path_info"
+   case "$enableval" in
+    yes)       echo "$as_me:2820: result: no" >&5
+echo "${ECHO_T}no" >&6
+               ;;
+    no)                echo "$as_me:2823: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\EOF
+#define DONT_LEAK_PATH_INFO 1
+EOF
+
+               ;;
+    *)         echo "$as_me:2831: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "Ignoring unknown argument to --enable-path-info: $enableval"
+               ;;
+  esac
+
+else
+  echo "$as_me:2838: result: no" >&5
+echo "${ECHO_T}no" >&6
+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:2844: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_EGREPPROG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$EGREPPROG"; then
+  ac_cv_prog_EGREPPROG="$EGREPPROG" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_EGREPPROG="egrep"
+echo "$as_me:2859: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+EGREPPROG=$ac_cv_prog_EGREPPROG
+if test -n "$EGREPPROG"; then
+  echo "$as_me:2867: result: $EGREPPROG" >&5
+echo "${ECHO_T}$EGREPPROG" >&6
+else
+  echo "$as_me:2870: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$EGREPPROG"; then
+    echo "Sorry, configure requires egrep to run."
+    exit
+fi
+
+if test "$with_devel" != "yes"; then
+    ac_cv_prog_cc_g=no
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:2891: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_CC="${ac_tool_prefix}gcc"
+echo "$as_me:2906: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:2914: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:2917: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:2926: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_ac_ct_CC="gcc"
+echo "$as_me:2941: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:2949: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:2952: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:2965: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_CC="${ac_tool_prefix}cc"
+echo "$as_me:2980: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:2988: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:2991: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:3000: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_ac_ct_CC="cc"
+echo "$as_me:3015: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:3023: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:3026: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:3039: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+  ac_prog_rejected=yes
+  continue
+fi
+ac_cv_prog_CC="cc"
+echo "$as_me:3059: found $ac_dir/$ac_word" >&5
+break
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" ${1+"$@"}
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:3081: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:3084: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:3095: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+echo "$as_me:3110: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:3118: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:3121: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:3134: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_ac_ct_CC="$ac_prog"
+echo "$as_me:3149: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:3157: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:3160: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+test -z "$CC" && { { echo "$as_me:3172: error: no acceptable cc found in \$PATH" >&5
+echo "$as_me: error: no acceptable cc found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:3177:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:3180: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:3183: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:3185: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:3188: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:3190: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:3193: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line 3197 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:3213: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:3216: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:3219: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+for ac_file in `ls a.exe conftest.exe 2>/dev/null;
+                ls a.out conftest 2>/dev/null;
+                ls a.* conftest.* 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
+    a.out ) # We found the default executable, but exeext='' is most
+            # certainly right.
+            break;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          # FIXME: I believe we export ac_cv_exeext for Libtool --akim.
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+{ { echo "$as_me:3242: error: C compiler cannot create executables" >&5
+echo "$as_me: error: C compiler cannot create executables" >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:3248: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:3253: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:3259: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3262: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:3269: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:3277: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:3284: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:3286: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:3289: checking for executable suffix" >&5
+echo $ECHO_N "checking for executable suffix... $ECHO_C" >&6
+if { (eval echo "$as_me:3291: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:3294: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:3310: error: cannot compute EXEEXT: cannot compile and link" >&5
+echo "$as_me: error: cannot compute EXEEXT: cannot compile and link" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:3316: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:3322: checking for object suffix" >&5
+echo $ECHO_N "checking for object suffix... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3328 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:3340: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3343: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+{ { echo "$as_me:3355: error: cannot compute OBJEXT: cannot compile" >&5
+echo "$as_me: error: cannot compute OBJEXT: cannot compile" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:3362: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:3366: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3372 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3387: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3390: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3393: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3396: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:3408: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:3414: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3420 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3432: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3435: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3438: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3441: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:3451: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3478: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3481: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3484: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3487: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3499 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3512: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3515: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3518: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3521: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3531 "configure"
+#include "confdefs.h"
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3543: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3546: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3549: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3552: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+echo "$as_me:3579: checking for POSIXized ISC" >&5
+echo $ECHO_N "checking for POSIXized ISC... $ECHO_C" >&6
+if test -d /etc/conf/kconfig.d &&
+   grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+  echo "$as_me:3584: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  ISC=yes # If later tests want to check for ISC.
+
+cat >>confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+  if test "$GCC" = yes; then
+    CC="$CC -posix"
+  else
+    CC="$CC -Xp"
+  fi
+else
+  echo "$as_me:3598: result: no" >&5
+echo "${ECHO_T}no" >&6
+  ISC=
+fi
+
+ac_cv_prog_cc_cross="no"
+cross_compiling="no"
+
+echo "$as_me:3606: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line 3614 "configure"
+#include "confdefs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:3663: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:3666: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:3669: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:3672: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:3689: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:3692: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+ac_cv_prog_cc_cross="no"
+cross_compiling="no"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:3704: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3725 "configure"
+#include "confdefs.h"
+#include <assert.h>
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:3730: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:3736: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3759 "configure"
+#include "confdefs.h"
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:3763: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:3769: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:3806: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3816 "configure"
+#include "confdefs.h"
+#include <assert.h>
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:3821: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:3827: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 3850 "configure"
+#include "confdefs.h"
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:3854: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:3860: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:3888: error: C preprocessor \"$CPP\" fails sanity check" >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test "$with_devel" = "yes" -a -n "$GCC"; then
+    CFLAGS="${CFLAGS} -Wall"
+fi
+
+# Extract the first word of "uname", so it can be a program name with args.
+set dummy uname; ac_word=$2
+echo "$as_me:3905: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_UNAMEPROG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$UNAMEPROG"; then
+  ac_cv_prog_UNAMEPROG="$UNAMEPROG" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_UNAMEPROG="uname"
+echo "$as_me:3920: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+UNAMEPROG=$ac_cv_prog_UNAMEPROG
+if test -n "$UNAMEPROG"; then
+  echo "$as_me:3928: result: $UNAMEPROG" >&5
+echo "${ECHO_T}$UNAMEPROG" >&6
+else
+  echo "$as_me:3931: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "tr", so it can be a program name with args.
+set dummy tr; ac_word=$2
+echo "$as_me:3937: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_TRPROG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$TRPROG"; then
+  ac_cv_prog_TRPROG="$TRPROG" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_TRPROG="tr"
+echo "$as_me:3952: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+TRPROG=$ac_cv_prog_TRPROG
+if test -n "$TRPROG"; then
+  echo "$as_me:3960: result: $TRPROG" >&5
+echo "${ECHO_T}$TRPROG" >&6
+else
+  echo "$as_me:3963: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "sed", so it can be a program name with args.
+set dummy sed; ac_word=$2
+echo "$as_me:3969: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_SEDPROG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$SEDPROG"; then
+  ac_cv_prog_SEDPROG="$SEDPROG" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_SEDPROG="sed"
+echo "$as_me:3984: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+SEDPROG=$ac_cv_prog_SEDPROG
+if test -n "$SEDPROG"; then
+  echo "$as_me:3992: result: $SEDPROG" >&5
+echo "${ECHO_T}$SEDPROG" >&6
+else
+  echo "$as_me:3995: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "nroff", so it can be a program name with args.
+set dummy nroff; ac_word=$2
+echo "$as_me:4001: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_NROFFPROG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NROFFPROG"; then
+  ac_cv_prog_NROFFPROG="$NROFFPROG" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_NROFFPROG="nroff"
+echo "$as_me:4016: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+NROFFPROG=$ac_cv_prog_NROFFPROG
+if test -n "$NROFFPROG"; then
+  echo "$as_me:4024: result: $NROFFPROG" >&5
+echo "${ECHO_T}$NROFFPROG" >&6
+else
+  echo "$as_me:4027: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$NROFFPROG"; then
+    MANTYPE="cat"
+    mansrcdir='$(srcdir)'
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:4053: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:4063: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:4067: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:4076: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:4080: error: $ac_config_sub $ac_cv_build_alias failed." >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed." >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:4085: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+echo "$as_me:4092: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:4101: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:4106: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+if test -n "$sudo_cv_prev_host"; then
+    if test "$sudo_cv_prev_host" != "$host"; then
+       echo ""
+       echo "Fatal Error: config.cache exists from another platform!"
+       echo "Please remove it and re-run configure."
+       echo ""
+       exit 1
+    else
+       echo "$as_me:4121: checking previous host type" >&5
+echo $ECHO_N "checking previous host type... $ECHO_C" >&6
+       if test "${sudo_cv_prev_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  sudo_cv_prev_host="$host"
+fi
+
+       echo $sudo_cv_prev_host
+    fi
+else
+    # this will produce no output since there is no cached value
+    if test "${sudo_cv_prev_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  sudo_cv_prev_host="$host"
+fi
+
+fi
+
+if test -n "$host_os"; then
+    OS=`echo $host_os | sed 's/[0-9].*//'`
+    OSREV=`echo $host_os | sed 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/'`
+else
+    OS="unknown"
+    OSREV=0
+fi
+
+case "$host" in
+    *-*-sunos4*)
+               # getcwd(3) opens a pipe to getpwd(1)!?!
+               BROKEN_GETCWD=1
+
+               # system headers lack prototypes but gcc helps...
+               if test -n "$GCC"; then
+                   CPPFLAGS="${CPPFLAGS} -D__USE_FIXED_PROTOTYPES__"
+               fi
+
+               # check for password adjunct functions (shadow passwords)
+               if test "$CHECKSHADOW" = "true"; then
+
+for ac_func in getpwanam issecure
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:4165: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4171 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4202: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4205: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4208: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4211: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:4221: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  break
+fi
+done
+
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-solaris2*)
+               # To get the crypt(3) prototype (so we pass -Wall)
+               CPPFLAGS="${CPPFLAGS} -D__EXTENSIONS__"
+               # AFS support needs -lucb
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lucb"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-aix*)
+               # To get all prototypes (so we pass -Wall)
+               CPPFLAGS="${CPPFLAGS} -D_XOPEN_EXTENDED_SOURCE"
+               cat >>confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+               SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp"
+               ;;
+    *-*-hiuxmpp*)
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:4257: checking for getprpwnam in -lsec" >&5
+echo $ECHO_N "checking for getprpwnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4265 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4284: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4287: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4290: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4293: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4304: result: $ac_cv_lib_sec_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getprpwnam" >&6
+if test $ac_cv_lib_sec_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1
+else
+  echo "$as_me:4312: checking for getprpwnam in -lsecurity" >&5
+echo $ECHO_N "checking for getprpwnam in -lsecurity... $ECHO_C" >&6
+if test "${ac_cv_lib_security_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsecurity  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4320 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4339: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4342: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4345: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4348: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_security_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_security_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4359: result: $ac_cv_lib_security_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_security_getprpwnam" >&6
+if test $ac_cv_lib_security_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity"; SECUREWARE=1
+fi
+
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux1[0-9]*)
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:4377: checking for getprpwnam in -lsec" >&5
+echo $ECHO_N "checking for getprpwnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4385 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4404: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4407: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4410: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4413: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4424: result: $ac_cv_lib_sec_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getprpwnam" >&6
+if test $ac_cv_lib_sec_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ echo "$as_me:4430: checking for iscomsec in -lsec" >&5
+echo $ECHO_N "checking for iscomsec in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_iscomsec+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4438 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char iscomsec ();
+int
+main ()
+{
+iscomsec ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4457: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4460: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4463: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4466: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_iscomsec=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_iscomsec=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4477: result: $ac_cv_lib_sec_iscomsec" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_iscomsec" >&6
+if test $ac_cv_lib_sec_iscomsec = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_ISCOMSEC 1
+EOF
+
+fi
+ SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1
+fi
+
+                   CHECKSHADOW="false"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux9*)
+
+cat >>confdefs.h <<\EOF
+#define BROKEN_SYSLOG 1
+EOF
+
+               if test "$CHECKSHADOW" = "true"; then
+
+for ac_func in getspwuid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:4510: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4516 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4547: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4550: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4553: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4556: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:4566: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+                   CHECKSHADOW="false"
+               fi
+
+               # DCE support (requires ANSI C compiler)
+               if test "$with_DCE" = "yes"; then
+                   # order of libs in 9.X is important. -lc_r must be last
+                   SUDO_LIBS="${SUDO_LIBS} -ldce -lM -lc_r"
+                   LIBS="${LIBS} -ldce -lM -lc_r"
+                   CPPFLAGS="${CPPFLAGS} -D_REENTRANT -I/usr/include/reentrant"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux*)
+               cat >>confdefs.h <<\EOF
+#define BROKEN_SYSLOG 1
+EOF
+
+               # Not sure if setuid binaries are safe in < 9.x
+               if test -n "$GCC"; then
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -static"
+               else
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-dec-osf*)
+               # ignore envariables wrt dynamic lib path
+               SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-no_library_replacement"
+
+               echo "$as_me:4617: checking whether to disable sia support on Digital UNIX" >&5
+echo $ECHO_N "checking whether to disable sia support on Digital UNIX... $ECHO_C" >&6
+               # Check whether --enable-sia or --disable-sia was given.
+if test "${enable_sia+set}" = set; then
+  enableval="$enable_sia"
+   case "$enableval" in
+                   yes)        echo "$as_me:4623: result: no" >&5
+echo "${ECHO_T}no" >&6
+                               ;;
+                   no)         echo "$as_me:4626: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+                               CHECKSIA=false
+                               ;;
+                   *)          echo "$as_me:4630: result: no" >&5
+echo "${ECHO_T}no" >&6
+                               echo "Ignoring unknown argument to --enable-sia: $enableval"
+                               ;;
+                 esac
+
+else
+  echo "$as_me:4637: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+               # use SIA by default, if we have it, else SecureWare
+               # unless overridden on the command line
+               if test "$CHECKSIA" = "true"; then
+                   echo "$as_me:4644: checking for sia_ses_init" >&5
+echo $ECHO_N "checking for sia_ses_init... $ECHO_C" >&6
+if test "${ac_cv_func_sia_ses_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4650 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sia_ses_init (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sia_ses_init ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_sia_ses_init) || defined (__stub___sia_ses_init)
+choke me
+#else
+f = sia_ses_init;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4681: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4684: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4687: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4690: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_sia_ses_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_sia_ses_init=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:4700: result: $ac_cv_func_sia_ses_init" >&5
+echo "${ECHO_T}$ac_cv_func_sia_ses_init" >&6
+if test $ac_cv_func_sia_ses_init = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_SIA 1
+EOF
+
+                   if test -n "$with_skey" -o -n "$with_opie" -o -n "$with_otp_only" -o -n "$with_long_otp_prompt" -o -n "$with_SecurID" -o -n "$with_fwtk" -o -n "$with_kerb4" -o -n "$with_kerb5" -o -n "$with_pam" -o -n "$with_AFS" -o -n "$with_DCE"; then
+                       { { echo "$as_me:4709: error: \"you cannot mix SIA and other authentication schemes.  You can turn off SIA support via the --disable-sia option\"" >&5
+echo "$as_me: error: \"you cannot mix SIA and other authentication schemes.  You can turn off SIA support via the --disable-sia option\"" >&2;}
+   { (exit 1); exit 1; }; }
+                   fi; CHECKSHADOW=false
+fi
+
+               fi
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:4717: checking for getprpwnam in -lsecurity" >&5
+echo $ECHO_N "checking for getprpwnam in -lsecurity... $ECHO_C" >&6
+if test "${ac_cv_lib_security_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsecurity  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4725 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4744: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4747: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4750: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4753: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_security_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_security_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4764: result: $ac_cv_lib_security_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_security_getprpwnam" >&6
+if test $ac_cv_lib_security_getprpwnam = yes; then
+  SECUREWARE=1
+fi
+
+                   CHECKSHADOW="false"
+               fi
+
+               if test -n "$SECUREWARE"; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+
+                   # -ldb includes bogus versions of snprintf/vsnprintf
+
+for ac_func in snprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:4784: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4790 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4821: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4824: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4827: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4830: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:4840: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  NEED_SNPRINTF=1
+fi
+done
+
+for ac_func in vsnprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:4855: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4861 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4892: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4895: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4898: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4901: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:4911: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  NEED_SNPRINTF=1
+fi
+done
+
+                   # 4.x and higher need -ldb too...
+                   echo "$as_me:4924: checking for dbopen in -ldb" >&5
+echo $ECHO_N "checking for dbopen in -ldb... $ECHO_C" >&6
+if test "${ac_cv_lib_db_dbopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldb  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 4932 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbopen ();
+int
+main ()
+{
+dbopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:4951: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:4954: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:4957: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:4960: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_db_dbopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_db_dbopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:4971: result: $ac_cv_lib_db_dbopen" >&5
+echo "${ECHO_T}$ac_cv_lib_db_dbopen" >&6
+if test $ac_cv_lib_db_dbopen = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"
+else
+  SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"
+fi
+
+for ac_func in dispcrypt
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:4982: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 4988 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5019: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5022: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5025: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5028: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:5038: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+                   echo "$as_me:5048: checking for broken /usr/include/prot.h" >&5
+echo $ECHO_N "checking for broken /usr/include/prot.h... $ECHO_C" >&6
+                   cat >conftest.$ac_ext <<_ACEOF
+#line 5051 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#include <sys/security.h>
+#include <prot.h>
+
+int
+main ()
+{
+exit(0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:5067: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:5070: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:5073: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5076: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:5078: result: no" >&5
+echo "${ECHO_T}no" >&6
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+echo "$as_me:5083: result: yes, fixing locally" >&5
+echo "${ECHO_T}yes, fixing locally" >&6
+                   sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+               elif test "$CHECKSIA" = "true"; then
+                   with_passwd=no
+                   AUTH_OBJS="sia.o"
+               fi
+               test -n "$mansectsu" || mansectsu=8
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-irix*)
+               CPPFLAGS="${CPPFLAGS} -D_BSD_TYPES"
+               if test -z "$NROFFPROG"; then
+                   MAN_POSTINSTALL='   /bin/rm -f $(mandir8)/sudo.$(mansect8).z $(mandir8)/visudo.$(mansect8).z $(mandir5)/sudoers.$(mansect5).z ; /usr/bin/pack $(mandir8)/sudo.$(mansect8) $(mandir8)/visudo.$(mansect8) $(mandir5)/sudoers.$(mansect5)'
+                   if test "$prefix" = "/usr/local" -a "$mandir" = '$(prefix)/man'; then
+                       if test -d /usr/share/catman/local; then
+                           mandir="/usr/share/catman/local"
+                       else
+                           mandir="/usr/catman/local"
+                       fi
+                   fi
+               else
+                   if test "$prefix" = "/usr/local" -a "$mandir" = '$(prefix)/man'; then
+                       if test -d "/usr/share/man/local"; then
+                           mandir="/usr/share/man/local"
+                       else
+                           mandir="/usr/man/local"
+                       fi
+                   fi
+               fi
+               # IRIX <= 4 needs -lsun
+               if test "$OSREV" -le 4; then
+                   echo "$as_me:5118: checking for getpwnam in -lsun" >&5
+echo $ECHO_N "checking for getpwnam in -lsun... $ECHO_C" >&6
+if test "${ac_cv_lib_sun_getpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsun  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5126 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getpwnam ();
+int
+main ()
+{
+getpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5145: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5148: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5151: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5154: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sun_getpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sun_getpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5165: result: $ac_cv_lib_sun_getpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sun_getpwnam" >&6
+if test $ac_cv_lib_sun_getpwnam = yes; then
+  LIBS="${LIBS} -lsun"
+fi
+
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-linux*)
+               # Some Linux versions need to link with -lshadow
+               if test "$CHECKSHADOW" = "true"; then
+
+for ac_func in getspnam
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:5182: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 5188 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5219: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5222: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5225: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5228: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:5238: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  echo "$as_me:5246: checking for getspnam in -lshadow" >&5
+echo $ECHO_N "checking for getspnam in -lshadow... $ECHO_C" >&6
+if test "${ac_cv_lib_shadow_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lshadow  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5254 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+int
+main ()
+{
+getspnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5273: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5276: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5279: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5282: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_shadow_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_shadow_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5293: result: $ac_cv_lib_shadow_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_shadow_getspnam" >&6
+if test $ac_cv_lib_shadow_getspnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lshadow"; LIBS="${LIBS} -lshadow"
+fi
+
+fi
+done
+
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-convex-bsd*)
+               cat >>confdefs.h <<\EOF
+#define _CONVEX_SOURCE 1
+EOF
+
+               if test -z "$GCC"; then
+                   CFLAGS="${CFLAGS} -D__STDC__"
+               fi
+
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:5318: checking for getprpwnam in -lsec" >&5
+echo $ECHO_N "checking for getprpwnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5326 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5345: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5348: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5351: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5354: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5365: result: $ac_cv_lib_sec_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getprpwnam" >&6
+if test $ac_cv_lib_sec_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lprot"; LIBS="${LIBS} -lprot"; OSDEFS="${OSDEFS} -D_AUDIT -D_ACL -DSecureWare"; SECUREWARE=1
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-ultrix*)
+               OS="ultrix"
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:5380: checking for getauthuid in -lauth" >&5
+echo $ECHO_N "checking for getauthuid in -lauth... $ECHO_C" >&6
+if test "${ac_cv_lib_auth_getauthuid+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lauth  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5388 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getauthuid ();
+int
+main ()
+{
+getauthuid ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5407: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5410: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5413: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5416: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_auth_getauthuid=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_auth_getauthuid=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5427: result: $ac_cv_lib_auth_getauthuid" >&5
+echo "${ECHO_T}$ac_cv_lib_auth_getauthuid" >&6
+if test $ac_cv_lib_auth_getauthuid = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_GETAUTHUID 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lauth"; LIBS="${LIBS} -lauth"
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-riscos*)
+               LIBS="${LIBS} -lsun -lbsd"
+               CPPFLAGS="${CPPFLAGS} -I/usr/include -I/usr/include/bsd"
+               OSDEFS="${OSDEFS} -D_MIPS"
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-isc*)
+               OSDEFS="${OSDEFS} -D_ISC"
+               LIB_CRYPT=1
+               SUDO_LIBS="${SUDO_LIBS} -lcrypt"
+               LIBS="${LIBS} -lcrypt"
+
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:5454: checking for getspnam in -lsec" >&5
+echo $ECHO_N "checking for getspnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5462 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+int
+main ()
+{
+getspnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5481: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5484: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5487: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5490: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5501: result: $ac_cv_lib_sec_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getspnam" >&6
+if test $ac_cv_lib_sec_getspnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-sco*|*-sco-*)
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:5517: checking for getprpwnam in -lprot" >&5
+echo $ECHO_N "checking for getprpwnam in -lprot... $ECHO_C" >&6
+if test "${ac_cv_lib_prot_getprpwnam_lx+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lprot -lx $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5525 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5544: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5547: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5550: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5553: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_prot_getprpwnam_lx=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_prot_getprpwnam_lx=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5564: result: $ac_cv_lib_prot_getprpwnam_lx" >&5
+echo "${ECHO_T}$ac_cv_lib_prot_getprpwnam_lx" >&6
+if test $ac_cv_lib_prot_getprpwnam_lx = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lprot -lx"; LIBS="${LIBS} -lprot -lx"; SECUREWARE=1
+fi
+
+                   echo "$as_me:5573: checking for getspnam in -lgen" >&5
+echo $ECHO_N "checking for getspnam in -lgen... $ECHO_C" >&6
+if test "${ac_cv_lib_gen_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgen  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5581 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+int
+main ()
+{
+getspnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5600: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5603: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5606: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5609: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gen_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_gen_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5620: result: $ac_cv_lib_gen_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_gen_getspnam" >&6
+if test $ac_cv_lib_gen_getspnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lgen"; LIBS="${LIBS} -lgen"
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    m88k-motorola-sysv*)
+               # motorolla's cc (a variant of gcc) does -O but not -O2
+               CFLAGS=`echo $CFLAGS | sed 's/-O2/-O/g'`
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-sequent-sysv*)
+               if test "$CHECKSHADOW" = "true"; then
+                   echo "$as_me:5642: checking for getspnam in -lsec" >&5
+echo $ECHO_N "checking for getspnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5650 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+int
+main ()
+{
+getspnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5669: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5672: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5675: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5678: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5689: result: $ac_cv_lib_sec_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getspnam" >&6
+if test $ac_cv_lib_sec_getspnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"
+fi
+
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-ncr-sysv4*|*-ncr-sysvr4*)
+               echo "$as_me:5704: checking for strcasecmp in -lc89" >&5
+echo $ECHO_N "checking for strcasecmp in -lc89... $ECHO_C" >&6
+if test "${ac_cv_lib_c89_strcasecmp+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc89  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5712 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strcasecmp ();
+int
+main ()
+{
+strcasecmp ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5731: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5734: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5737: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5740: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c89_strcasecmp=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_c89_strcasecmp=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5751: result: $ac_cv_lib_c89_strcasecmp" >&5
+echo "${ECHO_T}$ac_cv_lib_c89_strcasecmp" >&6
+if test $ac_cv_lib_c89_strcasecmp = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_STRCASECMP 1
+EOF
+ LIBS="${LIBS} -lc89"; ac_cv_func_strcasecmp=yes
+fi
+
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-ccur-sysv4*|*-ccur-sysvr4*)
+               LIBS="${LIBS} -lgen"
+               SUDO_LIBS="${SUDO_LIBS} -lgen"
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-bsdi*)
+               BROKEN_SETREUID=yes
+               # Use shlicc for BSD/OS [23].x unless asked to do otherwise
+               if test "${with_CC+set}" != set -a "$ac_cv_prog_CC" = gcc; then
+                   case "$OSREV" in
+                       2|3)    echo 'using shlicc as CC'
+                               ac_cv_prog_CC=shlicc
+                               CC="$ac_cv_prog_CC"
+                               ;;
+                   esac
+               fi
+               ;;
+    *-*-freebsd*)
+               # FreeBSD has a real setreuid(2) starting with 2.1 and
+               # backported to 2.0.5.  We just take 2.1 and above...
+               case "`echo $host_os | sed 's/^freebsd\([0-9\.]*\).*$/\1/'`" in
+               0.*|1.*|2.0*)
+                   BROKEN_SETREUID=yes
+                   ;;
+               esac
+               if test "$with_logincap" = "yes"; then
+                   SUDO_LIBS="${SUDO_LIBS} -lutil"
+               fi
+               if test "$with_skey" = "yes"; then
+                    SUDO_LIBS="${SUDO_LIBS} -lmd"
+               fi
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*openbsd*)
+               BROKEN_SETREUID=yes
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*netbsd*)
+               # NetBSD has a real setreuid(2) starting with 1.3.2
+               case "`echo $host_os | sed 's/^netbsd\([0-9\.]*\).*$/\1/'`" in
+               0.9*|1.012*|1.3|1.3.1)
+                   BROKEN_SETREUID=yes
+                   ;;
+               esac
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*bsd*)
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-nextstep*)
+               # lockf() on is broken on the NeXT -- use flock instead
+               ac_cv_func_lockf=no
+               ac_cv_func_flock=yes
+               ;;
+    *-*-sysv*)
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+esac
+
+test -n "$mansectsu" || mansectsu=8
+test -n "$mansectform" || mansectform=5
+
+if test "$CHECKSHADOW" = "true"; then
+
+for ac_func in getspnam
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:5840: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 5846 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5877: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5880: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5883: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5886: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:5896: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+ CHECKSHADOW="false"
+else
+  echo "$as_me:5904: checking for getspnam in -lgen" >&5
+echo $ECHO_N "checking for getspnam in -lgen... $ECHO_C" >&6
+if test "${ac_cv_lib_gen_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgen  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 5912 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+int
+main ()
+{
+getspnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:5931: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:5934: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:5937: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:5940: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gen_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_gen_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:5951: result: $ac_cv_lib_gen_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_gen_getspnam" >&6
+if test $ac_cv_lib_gen_getspnam = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
+EOF
+ SUDO_LIBS="${SUDO_LIBS} -lgen"; LIBS="${LIBS} -lgen"
+fi
+
+fi
+done
+
+fi
+if test "$CHECKSHADOW" = "true"; then
+    echo "$as_me:5966: checking for getprpwnam" >&5
+echo $ECHO_N "checking for getprpwnam... $ECHO_C" >&6
+if test "${ac_cv_func_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 5972 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getprpwnam (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getprpwnam) || defined (__stub___getprpwnam)
+choke me
+#else
+f = getprpwnam;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6003: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6006: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6009: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6012: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:6022: result: $ac_cv_func_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_func_getprpwnam" >&6
+if test $ac_cv_func_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ CHECKSHADOW="false"; SECUREWARE=1, echo "$as_me:6028: checking for getprpwnam in -lsec" >&5
+echo $ECHO_N "checking for getprpwnam in -lsec... $ECHO_C" >&6
+if test "${ac_cv_lib_sec_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsec  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 6036 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6055: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6058: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6061: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6064: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sec_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_sec_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:6075: result: $ac_cv_lib_sec_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_sec_getprpwnam" >&6
+if test $ac_cv_lib_sec_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"
+else
+  echo "$as_me:6083: checking for getprpwnam in -lsecurity" >&5
+echo $ECHO_N "checking for getprpwnam in -lsecurity... $ECHO_C" >&6
+if test "${ac_cv_lib_security_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsecurity  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 6091 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6110: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6113: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6116: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6119: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_security_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_security_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:6130: result: $ac_cv_lib_security_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_security_getprpwnam" >&6
+if test $ac_cv_lib_security_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity"
+else
+  echo "$as_me:6138: checking for getprpwnam in -lprot" >&5
+echo $ECHO_N "checking for getprpwnam in -lprot... $ECHO_C" >&6
+if test "${ac_cv_lib_prot_getprpwnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lprot  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 6146 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getprpwnam ();
+int
+main ()
+{
+getprpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6165: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6168: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6171: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6174: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_prot_getprpwnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_prot_getprpwnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:6185: result: $ac_cv_lib_prot_getprpwnam" >&5
+echo "${ECHO_T}$ac_cv_lib_prot_getprpwnam" >&6
+if test $ac_cv_lib_prot_getprpwnam = yes; then
+  cat >>confdefs.h <<\EOF
+#define HAVE_GETPRPWNAM 1
+EOF
+ CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lprot"; LIBS="${LIBS} -lprot"
+fi
+
+fi
+
+fi
+
+fi
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:6203: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6210 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line 6225 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:6238: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:6245: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6251 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:6309: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:6312: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:6315: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6318: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_c_const=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:6328: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo "$as_me:6338: checking for working volatile" >&5
+echo $ECHO_N "checking for working volatile... $ECHO_C" >&6
+if test "${ac_cv_c_volatile+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6344 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:6358: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:6361: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:6364: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6367: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_volatile=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_c_volatile=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:6377: result: $ac_cv_c_volatile" >&5
+echo "${ECHO_T}$ac_cv_c_volatile" >&6
+if test $ac_cv_c_volatile = no; then
+
+cat >>confdefs.h <<\EOF
+#define volatile
+EOF
+
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:6391: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+  ac_save_IFS=$IFS; IFS=$ac_path_separator
+ac_dummy="$PATH"
+for ac_dir in $ac_dummy; do
+  IFS=$ac_save_IFS
+  test -z "$ac_dir" && ac_dir=.
+  $as_executable_p "$ac_dir/$ac_word" || continue
+ac_cv_prog_YACC="$ac_prog"
+echo "$as_me:6406: found $ac_dir/$ac_word" >&5
+break
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:6414: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:6417: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo "$as_me:6425: checking for mv" >&5
+echo $ECHO_N "checking for mv... $ECHO_C" >&6
+if test -f "/usr/bin/mv"; then
+    echo "$as_me:6428: result: /usr/bin/mv" >&5
+echo "${ECHO_T}/usr/bin/mv" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_MV "/usr/bin/mv"
+EOF
+
+elif test -f "/bin/mv"; then
+    echo "$as_me:6435: result: /bin/mv" >&5
+echo "${ECHO_T}/bin/mv" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_MV "/bin/mv"
+EOF
+
+elif test -f "/usr/ucb/mv"; then
+    echo "$as_me:6442: result: /usr/ucb/mv" >&5
+echo "${ECHO_T}/usr/ucb/mv" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_MV "/usr/ucb/mv"
+EOF
+
+elif test -f "/usr/sbin/mv"; then
+    echo "$as_me:6449: result: /usr/sbin/mv" >&5
+echo "${ECHO_T}/usr/sbin/mv" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_MV "/usr/sbin/mv"
+EOF
+
+else
+    echo "$as_me:6456: result: not found" >&5
+echo "${ECHO_T}not found" >&6
+fi
+
+echo "$as_me:6460: checking for bourne shell" >&5
+echo $ECHO_N "checking for bourne shell... $ECHO_C" >&6
+if test -f "/bin/sh"; then
+    echo "$as_me:6463: result: /bin/sh" >&5
+echo "${ECHO_T}/bin/sh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/bin/sh"
+EOF
+
+elif test -f "/usr/bin/sh"; then
+    echo "$as_me:6470: result: /usr/bin/sh" >&5
+echo "${ECHO_T}/usr/bin/sh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/usr/bin/sh"
+EOF
+
+elif test -f "/sbin/sh"; then
+    echo "$as_me:6477: result: /sbin/sh" >&5
+echo "${ECHO_T}/sbin/sh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/sbin/sh"
+EOF
+
+elif test -f "/usr/sbin/sh"; then
+    echo "$as_me:6484: result: /usr/sbin/sh" >&5
+echo "${ECHO_T}/usr/sbin/sh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/usr/sbin/sh"
+EOF
+
+elif test -f "/bin/ksh"; then
+    echo "$as_me:6491: result: /bin/ksh" >&5
+echo "${ECHO_T}/bin/ksh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/bin/ksh"
+EOF
+
+elif test -f "/usr/bin/ksh"; then
+    echo "$as_me:6498: result: /usr/bin/ksh" >&5
+echo "${ECHO_T}/usr/bin/ksh" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/usr/bin/ksh"
+EOF
+
+elif test -f "/bin/bash"; then
+    echo "$as_me:6505: result: /bin/bash" >&5
+echo "${ECHO_T}/bin/bash" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/bin/bash"
+EOF
+
+elif test -f "/usr/bin/bash"; then
+    echo "$as_me:6512: result: /usr/bin/bash" >&5
+echo "${ECHO_T}/usr/bin/bash" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_BSHELL "/usr/bin/bash"
+EOF
+
+else
+    echo "$as_me:6519: result: not found" >&5
+echo "${ECHO_T}not found" >&6
+fi
+
+if test -z "$with_sendmail"; then
+    echo "$as_me:6524: checking for sendmail" >&5
+echo $ECHO_N "checking for sendmail... $ECHO_C" >&6
+if test -f "/usr/sbin/sendmail"; then
+    echo "$as_me:6527: result: /usr/sbin/sendmail" >&5
+echo "${ECHO_T}/usr/sbin/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/sbin/sendmail"
+EOF
+
+elif test -f "/usr/lib/sendmail"; then
+    echo "$as_me:6534: result: /usr/lib/sendmail" >&5
+echo "${ECHO_T}/usr/lib/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/lib/sendmail"
+EOF
+
+elif test -f "/usr/etc/sendmail"; then
+    echo "$as_me:6541: result: /usr/etc/sendmail" >&5
+echo "${ECHO_T}/usr/etc/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/etc/sendmail"
+EOF
+
+elif test -f "/usr/ucblib/sendmail"; then
+    echo "$as_me:6548: result: /usr/ucblib/sendmail" >&5
+echo "${ECHO_T}/usr/ucblib/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/ucblib/sendmail"
+EOF
+
+elif test -f "/usr/local/lib/sendmail"; then
+    echo "$as_me:6555: result: /usr/local/lib/sendmail" >&5
+echo "${ECHO_T}/usr/local/lib/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/local/lib/sendmail"
+EOF
+
+elif test -f "/usr/local/bin/sendmail"; then
+    echo "$as_me:6562: result: /usr/local/bin/sendmail" >&5
+echo "${ECHO_T}/usr/local/bin/sendmail" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_SENDMAIL "/usr/local/bin/sendmail"
+EOF
+
+else
+    echo "$as_me:6569: result: not found" >&5
+echo "${ECHO_T}not found" >&6
+fi
+
+fi
+if test -z "$with_editor"; then
+    echo "$as_me:6575: checking for vi" >&5
+echo $ECHO_N "checking for vi... $ECHO_C" >&6
+if test -f "/usr/bin/vi"; then
+    echo "$as_me:6578: result: /usr/bin/vi" >&5
+echo "${ECHO_T}/usr/bin/vi" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_VI "/usr/bin/vi"
+EOF
+
+elif test -f "/usr/ucb/vi"; then
+    echo "$as_me:6585: result: /usr/ucb/vi" >&5
+echo "${ECHO_T}/usr/ucb/vi" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_VI "/usr/ucb/vi"
+EOF
+
+elif test -f "/usr/bsd/vi"; then
+    echo "$as_me:6592: result: /usr/bsd/vi" >&5
+echo "${ECHO_T}/usr/bsd/vi" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_VI "/usr/bsd/vi"
+EOF
+
+elif test -f "/bin/vi"; then
+    echo "$as_me:6599: result: /bin/vi" >&5
+echo "${ECHO_T}/bin/vi" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_VI "/bin/vi"
+EOF
+
+elif test -f "/usr/local/bin/vi"; then
+    echo "$as_me:6606: result: /usr/local/bin/vi" >&5
+echo "${ECHO_T}/usr/local/bin/vi" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_VI "/usr/local/bin/vi"
+EOF
+
+else
+    echo "$as_me:6613: result: not found" >&5
+echo "${ECHO_T}not found" >&6
+fi
+
+fi
+echo "$as_me:6618: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6624 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+_ACEOF
+if { (eval echo "$as_me:6632: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:6638: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6660 "configure"
+#include "confdefs.h"
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6678 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6699 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:6725: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6728: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:6730: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6733: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:6746: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:6759: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6765 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:6780: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:6783: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:6786: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6789: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:6799: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+EOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:6812: checking for opendir in -ldir" >&5
+echo $ECHO_N "checking for opendir in -ldir... $ECHO_C" >&6
+if test "${ac_cv_lib_dir_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldir  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 6820 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6839: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6842: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6845: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6848: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dir_opendir=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_dir_opendir=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:6859: result: $ac_cv_lib_dir_opendir" >&5
+echo "${ECHO_T}$ac_cv_lib_dir_opendir" >&6
+if test $ac_cv_lib_dir_opendir = yes; then
+  LIBS="$LIBS -ldir"
+fi
+
+else
+  echo "$as_me:6866: checking for opendir in -lx" >&5
+echo $ECHO_N "checking for opendir in -lx... $ECHO_C" >&6
+if test "${ac_cv_lib_x_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lx  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 6874 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:6893: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6896: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6899: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:6902: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_x_opendir=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_x_opendir=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:6913: result: $ac_cv_lib_x_opendir" >&5
+echo "${ECHO_T}$ac_cv_lib_x_opendir" >&6
+if test $ac_cv_lib_x_opendir = yes; then
+  LIBS="$LIBS -lx"
+fi
+
+fi
+
+for ac_header in malloc.h paths.h utime.h netgroup.h sys/sockio.h sys/bsdtypes.h sys/select.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:6924: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 6930 "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:6934: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:6940: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:6959: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+if test "$OS" != "ultrix"; then
+    echo "$as_me:6970: 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
+#line 6976 "configure"
+#include "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 { (eval echo "$as_me:6991: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:6994: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:6997: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7000: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_posix_termios=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_sys_posix_termios=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:7010: 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 <<\EOF
+#define HAVE_TERMIOS_H 1
+EOF
+
+    else
+
+for ac_header in termio.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:7024: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7030 "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:7034: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:7040: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:7059: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+    fi
+fi
+if test "$with_logincap" = "yes"; then
+
+for ac_header in login_cap.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:7076: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7082 "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:7086: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:7092: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:7111: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+fi
+if test "$with_bsdauth" = "yes"; then
+    echo "$as_me:7123: checking for bsd_auth.h" >&5
+echo $ECHO_N "checking for bsd_auth.h... $ECHO_C" >&6
+if test "${ac_cv_header_bsd_auth_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7129 "configure"
+#include "confdefs.h"
+#include <bsd_auth.h>
+_ACEOF
+if { (eval echo "$as_me:7133: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:7139: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_cv_header_bsd_auth_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_header_bsd_auth_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:7158: result: $ac_cv_header_bsd_auth_h" >&5
+echo "${ECHO_T}$ac_cv_header_bsd_auth_h" >&6
+if test $ac_cv_header_bsd_auth_h = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_BSD_AUTH_H 1
+EOF
+ with_passwd=no; AUTH_OBJS=bsdauth.o
+fi
+
+fi
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:7175: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7181 "configure"
+#include "confdefs.h"
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7187: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7190: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7193: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7196: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7206: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+echo "$as_me:7216: checking for mode_t" >&5
+echo $ECHO_N "checking for mode_t... $ECHO_C" >&6
+if test "${ac_cv_type_mode_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7222 "configure"
+#include "confdefs.h"
+$ac_includes_default
+int
+main ()
+{
+if ((mode_t *) 0)
+  return 0;
+if (sizeof (mode_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7237: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7240: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7243: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7246: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_mode_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_type_mode_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7256: result: $ac_cv_type_mode_t" >&5
+echo "${ECHO_T}$ac_cv_type_mode_t" >&6
+if test $ac_cv_type_mode_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<EOF
+#define mode_t int
+EOF
+
+fi
+
+echo "$as_me:7268: checking for uid_t in sys/types.h" >&5
+echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
+if test "${ac_cv_type_uid_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7274 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:7288: result: $ac_cv_type_uid_t" >&5
+echo "${ECHO_T}$ac_cv_type_uid_t" >&6
+if test $ac_cv_type_uid_t = no; then
+
+cat >>confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+cat >>confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo "$as_me:7302: 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
+#line 7308 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+if ((sig_atomic_t *) 0)
+  return 0;
+if (sizeof (sig_atomic_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7325: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7328: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7331: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7334: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_sig_atomic_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_type_sig_atomic_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7344: 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 <<EOF
+#define HAVE_SIG_ATOMIC_T 1
+EOF
+
+else
+
+cat >>confdefs.h <<\EOF
+#define sig_atomic_t int
+EOF
+
+fi
+
+echo "$as_me:7360: 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
+#line 7366 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+if ((sigaction_t *) 0)
+  return 0;
+if (sizeof (sigaction_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7383: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7386: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7389: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7392: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_sigaction_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_type_sigaction_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7402: 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 <<EOF
+#define HAVE_SIGACTION_T 1
+EOF
+
+cat >>confdefs.h <<\EOF
+#define HAVE_SIGACTION_T 1
+EOF
+
+fi
+
+echo "$as_me:7416: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${sudo_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7422 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "size_t" >/dev/null 2>&1; then
+  sudo_cv_type_size_t=yes
+else
+  sudo_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:7442: result: $sudo_cv_type_size_t" >&5
+echo "${ECHO_T}$sudo_cv_type_size_t" >&6
+if test $sudo_cv_type_size_t = no; then
+
+cat >>confdefs.h <<\EOF
+#define size_t int
+EOF
+
+fi
+
+echo "$as_me:7452: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${sudo_cv_type_ssize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7458 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "ssize_t" >/dev/null 2>&1; then
+  sudo_cv_type_ssize_t=yes
+else
+  sudo_cv_type_ssize_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:7478: result: $sudo_cv_type_ssize_t" >&5
+echo "${ECHO_T}$sudo_cv_type_ssize_t" >&6
+if test $sudo_cv_type_ssize_t = no; then
+
+cat >>confdefs.h <<\EOF
+#define ssize_t int
+EOF
+
+fi
+
+echo "$as_me:7488: checking for dev_t" >&5
+echo $ECHO_N "checking for dev_t... $ECHO_C" >&6
+if test "${sudo_cv_type_dev_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7494 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "dev_t" >/dev/null 2>&1; then
+  sudo_cv_type_dev_t=yes
+else
+  sudo_cv_type_dev_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:7514: result: $sudo_cv_type_dev_t" >&5
+echo "${ECHO_T}$sudo_cv_type_dev_t" >&6
+if test $sudo_cv_type_dev_t = no; then
+
+cat >>confdefs.h <<\EOF
+#define dev_t int
+EOF
+
+fi
+
+echo "$as_me:7524: checking for ino_t" >&5
+echo $ECHO_N "checking for ino_t... $ECHO_C" >&6
+if test "${sudo_cv_type_ino_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7530 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "ino_t" >/dev/null 2>&1; then
+  sudo_cv_type_ino_t=yes
+else
+  sudo_cv_type_ino_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:7550: result: $sudo_cv_type_ino_t" >&5
+echo "${ECHO_T}$sudo_cv_type_ino_t" >&6
+if test $sudo_cv_type_ino_t = no; then
+
+cat >>confdefs.h <<\EOF
+#define ino_t unsigned int
+EOF
+
+fi
+
+echo "$as_me:7560: checking for full void implementation" >&5
+echo $ECHO_N "checking for full void implementation... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line 7563 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+void *foo;
+foo = (void *)0; (void *)"test";
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7576: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7579: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7582: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7585: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\EOF
+#define VOID void
+EOF
+
+echo "$as_me:7592: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+cat >>confdefs.h <<\EOF
+#define VOID char
+EOF
+
+echo "$as_me:7601: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:7606: checking max length of uid_t" >&5
+echo $ECHO_N "checking max length of uid_t... $ECHO_C" >&6
+if test "${sudo_cv_uid_t_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f conftestdata
+if test "$cross_compiling" = yes; then
+  { { echo "$as_me:7613: error: cannot run test program while cross compiling" >&5
+echo "$as_me: error: cannot run test program while cross compiling" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7618 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/param.h>
+main() {
+  FILE *f;
+  char b[1024];
+  uid_t u = (uid_t) -1;
+
+  if ((f = fopen("conftestdata", "w")) == NULL)
+    exit(1);
+
+  (void) sprintf(b, "%u", u);
+  (void) fprintf(f, "%d\n", strlen(b));
+  (void) fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:7640: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7643: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:7645: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7648: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_uid_t_len=`cat conftestdata`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+sudo_cv_uid_t_len=10
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+fi
+
+rm -f conftestdata
+echo "$as_me:7663: result: $sudo_cv_uid_t_len" >&5
+echo "${ECHO_T}$sudo_cv_uid_t_len" >&6
+
+cat >>confdefs.h <<EOF
+#define MAX_UID_T_LEN $sudo_cv_uid_t_len
+EOF
+
+echo "$as_me:7670: checking for long long support" >&5
+echo $ECHO_N "checking for long long support... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line 7673 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+long long foo = 1000; foo /= 10;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:7685: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7688: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:7691: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7694: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_LONG_LONG 1
+EOF
+
+if test "$cross_compiling" = yes; then
+  { { echo "$as_me:7702: error: cannot run test program while cross compiling" >&5
+echo "$as_me: error: cannot run test program while cross compiling" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7707 "configure"
+#include "confdefs.h"
+main() {if (sizeof(long long) == sizeof(long)) exit(0); else exit(1);}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:7712: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7715: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:7717: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7720: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\EOF
+#define LONG_IS_QUAD 1
+EOF
+
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7734: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+echo "$as_me:7739: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+echo "$as_me:7743: checking for sa_len field in struct sockaddr" >&5
+echo $ECHO_N "checking for sa_len field in struct sockaddr... $ECHO_C" >&6
+if test "${sudo_cv_sock_sa_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  sudo_cv_sock_sa_len=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7752 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+main() {
+struct sockaddr s;
+s.sa_len = 0;
+exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:7763: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7766: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:7768: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7771: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_sock_sa_len=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+sudo_cv_sock_sa_len=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core core.* *.core
+fi
+echo "$as_me:7784: result: $sudo_cv_sock_sa_len" >&5
+echo "${ECHO_T}$sudo_cv_sock_sa_len" >&6
+if test $sudo_cv_sock_sa_len = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_SA_LEN 1
+EOF
+
+fi
+
+case "$DEFS" in
+    *"RETSIGTYPE"*)    ;;
+    *)                 echo "$as_me:7796: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7802 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:7824: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:7827: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:7830: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7833: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_type_signal=int
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:7843: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+;;
+esac
+
+for ac_func in strchr strrchr memchr memcpy memset sysconf tzset \
+              seteuid setegid strftime setrlimit initgroups fstat
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:7857: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7863 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:7894: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7897: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:7900: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7903: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:7913: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+if test -z "$BROKEN_SETREUID"; then
+
+for ac_func in setreuid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:7928: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 7934 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:7965: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:7968: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:7971: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:7974: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:7984: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+fi
+if test X"$with_interfaces" != X"no"; then
+
+for ac_func in getifaddrs
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8000: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8006 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8037: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8040: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8043: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8046: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8056: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+for ac_func in freeifaddrs
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8066: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8072 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes
+else
+  which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8104: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8107: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8110: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8113: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8123: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+fi
+done
+
+fi
+if test -n "$SECUREWARE"; then
+
+for ac_func in bigcrypt set_auth_parameters initprivs
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8142: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8148 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8179: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8182: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8185: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8188: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8198: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+
+fi
+if test -z "$BROKEN_GETCWD"; then
+
+for ac_func in getcwd
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8214: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8220 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8251: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8254: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8257: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8260: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8270: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+fi
+done
+
+fi
+
+for ac_func in lockf flock
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8287: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8293 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8324: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8327: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8330: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8333: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8343: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+ break
+fi
+done
+
+for ac_func in waitpid wait3
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8356: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8362 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8393: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8396: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8399: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8402: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8412: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+ break
+fi
+done
+
+for ac_func in innetgr _innetgr
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8425: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8431 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8462: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8465: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8468: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8471: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8481: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+for ac_func in getdomainname
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8491: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8497 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes
+else
+  which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8529: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8532: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8535: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8538: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8548: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+fi
+done
+ break
+fi
+done
+
+for ac_func in lsearch
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8564: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8570 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8601: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8604: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8607: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8610: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8620: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  echo "$as_me:8628: 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
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcompat  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 8636 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char lsearch ();
+int
+main ()
+{
+lsearch ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8655: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8658: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8661: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8664: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_compat_lsearch=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_compat_lsearch=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:8675: 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:8678: 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
+#line 8684 "configure"
+#include "confdefs.h"
+#include <search.h>
+_ACEOF
+if { (eval echo "$as_me:8688: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:8694: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_cv_header_search_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_header_search_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:8713: 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 <<\EOF
+#define HAVE_LSEARCH 1
+EOF
+ LIBS="${LIBS} -lcompat"
+else
+  LIBOBJS="$LIBOBJS lsearch.$ac_objext"
+fi
+
+else
+  LIBOBJS="$LIBOBJS lsearch.$ac_objext"
+fi
+
+fi
+done
+
+for ac_func in utime
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8734: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8740 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8771: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8774: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8777: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8780: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8790: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+ echo "$as_me:8796: checking for POSIX utime" >&5
+echo $ECHO_N "checking for POSIX utime... $ECHO_C" >&6
+if test "${sudo_cv_func_utime_posix+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f conftestdata; > conftestdata
+if test "$cross_compiling" = yes; then
+  sudo_cv_func_utime_posix=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8806 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <utime.h>
+main() {
+struct utimbuf ut;
+ut.actime = ut.modtime = time(0);
+utime("conftestdata", &ut);
+exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:8819: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8822: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:8824: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8827: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_func_utime_posix=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+sudo_cv_func_utime_posix=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core core.* *.core
+fi
+echo "$as_me:8840: result: $sudo_cv_func_utime_posix" >&5
+echo "${ECHO_T}$sudo_cv_func_utime_posix" >&6
+if test $sudo_cv_func_utime_posix = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_UTIME_POSIX 1
+EOF
+
+fi
+
+else
+  LIBOBJS="$LIBOBJS utime.$ac_objext"
+fi
+done
+
+echo "$as_me:8855: checking for working fnmatch with FNM_CASEFOLD" >&5
+echo $ECHO_N "checking for working fnmatch with FNM_CASEFOLD... $ECHO_C" >&6
+if test "${sudo_cv_func_fnmatch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f conftestdata; > conftestdata
+if test "$cross_compiling" = yes; then
+  sudo_cv_func_fnmatch=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8865 "configure"
+#include "confdefs.h"
+#include <fnmatch.h>
+main() { exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", FNM_CASEFOLD)); }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:8872: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8875: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:8877: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8880: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_func_fnmatch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+sudo_cv_func_fnmatch=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core core.* *.core
+fi
+echo "$as_me:8893: result: $sudo_cv_func_fnmatch" >&5
+echo "${ECHO_T}$sudo_cv_func_fnmatch" >&6
+if test $sudo_cv_func_fnmatch = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_FNMATCH 1
+EOF
+
+else
+  LIBOBJS="$LIBOBJS fnmatch.$ac_objext"
+fi
+
+echo "$as_me:8905: checking for isblank" >&5
+echo $ECHO_N "checking for isblank... $ECHO_C" >&6
+if test "${sudo_cv_func_isblank+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8911 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+int
+main ()
+{
+(void)isblank(1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8923: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8926: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8929: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:8932: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_func_isblank=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+sudo_cv_func_isblank=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:8942: result: $sudo_cv_func_isblank" >&5
+echo "${ECHO_T}$sudo_cv_func_isblank" >&6
+
+  if test "$sudo_cv_func_isblank" = "yes"; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_ISBLANK 1
+EOF
+
+  fi
+
+for ac_func in strerror strcasecmp sigaction
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:8956: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 8962 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:8993: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:8996: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:8999: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9002: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9012: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+fi
+done
+
+for ac_func in snprintf vsnprintf asprintf vasprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:9027: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9033 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9064: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9067: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9070: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9073: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9083: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<EOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+EOF
+
+else
+  NEED_SNPRINTF=1
+fi
+done
+
+if test -n "$NEED_SNPRINTF"; then
+    LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+fi
+if test -z "$LIB_CRYPT"; then
+    echo "$as_me:9099: checking for crypt" >&5
+echo $ECHO_N "checking for crypt... $ECHO_C" >&6
+if test "${ac_cv_func_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9105 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char crypt (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_crypt) || defined (__stub___crypt)
+choke me
+#else
+f = crypt;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9136: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9139: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9142: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9145: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9155: result: $ac_cv_func_crypt" >&5
+echo "${ECHO_T}$ac_cv_func_crypt" >&6
+if test $ac_cv_func_crypt = yes; then
+  :
+else
+  echo "$as_me:9160: checking for crypt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9168 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9187: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9190: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9193: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9196: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_crypt_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9207: result: $ac_cv_lib_crypt_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6
+if test $ac_cv_lib_crypt_crypt = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -lcrypt"; LIBS="${LIBS} -lcrypt"
+else
+  echo "$as_me:9212: checking for crypt in -lcrypt_d" >&5
+echo $ECHO_N "checking for crypt in -lcrypt_d... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_d_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt_d  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9220 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9239: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9242: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9245: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9248: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_d_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_crypt_d_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9259: result: $ac_cv_lib_crypt_d_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_d_crypt" >&6
+if test $ac_cv_lib_crypt_d_crypt = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -lcrypt_d"; LIBS="${LIBS} -lcrypt_d"
+else
+  echo "$as_me:9264: checking for crypt in -lufc" >&5
+echo $ECHO_N "checking for crypt in -lufc... $ECHO_C" >&6
+if test "${ac_cv_lib_ufc_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lufc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9272 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9291: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9294: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9297: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9300: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ufc_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_ufc_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9311: result: $ac_cv_lib_ufc_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_ufc_crypt" >&6
+if test $ac_cv_lib_ufc_crypt = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -lufc"; LIBS="${LIBS} -lufc"
+fi
+
+fi
+
+fi
+
+fi
+
+fi
+echo "$as_me:9324: checking for socket" >&5
+echo $ECHO_N "checking for socket... $ECHO_C" >&6
+if test "${ac_cv_func_socket+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9330 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char socket (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_socket) || defined (__stub___socket)
+choke me
+#else
+f = socket;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9361: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9364: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9367: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9370: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_socket=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_socket=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9380: result: $ac_cv_func_socket" >&5
+echo "${ECHO_T}$ac_cv_func_socket" >&6
+if test $ac_cv_func_socket = yes; then
+  :
+else
+  echo "$as_me:9385: checking for socket in -lsocket" >&5
+echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_socket+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9393 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+int
+main ()
+{
+socket ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9412: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9415: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9418: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9421: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_socket=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_socket_socket=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9432: result: $ac_cv_lib_socket_socket" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6
+if test $ac_cv_lib_socket_socket = yes; then
+  NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"
+else
+  echo "$as_me:9437: checking for socket in -linet" >&5
+echo $ECHO_N "checking for socket in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_socket+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9445 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+int
+main ()
+{
+socket ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9464: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9467: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9470: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9473: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_socket=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_inet_socket=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9484: result: $ac_cv_lib_inet_socket" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_socket" >&6
+if test $ac_cv_lib_inet_socket = yes; then
+  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
+else
+  { echo "$as_me:9489: WARNING: unable to find socket() trying -lsocket -lnsl" >&5
+echo "$as_me: WARNING: unable to find socket() trying -lsocket -lnsl" >&2;}
+echo "$as_me:9491: checking for socket in -lsocket" >&5
+echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_socket_lnsl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket -lnsl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9499 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+int
+main ()
+{
+socket ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9518: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9521: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9524: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9527: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_socket_lnsl=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_socket_socket_lnsl=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9538: result: $ac_cv_lib_socket_socket_lnsl" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_socket_lnsl" >&6
+if test $ac_cv_lib_socket_socket_lnsl = yes; then
+  NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"
+fi
+
+fi
+
+fi
+
+fi
+
+echo "$as_me:9550: checking for inet_addr" >&5
+echo $ECHO_N "checking for inet_addr... $ECHO_C" >&6
+if test "${ac_cv_func_inet_addr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9556 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char inet_addr (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_addr ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_inet_addr) || defined (__stub___inet_addr)
+choke me
+#else
+f = inet_addr;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9587: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9590: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9593: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9596: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_inet_addr=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_inet_addr=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9606: result: $ac_cv_func_inet_addr" >&5
+echo "${ECHO_T}$ac_cv_func_inet_addr" >&6
+if test $ac_cv_func_inet_addr = yes; then
+  :
+else
+  echo "$as_me:9611: checking for __inet_addr" >&5
+echo $ECHO_N "checking for __inet_addr... $ECHO_C" >&6
+if test "${ac_cv_func___inet_addr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9617 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char __inet_addr (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __inet_addr ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub___inet_addr) || defined (__stub_____inet_addr)
+choke me
+#else
+f = __inet_addr;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9648: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9651: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9654: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9657: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func___inet_addr=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func___inet_addr=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9667: result: $ac_cv_func___inet_addr" >&5
+echo "${ECHO_T}$ac_cv_func___inet_addr" >&6
+if test $ac_cv_func___inet_addr = yes; then
+  :
+else
+  echo "$as_me:9672: checking for inet_addr in -lnsl" >&5
+echo $ECHO_N "checking for inet_addr in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_inet_addr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9680 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_addr ();
+int
+main ()
+{
+inet_addr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9699: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9702: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9705: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9708: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_inet_addr=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_nsl_inet_addr=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9719: result: $ac_cv_lib_nsl_inet_addr" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_inet_addr" >&6
+if test $ac_cv_lib_nsl_inet_addr = yes; then
+  NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"
+else
+  echo "$as_me:9724: checking for inet_addr in -linet" >&5
+echo $ECHO_N "checking for inet_addr in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_inet_addr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9732 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_addr ();
+int
+main ()
+{
+inet_addr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9751: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9754: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9757: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9760: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_inet_addr=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_inet_inet_addr=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9771: result: $ac_cv_lib_inet_inet_addr" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_inet_addr" >&6
+if test $ac_cv_lib_inet_inet_addr = yes; then
+  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
+else
+  { echo "$as_me:9776: WARNING: unable to find inet_addr() trying -lsocket -lnsl" >&5
+echo "$as_me: WARNING: unable to find inet_addr() trying -lsocket -lnsl" >&2;}
+echo "$as_me:9778: checking for inet_addr in -lsocket" >&5
+echo $ECHO_N "checking for inet_addr in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_inet_addr_lnsl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket -lnsl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9786 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_addr ();
+int
+main ()
+{
+inet_addr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9805: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9808: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9811: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9814: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_inet_addr_lnsl=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_socket_inet_addr_lnsl=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9825: result: $ac_cv_lib_socket_inet_addr_lnsl" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_inet_addr_lnsl" >&6
+if test $ac_cv_lib_socket_inet_addr_lnsl = yes; then
+  NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"
+fi
+
+fi
+
+fi
+
+fi
+
+fi
+
+echo "$as_me:9839: checking for syslog" >&5
+echo $ECHO_N "checking for syslog... $ECHO_C" >&6
+if test "${ac_cv_func_syslog+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 9845 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char syslog (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char syslog ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_syslog) || defined (__stub___syslog)
+choke me
+#else
+f = syslog;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9876: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9879: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9882: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9885: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_syslog=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_syslog=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:9895: result: $ac_cv_func_syslog" >&5
+echo "${ECHO_T}$ac_cv_func_syslog" >&6
+if test $ac_cv_func_syslog = yes; then
+  :
+else
+  echo "$as_me:9900: checking for syslog in -lsocket" >&5
+echo $ECHO_N "checking for syslog in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_syslog+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9908 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char syslog ();
+int
+main ()
+{
+syslog ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9927: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9930: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9933: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9936: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_syslog=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_socket_syslog=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9947: result: $ac_cv_lib_socket_syslog" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_syslog" >&6
+if test $ac_cv_lib_socket_syslog = yes; then
+  NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"
+else
+  echo "$as_me:9952: checking for syslog in -lnsl" >&5
+echo $ECHO_N "checking for syslog in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_syslog+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 9960 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char syslog ();
+int
+main ()
+{
+syslog ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:9979: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:9982: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:9985: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:9988: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_syslog=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_nsl_syslog=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:9999: result: $ac_cv_lib_nsl_syslog" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_syslog" >&6
+if test $ac_cv_lib_nsl_syslog = yes; then
+  NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"
+else
+  echo "$as_me:10004: checking for syslog in -linet" >&5
+echo $ECHO_N "checking for syslog in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_syslog+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 10012 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char syslog ();
+int
+main ()
+{
+syslog ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10031: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10034: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10037: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10040: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_syslog=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_inet_syslog=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:10051: result: $ac_cv_lib_inet_syslog" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_syslog" >&6
+if test $ac_cv_lib_inet_syslog = yes; then
+  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
+fi
+
+fi
+
+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:10066: 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
+#line 10072 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10084: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10087: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10090: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10093: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:10103: 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 <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo "$as_me:10113: 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
+#line 10119 "configure"
+#include "confdefs.h"
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if 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);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10151: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10154: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10157: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10160: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:10170: 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 <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+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=alloca.$ac_objext
+
+cat >>confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+echo "$as_me:10191: 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
+#line 10197 "configure"
+#include "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:10215: 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:10220: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line 10226 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+char (*f) ();
+
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10257: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10260: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10263: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10266: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:10276: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:10290: 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 $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
+#line 10299 "configure"
+#include "confdefs.h"
+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 ()
+{
+  exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:10322: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10325: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:10327: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10330: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_stack_direction=1
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_c_stack_direction=-1
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:10342: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+fi
+
+if test "$with_kerb5" = "yes"; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_KERB5 1
+EOF
+
+    if test -f "/usr/local/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+    elif test -f "/usr/local/kerberos/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/kerberos/include"
+    elif test -f "/usr/krb5/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/krb5/include"
+    elif test -f "/usr/local/krb5/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/krb5/include"
+    else
+       echo 'Unable to locate kerberos 5 include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS'
+    fi
+
+    if test -f "/usr/local/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test -f "/usr/local/kerberos/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/kerberos/lib"
+    elif test -f "/usr/krb5/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/krb5/lib"
+    elif test -f "/usr/local/krb5/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/krb5/lib"
+    else
+       echo 'Unable to locate kerberos 5 libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDO_LDFLAGS'
+    fi
+
+    SUDO_LIBS="${SUDO_LIBS} -lkrb5 -lk5crypto -lcom_err"
+    AUTH_OBJS="${AUTH_OBJS} kerb5.o"
+fi
+
+if test "$with_pam" = "yes"; then
+    echo "$as_me:10388: 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
+#line 10396 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10408: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10411: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10414: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10417: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_dl_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:10428: result: $ac_cv_lib_dl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_main" >&6
+if test $ac_cv_lib_dl_main = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -ldl -lpam"
+else
+  SUDO_LIBS="${SUDO_LIBS} -lpam"
+fi
+ac_cv_lib_dl=ac_cv_lib_dl_main
+
+fi
+
+if test "$with_kerb4" = "yes"; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_KERB4 1
+EOF
+
+    if test -f "/usr/include/kerberosIV/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/include/kerberosIV"
+    elif test -f "/usr/local/include/kerberosIV/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include/kerberosIV"
+    elif test -f "/usr/kerberos/include/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/kerberos/include"
+    elif test -f "/usr/local/kerberos/include/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/kerberos/include"
+    else
+       echo 'Unable to locate kerberos 4 include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS'
+    fi
+
+    if test -d "/usr/kerberos/lib"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/kerberos/lib"
+    elif test -d "/usr/lib/kerberos"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/lib/kerberos"
+    elif test -f "/usr/local/lib/libkrb.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test ! -f "/usr/lib/libkrb.a"; then
+       echo 'Unable to locate kerberos 4 libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDO_LDFLAGS'
+    fi
+
+    echo "$as_me:10467: checking for main in -ldes" >&5
+echo $ECHO_N "checking for main in -ldes... $ECHO_C" >&6
+if test "${ac_cv_lib_des_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 10475 "configure"
+#include "confdefs.h"
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10487: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10490: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10493: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10496: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_des_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:10507: result: $ac_cv_lib_des_main" >&5
+echo "${ECHO_T}$ac_cv_lib_des_main" >&6
+if test $ac_cv_lib_des_main = yes; then
+  SUDO_LIBS="${SUDO_LIBS} -lkrb -ldes"
+else
+  SUDO_LIBS="${SUDO_LIBS} -lkrb"
+fi
+ac_cv_lib_des=ac_cv_lib_des_main
+
+    AUTH_OBJS="${AUTH_OBJS} kerb4.o"
+fi
+
+if test "$with_AFS" = "yes"; then
+
+    # looks like the "standard" place for AFS libs is /usr/afsws/lib
+    AFSLIBDIRS="/usr/lib/afs /usr/afsws/lib /usr/afsws/lib/afs"
+    for i in $AFSLIBDIRS; do
+       if test -d ${i}; then
+           SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${i}"
+           FOUND_AFSLIBDIR=true
+       fi
+    done
+    if test -z "$FOUND_AFSLIBDIR"; then
+       echo 'Unable to locate AFS libraries, you will have to edit the Makefile and add -L/path/to/afs/libs to SUDO_LDFLAGS or rerun configure with the --with-libpath options.'
+    fi
+
+    # Order is important here.  Note that we build AFS_LIBS from right to left
+    # since AFS_LIBS may be initialized with BSD compat libs that must go last
+    AFS_LIBS="-laudit ${AFS_LIBS}"
+    for i in $AFSLIBDIRS; do
+       if test -f ${i}/util.a; then
+           AFS_LIBS="${i}/util.a ${AFS_LIBS}"
+           FOUND_UTIL_A=true
+           break;
+       fi
+    done
+    if test -z "$FOUND_UTIL_A"; then
+       AFS_LIBS="-lutil ${AFS_LIBS}"
+    fi
+    AFS_LIBS="-lkauth -lprot -lubik -lauth -lrxkad -lsys -ldes -lrx -llwp -lcom_err ${AFS_LIBS}"
+
+    # AFS includes may live in /usr/include on some machines...
+    for i in /usr/afsws/include; do
+       if test -d ${i}; then
+           CPPFLAGS="${CPPFLAGS} -I${i}"
+           FOUND_AFSINCDIR=true
+       fi
+    done
+
+    if test -z "$FOUND_AFSLIBDIR"; then
+       echo 'Unable to locate AFS include dir, you may have to edit the Makefile and add -I/path/to/afs/includes to CPPFLAGS or rerun configure with the --with-incpath options.'
+    fi
+fi
+
+if test "$with_DCE" = "yes"; then
+    DCE_OBJS="${DCE_OBJS} dce_pwent.o"
+    SUDO_LIBS="${SUDO_LIBS} -ldce"
+fi
+
+if test "$with_skey" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lskey"
+    if test -f /usr/include/skey.h -a -f /usr/lib/libskey.a; then
+       :
+    elif test -f /usr/local/include/skey.h; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test "$with_csops" = "yes" -a -f /tools/cs/skey/include/skey.h -a -f /tools/cs/skey/lib/libskey.a; then
+       CPPFLAGS="${CPPFLAGS} -I/tools/cs/skey/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/tools/cs/skey/lib"
+    else
+       echo 'Unable to locate libskey.a and/or skey.h, you will have to edit the Makefile and add -L/path/to/skey/lib to SUDO_LDFLAGS and/or -I/path/to/skey.h to CPPFLAGS'
+    fi
+    echo "$as_me:10579: checking for skeyaccess in -lskey" >&5
+echo $ECHO_N "checking for skeyaccess in -lskey... $ECHO_C" >&6
+if test "${ac_cv_lib_skey_skeyaccess+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lskey  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line 10587 "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char skeyaccess ();
+int
+main ()
+{
+skeyaccess ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:10606: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:10609: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:10612: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:10615: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_skey_skeyaccess=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_skey_skeyaccess=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:10626: result: $ac_cv_lib_skey_skeyaccess" >&5
+echo "${ECHO_T}$ac_cv_lib_skey_skeyaccess" >&6
+if test $ac_cv_lib_skey_skeyaccess = yes; then
+
+cat >>confdefs.h <<\EOF
+#define HAVE_SKEYACCESS 1
+EOF
+
+fi
+
+fi
+
+if test "$with_opie" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lopie"
+    if test -f /usr/include/opie.h -a -f /usr/lib/libopie.a; then
+       :
+    elif test -f /usr/local/include/opie.h; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    else
+       echo 'Unable to locate libopie.a and/or opie.h, you will have to edit the Makefile and add -L/path/to/opie/lib to SUDO_LDFLAGS and/or -I/path/to/opie.h to CPPFLAGS'
+    fi
+fi
+
+if test -n "$with_SecurID" -a "$with_SecurID" != "no"; then
+    if test "$with_SecurID" != "yes"; then
+       SUDO_LIBS="${SUDO_LIBS} ${with_SecurID}/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I${with_SecurID}"
+    elif test -f /usr/ace/examples/sdiclient.a; then
+       SUDO_LIBS="${SUDO_LIBS} /usr/ace/examples/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I/usr/ace/examples"
+    else
+       SUDO_LIBS="${SUDO_LIBS} /usr/ace/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I/usr/ace"
+    fi
+fi
+
+if test "$with_fwtk" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lauth -lfwall"
+fi
+
+if test "$with_authenticate" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -ls"
+fi
+
+echo "$as_me:10671: checking for log file location" >&5
+echo $ECHO_N "checking for log file location... $ECHO_C" >&6
+if test -n "$with_logpath"; then
+    echo "$as_me:10674: result: $with_logpath" >&5
+echo "${ECHO_T}$with_logpath" >&6
+    cat >>confdefs.h <<EOF
+#define _PATH_SUDO_LOGFILE "$with_logpath"
+EOF
+
+elif test -d "/var/log"; then
+    echo "$as_me:10681: result: /var/log/sudo.log" >&5
+echo "${ECHO_T}/var/log/sudo.log" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/var/log/sudo.log"
+EOF
+
+elif test -d "/var/adm"; then
+    echo "$as_me:10688: result: /var/adm/sudo.log" >&5
+echo "${ECHO_T}/var/adm/sudo.log" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/var/adm/sudo.log"
+EOF
+
+elif test -d "/usr/adm"; then
+    echo "$as_me:10695: result: /usr/adm/sudo.log" >&5
+echo "${ECHO_T}/usr/adm/sudo.log" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/usr/adm/sudo.log"
+EOF
+
+else
+    echo "$as_me:10702: result: unknown" >&5
+echo "${ECHO_T}unknown" >&6
+fi
+
+echo "$as_me:10706: checking for timestamp file location" >&5
+echo $ECHO_N "checking for timestamp file location... $ECHO_C" >&6
+if test -n "$with_timedir"; then
+    echo "$as_me:10709: result: $with_timedir" >&5
+echo "${ECHO_T}$with_timedir" >&6
+    cat >>confdefs.h <<EOF
+#define _PATH_SUDO_TIMEDIR "$with_timedir"
+EOF
+
+    timedir="$with_timedir"
+elif test -d "/var/run"; then
+    echo "$as_me:10717: result: /var/run/sudo" >&5
+echo "${ECHO_T}/var/run/sudo" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_TIMEDIR "/var/run/sudo"
+EOF
+
+    timedir="/var/run/sudo"
+else
+    echo "$as_me:10725: result: /tmp/.odus" >&5
+echo "${ECHO_T}/tmp/.odus" >&6
+    cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_TIMEDIR "/tmp/.odus"
+EOF
+
+    timedir="/tmp/.odus"
+fi
+
+if test "$with_passwd" = "no"; then
+    cat >>confdefs.h <<\EOF
+#define WITHOUT_PASSWD 1. Define to avoid using the passwd/shadow file for authentication.
+EOF
+
+    if test -z "$AUTH_OBJS"; then
+       { { echo "$as_me:10740: error: no authentication methods defined." >&5
+echo "$as_me: error: no authentication methods defined." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+else
+    if test -n "$SECUREWARE"; then
+       AUTH_OBJS="${AUTH_OBJS} passwd.o secureware.o"
+    else
+       AUTH_OBJS="${AUTH_OBJS} passwd.o"
+    fi
+fi
+
+if test -n "$LIBS"; then
+    L="$LIBS"
+    LIBS=
+    for l in ${L}; do
+       dupe=0
+       for sl in ${SUDO_LIBS} ${NET_LIBS}; do
+           test $l = $sl && dupe=1
+       done
+       test $dupe = 0 && LIBS="${LIBS} $l"
+    done
+fi
+
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+ac_config_files="$ac_config_files Makefile sudo.man visudo.man sudoers.man"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overriden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if cmp -s $cache_file confcache; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:10846: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+ac_cs_invocation="\$0 \$@"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Name of the executable.
+as_me=`echo "$0" |sed 's,.*[\\/],,'`
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+# NLS nuisances.
+$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; }
+$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; }
+$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; }
+$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; }
+$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; }
+$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; }
+$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; }
+$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; }
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; }
+
+exec 6>&1
+
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\EOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+EOF
+
+cat >>$CONFIG_STATUS <<EOF
+ac_cs_version="\\
+sudo config.status 1.6.6
+configured by $0, generated by GNU Autoconf 2.52,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+EOF
+
+cat >>$CONFIG_STATUS <<\EOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    shift
+    set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+    shift
+    ;;
+  -*);;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_need_defaults=false;;
+  esac
+
+  case $1 in
+  # Handling of the options.
+EOF
+cat >>$CONFIG_STATUS <<EOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
+    exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
+EOF
+cat >>$CONFIG_STATUS <<\EOF
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:11018: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    shift
+    CONFIG_FILES="$CONFIG_FILES $1"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $1"
+    ac_need_defaults=false;;
+
+  # This is an error.
+  -*) { { echo "$as_me:11037: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+exec 5>>config.log
+cat >&5 << _ACEOF
+
+## ----------------------- ##
+## Running config.status.  ##
+## ----------------------- ##
+
+This file was extended by $as_me (sudo 1.6.6) 2.52, executed with
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  > $ac_cs_invocation
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+
+_ACEOF
+EOF
+
+cat >>$CONFIG_STATUS <<\EOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "sudo.man" ) CONFIG_FILES="$CONFIG_FILES sudo.man" ;;
+  "visudo.man" ) CONFIG_FILES="$CONFIG_FILES visudo.man" ;;
+  "sudoers.man" ) CONFIG_FILES="$CONFIG_FILES sudoers.man" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  "pathnames.h" ) CONFIG_HEADERS="$CONFIG_HEADERS pathnames.h" ;;
+  *) { { echo "$as_me:11078: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+  tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=$TMPDIR/cs$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+   { (exit 1); exit 1; }
+}
+
+EOF
+
+cat >>$CONFIG_STATUS <<EOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@DEFS@,$DEFS,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@PROGS@,$PROGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@SUDO_LDFLAGS@,$SUDO_LDFLAGS,;t t
+s,@SUDO_LIBS@,$SUDO_LIBS,;t t
+s,@NET_LIBS@,$NET_LIBS,;t t
+s,@AFS_LIBS@,$AFS_LIBS,;t t
+s,@OSDEFS@,$OSDEFS,;t t
+s,@AUTH_OBJS@,$AUTH_OBJS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@MANTYPE@,$MANTYPE,;t t
+s,@MAN_POSTINSTALL@,$MAN_POSTINSTALL,;t t
+s,@SUDOERS_MODE@,$SUDOERS_MODE,;t t
+s,@SUDOERS_UID@,$SUDOERS_UID,;t t
+s,@SUDOERS_GID@,$SUDOERS_GID,;t t
+s,@DEV@,$DEV,;t t
+s,@mansectsu@,$mansectsu,;t t
+s,@mansectform@,$mansectform,;t t
+s,@mansrcdir@,$mansrcdir,;t t
+s,@timedir@,$timedir,;t t
+s,@timeout@,$timeout,;t t
+s,@password_timeout@,$password_timeout,;t t
+s,@sudo_umask@,$sudo_umask,;t t
+s,@passprompt@,$passprompt,;t t
+s,@long_otp_prompt@,$long_otp_prompt,;t t
+s,@lecture@,$lecture,;t t
+s,@logfac@,$logfac,;t t
+s,@goodpri@,$goodpri,;t t
+s,@badpri@,$badpri,;t t
+s,@loglen@,$loglen,;t t
+s,@ignore_dot@,$ignore_dot,;t t
+s,@mail_no_user@,$mail_no_user,;t t
+s,@mail_no_host@,$mail_no_host,;t t
+s,@mail_no_perms@,$mail_no_perms,;t t
+s,@mailto@,$mailto,;t t
+s,@mailsub@,$mailsub,;t t
+s,@badpass_message@,$badpass_message,;t t
+s,@fqdn@,$fqdn,;t t
+s,@runas_default@,$runas_default,;t t
+s,@env_editor@,$env_editor,;t t
+s,@passwd_tries@,$passwd_tries,;t t
+s,@tty_tickets@,$tty_tickets,;t t
+s,@insults@,$insults,;t t
+s,@EGREPPROG@,$EGREPPROG,;t t
+s,@CC@,$CC,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@UNAMEPROG@,$UNAMEPROG,;t t
+s,@TRPROG@,$TRPROG,;t t
+s,@SEDPROG@,$SEDPROG,;t t
+s,@NROFFPROG@,$NROFFPROG,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@YACC@,$YACC,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+CEOF
+
+EOF
+
+  cat >>$CONFIG_STATUS <<\EOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+EOF
+cat >>$CONFIG_STATUS <<\EOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    { case "$ac_dir" in
+  [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+  *)                      as_incr_dir=.;;
+esac
+as_dummy="$ac_dir"
+for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+  case $as_mkdir_dir in
+    # Skip DOS drivespec
+    ?:) as_incr_dir=$as_mkdir_dir ;;
+    *)
+      as_incr_dir=$as_incr_dir/$as_mkdir_dir
+      test -d "$as_incr_dir" || mkdir "$as_incr_dir"
+    ;;
+  esac
+done; }
+
+    ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case $srcdir in
+  .)  ac_srcdir=.
+      if test -z "$ac_dots"; then
+         ac_top_srcdir=.
+      else
+         ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'`
+      fi ;;
+  [\\/]* | ?:[\\/]* )
+      ac_srcdir=$srcdir$ac_dir_suffix;
+      ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_dots$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_dots$srcdir ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:11332: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated automatically by config.status.  */
+  configure_input="Generated automatically from `echo $ac_file_in |
+                                                 sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:11350: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:11363: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+EOF
+cat >>$CONFIG_STATUS <<EOF
+  sed "$ac_vpsub
+$extrasub
+EOF
+cat >>$CONFIG_STATUS <<\EOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+EOF
+cat >>$CONFIG_STATUS <<\EOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:11423: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:11434: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:11447: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[     ]*$//' $ac_file_inputs >$tmp/in
+
+EOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\EOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\(\([^        (][^    (]*\)([^)]*)\)[         ]*\(.*\)$,${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD},gp
+t end
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+EOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\EOF
+s,^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+EOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if egrep "^[   ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[    ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # egrep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[    ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\EOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated automatically by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated automatically by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated automatically by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
+      { echo "$as_me:11564: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+        { case "$ac_dir" in
+  [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+  *)                      as_incr_dir=.;;
+esac
+as_dummy="$ac_dir"
+for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+  case $as_mkdir_dir in
+    # Skip DOS drivespec
+    ?:) as_incr_dir=$as_mkdir_dir ;;
+    *)
+      as_incr_dir=$as_incr_dir/$as_mkdir_dir
+      test -d "$as_incr_dir" || mkdir "$as_incr_dir"
+    ;;
+  esac
+done; }
+
+      fi
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+EOF
+
+cat >>$CONFIG_STATUS <<\EOF
+
+{ (exit 0); exit 0; }
+EOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+if test "$with_pam" = "yes"; then
+    echo ""
+    case $host in
+       *-*-linux*)
+           echo "You will need to customize sample.pam and install it as /etc/pam.d/sudo"
+           ;;
+    esac
+    echo ""
+fi
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..9a818ff
--- /dev/null
@@ -0,0 +1,1952 @@
+dnl
+dnl Process this file with GNU autoconf to produce a configure script.
+dnl $Sudo: configure.in,v 1.349 2002/04/18 15:41:30 millert Exp $
+dnl
+dnl Copyright (c) 1994-1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl
+AC_INIT(sudo, 1.6.6)
+AC_CONFIG_HEADER(config.h pathnames.h)
+dnl
+dnl This won't work before AC_INIT()
+dnl
+echo "Configuring Sudo version 1.6.6"
+dnl
+dnl Variables that get substituted in the Makefile and man pages
+dnl
+AC_SUBST(CFLAGS)dnl
+AC_SUBST(PROGS)dnl
+AC_SUBST(CPPFLAGS)dnl
+AC_SUBST(LDFLAGS)dnl
+AC_SUBST(SUDO_LDFLAGS)dnl
+AC_SUBST(LIBS)dnl
+AC_SUBST(SUDO_LIBS)dnl
+AC_SUBST(NET_LIBS)dnl
+AC_SUBST(AFS_LIBS)dnl
+AC_SUBST(OSDEFS)dnl
+AC_SUBST(AUTH_OBJS)dnl
+AC_SUBST(LIBOBJS)dnl
+AC_SUBST(MANTYPE)dnl
+AC_SUBST(MAN_POSTINSTALL)dnl
+AC_SUBST(SUDOERS_MODE)dnl
+AC_SUBST(SUDOERS_UID)dnl
+AC_SUBST(SUDOERS_GID)dnl
+AC_SUBST(DEV)
+AC_SUBST(mansectsu)
+AC_SUBST(mansectform)
+AC_SUBST(mansrcdir)
+dnl
+dnl Variables that get substituted in docs (not overridden by environment)
+dnl
+AC_SUBST(timedir)dnl initial value from SUDO_TIMEDIR
+AC_SUBST(timeout)
+AC_SUBST(password_timeout)
+AC_SUBST(sudo_umask)
+AC_SUBST(passprompt)
+AC_SUBST(long_otp_prompt)
+AC_SUBST(lecture)
+AC_SUBST(logfac)
+AC_SUBST(goodpri)
+AC_SUBST(badpri)
+AC_SUBST(loglen)
+AC_SUBST(ignore_dot)
+AC_SUBST(mail_no_user)
+AC_SUBST(mail_no_host)
+AC_SUBST(mail_no_perms)
+AC_SUBST(mailto)
+AC_SUBST(mailsub)
+AC_SUBST(badpass_message)
+AC_SUBST(fqdn)
+AC_SUBST(runas_default)
+AC_SUBST(env_editor)
+AC_SUBST(passwd_tries)
+AC_SUBST(tty_tickets)
+AC_SUBST(insults)
+dnl
+dnl Initial values for above
+dnl
+timeout=5
+password_timeout=5
+sudo_umask=0022
+passprompt="Password:"
+long_otp_prompt=off
+lecture=on
+logfac=local2
+goodpri=notice
+badpri=alert
+loglen=80
+ignore_dot=off
+mail_no_user=on
+mail_no_host=off
+mail_no_perms=off
+mailto=root
+mailsub='*** SECURITY information for %h ***'
+badpass_message='Sorry, try again.'
+fqdn=off
+runas_default=root
+env_editor=off
+passwd_tries=3
+tty_tickets=off
+insults=off
+dnl
+dnl Initial values for Makefile variables listed above
+dnl May be overridden by environment variables..
+dnl
+PROGS="sudo visudo"
+test -n "$MANTYPE" || MANTYPE="man"
+test -n "$mansrcdir" || mansrcdir="."
+test -n "$SUDOERS_MODE" || SUDOERS_MODE=0440
+test -n "$SUDOERS_UID" || SUDOERS_UID=0
+test -n "$SUDOERS_GID" || SUDOERS_GID=0
+DEV="#"
+
+dnl
+dnl Other vaiables
+dnl
+CHECKSHADOW=true
+CHECKSIA=true
+
+dnl
+dnl Override default configure dirs...
+dnl
+test "$mandir" = '${prefix}/man' && mandir='$(prefix)/man'
+test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
+test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
+test "$sysconfdir" = '${prefix}/etc' && sysconfdir='/etc'
+
+dnl
+dnl Deprecated --with options (these all warn or generate an error)
+dnl
+
+AC_ARG_WITH(otp-only, [  --with-otp-only         deprecated],
+[case $with_otp_only in
+    yes)       with_passwd=no
+               AC_DEFINE(WITHOUT_PASSWD, 1, [Define to avoid using the passwd/shadow file for authentication.])
+               AC_MSG_WARN([--with-otp-only option deprecated, treating as --without-passwd])
+               ;;
+esac])
+
+AC_ARG_WITH(alertmail, [  --with-alertmail        deprecated],
+[case $with_alertmail in
+    *)         with_mailto="$with_alertmail"
+               AC_MSG_WARN([--with-alertmail option deprecated, treating as --mailto])
+               ;;
+esac])
+
+dnl
+dnl Options for --with
+dnl
+
+AC_ARG_WITH(CC, [  --with-CC               C compiler to use],
+[case $with_CC in
+    yes)       AC_MSG_ERROR(["must give --with-CC an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["illegal argument: --without-CC."])
+               ;;
+    *)         CC=$with_CC
+               ;;
+esac])
+
+AC_ARG_WITH(incpath, [  --with-incpath          additional places to look for include files],
+[case $with_incpath in  
+    yes)       AC_MSG_ERROR(["must give --with-incpath an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-incpath not supported."])
+               ;;
+    *)         echo "Adding ${with_incpath} to CPPFLAGS"
+               for i in ${with_incpath}; do
+                   CPPFLAGS="${CPPFLAGS} -I${i}"
+               done
+               ;;
+esac])
+
+AC_ARG_WITH(libpath, [  --with-libpath          additional places to look for libraries],
+[case $with_libpath in  
+    yes)       AC_MSG_ERROR(["must give --with-libpath an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-libpath not supported."])
+               ;;
+    *)         echo "Adding ${with_libpath} to LDFLAGS"
+               for i in ${with_libpath}; do
+                   LDFLAGS="${LDFLAGS} -L${i}"
+               done
+               ;;
+esac])
+
+AC_ARG_WITH(libraries, [  --with-libraries        additional libraries to link with],
+[case $with_libraries in  
+    yes)       AC_MSG_ERROR(["must give --with-libraries an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-libraries not supported."])
+               ;;
+    *)         echo "Adding ${with_libraries} to LIBS"
+               for i in ${with_libraries}; do
+                   case $i in
+                       -l*)    ;;
+                       *.a)    ;;
+                       *.o)    ;;
+                       *)      i="-l${i}";;
+                   esac
+                   LIBS="${LIBS} ${i}"
+               done
+               ;;
+esac])
+
+AC_ARG_WITH(devel, [  --with-devel            add developement options],
+[case $with_devel in  
+    yes)       echo 'Setting up for developement: -Wall, flex, yacc'
+               PROGS="${PROGS} testsudoers"
+               OSDEFS="${OSDEFS} -DSUDO_DEVEL"
+               DEV=""
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-devel: $with_devel"
+               ;;
+esac])
+
+AC_ARG_WITH(efence, [  --with-efence           link with -lefence for malloc() debugging],
+[case $with_efence in  
+    yes)       echo 'Sudo will link with -lefence (Electric Fence)'
+               LIBS="${LIBS} -lefence"
+               if test -f /usr/local/lib/libefence.a; then
+                   LDFLAGS="${LDFLAGS} -L/usr/local/lib"
+               fi
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-efence: $with_efence"
+               ;;
+esac])
+
+AC_ARG_WITH(csops, [  --with-csops            add CSOps standard options],
+[case $with_csops in  
+    yes)       echo 'Adding CSOps standard options'
+               CHECKSIA=false
+               with_ignore_dot=yes
+               insults=on
+               with_classic_insults=yes
+               with_csops_insults=yes
+               with_env_editor=yes
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-csops: $with_csops"
+               ;;
+esac])
+
+AC_ARG_WITH(passwd, [  --without-passwd        don't use passwd/shadow file for authentication],
+[case $with_passwd in
+    yes)       ;;
+    no)                AC_DEFINE(WITHOUT_PASSWD)
+               AC_MSG_CHECKING(whether to use shadow/passwd file authentication)
+               AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_ERROR(["Sorry, --with-passwd does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(skey, [  --with-skey             enable S/Key support ],
+[case $with_skey in
+    yes)       if test -n "$with_opie"; then
+                   AC_MSG_ERROR(["cannot use both S/Key and OPIE"])
+               fi
+               AC_DEFINE(HAVE_SKEY, 1, [Define if you use S/Key.])
+               AC_MSG_CHECKING(whether to try S/Key authentication)
+               AC_MSG_RESULT(yes)
+               AUTH_OBJS="${AUTH_OBJS} rfc1938.o"
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-skey: $with_skey"
+               ;;
+esac])
+
+AC_ARG_WITH(opie, [  --with-opie             enable OPIE support ],
+[case $with_opie in
+    yes)       if test -n "$with_skey"; then
+                   AC_MSG_ERROR(["cannot use both S/Key and OPIE"])
+               fi
+               AC_DEFINE(HAVE_OPIE, 1, [Define if you use NRL OPIE.])
+               AC_MSG_CHECKING(whether to try NRL OPIE authentication)
+               AC_MSG_RESULT(yes)
+               AUTH_OBJS="${AUTH_OBJS} rfc1938.o"
+               ;;
+    no)                ;;
+    *)         echo "Ignoring unknown argument to --with-opie: $with_opie"
+               ;;
+esac])
+
+AC_ARG_WITH(long-otp-prompt, [  --with-long-otp-prompt  use a two line OTP (skey/opie) prompt],
+[case $with_long_otp_prompt in
+    yes)       AC_DEFINE(LONG_OTP_PROMPT, 1, [Define if you want a two line OTP (S/Key or OPIE) prompt.])
+               AC_MSG_CHECKING(whether to use a two line prompt for OTP authentication)
+               AC_MSG_RESULT(yes)
+               long_otp_prompt=on
+               ;;
+    no)                long_otp_prompt=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-long-otp-prompt does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(SecurID, [  --with-SecurID          enable SecurID support],
+[case $with_SecurID in
+    no)                ;;
+    *)         AC_DEFINE(HAVE_SECURID, 1, [Define if you use SecurID.])
+               AC_MSG_CHECKING(whether to use SecurID for authentication)
+               AC_MSG_RESULT(yes)
+               with_passwd=no
+               AUTH_OBJS="securid.o"
+               ;;
+esac])
+
+AC_ARG_WITH(fwtk, [  --with-fwtk             enable FWTK AuthSRV support],
+[case $with_fwtk in
+    no)                ;;
+    *)         AC_DEFINE(HAVE_FWTK, 1, [Define if you use the FWTK authsrv daemon.])
+               AC_MSG_CHECKING(whether to use FWTK AuthSRV for authentication)
+               AC_MSG_RESULT(yes)
+               with_passwd=no
+               AUTH_OBJS="fwtk.o"
+               if test "$with_fwtk" != "yes"; then
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${with_fwtk}"
+                   CPPFLAGS="${CPPFLAGS} -I${with_fwtk}"
+                   with_fwtk=yes
+               fi
+               ;;
+esac])
+
+AC_ARG_WITH(kerb4, [  --with-kerb4            enable kerberos v4 support],
+[case $with_kerb4 in
+    yes)       AC_MSG_CHECKING(whether to try Kerberos 4 authentication)
+               AC_MSG_RESULT(yes)
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-kerb4 does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(kerb5, [  --with-kerb5            enable kerberos v5 support],
+[case $with_kerb5 in
+    yes)       AC_MSG_CHECKING(whether to try Kerberos 5 authentication)
+               AC_MSG_RESULT(yes)
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-kerb5 does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(authenticate, [  --with-authenticate     enable AIX general authentication support],
+[case $with_authenticate in
+    yes)       AC_DEFINE(HAVE_AUTHENTICATE, 1, [Define if you use AIX general authentication.])
+               AC_MSG_CHECKING(whether to use AIX general authentication)
+               AC_MSG_RESULT(yes)
+               with_passwd=no
+               AUTH_OBJS="aix_auth.o"
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-authenticate does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(pam, [  --with-pam              enable PAM support],
+[case $with_pam in
+    yes)       AC_DEFINE(HAVE_PAM, 1, [Define if you use PAM.])
+               AC_MSG_CHECKING(whether to use PAM authentication)
+               AC_MSG_RESULT(yes)
+               with_passwd=no
+               AUTH_OBJS="pam.o"
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-pam does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(AFS, [  --with-AFS              enable AFS support],
+[case $with_AFS in
+    yes)       AC_DEFINE(HAVE_AFS, 1, [Define if you use AFS.])
+               AC_MSG_CHECKING(whether to try AFS (kerberos) authentication)
+               AC_MSG_RESULT(yes)
+               AUTH_OBJS="${AUTH_OBJS} afs.o"
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-AFS does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(DCE, [  --with-DCE              enable DCE support],
+[case $with_DCE in
+    yes)       AC_DEFINE(HAVE_DCE, 1, [Define if you use OSF DCE.])
+               AC_MSG_CHECKING(whether to try DCE (kerberos) authentication)
+               AC_MSG_RESULT(yes)
+               AUTH_OBJS="${AUTH_OBJS} dce.o"
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-DCE does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(logincap, [  --with-logincap         enable BSD login class support],
+[case $with_logincap in
+    yes|no)    ;;
+    *)         AC_MSG_ERROR(["--with-logincap does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(bsdauth, [  --with-bsdauth          enable BSD authentication support],
+[case $with_bsdauth in
+    yes)       with_logincap=yes
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-bsdauth does not take an argument."])
+               ;;
+esac])
+
+AC_MSG_CHECKING(whether to lecture users the first time they run sudo)
+AC_ARG_WITH(lecture, [  --without-lecture       don't print lecture for first-time sudoer],
+[case $with_lecture in  
+    yes|short) lecture=on
+               ;;
+    no|none)   lecture=off
+               ;;
+    *)         AC_MSG_ERROR(["unknown argument to --with-lecture: $with_lecture"])
+               ;;
+esac])
+if test "$lecture" = "on"; then
+    AC_MSG_RESULT(yes)
+else
+    AC_DEFINE(NO_LECTURE, 1, [Define if you don't want users to get the lecture the first they user sudo.])
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether sudo should log via syslog or to a file by default)
+AC_ARG_WITH(logging, [  --with-logging          log via syslog, file, or both],
+[case $with_logging in  
+    yes)       AC_MSG_ERROR(["must give --with-logging an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-logging not supported."])
+               ;;
+    syslog)    AC_DEFINE(LOGGING, SLOG_SYSLOG, [Define to SLOG_SYSLOG, SLOG_FILE, or SLOG_BOTH.])
+               AC_MSG_RESULT(syslog)
+               ;;
+    file)      AC_DEFINE(LOGGING, SLOG_FILE)
+               AC_MSG_RESULT(file)
+               ;;
+    both)      AC_DEFINE(LOGGING, SLOG_BOTH)
+               AC_MSG_RESULT(both)
+               ;;
+    *)         AC_MSG_ERROR(["unknown argument to --with-logging: $with_logging"])
+               ;;
+esac], [AC_DEFINE(LOGGING, SLOG_SYSLOG) AC_MSG_RESULT(syslog)])
+
+AC_MSG_CHECKING(which syslog facility sudo should log with)
+AC_ARG_WITH(logfac, [  --with-logfac           syslog facility to log with (default is "local2")],
+[case $with_logfac in  
+    yes)       AC_MSG_ERROR(["must give --with-logfac an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-logfac not supported."])
+               ;;
+    authpriv|auth|daemon|user|local0|local1|local2|local3|local4|local5|local6|local7)         logfac=$with_logfac
+               ;;
+    *)         AC_MSG_ERROR(["$with_logfac is not a supported syslog facility."])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(LOGFAC, "$logfac", [The syslog facility sudo will use.])
+AC_MSG_RESULT($logfac)
+
+AC_MSG_CHECKING(at which syslog priority to log commands)
+AC_ARG_WITH(goodpri, [  --with-goodpri          syslog priority for commands (def is "notice")],
+[case $with_goodpri in  
+    yes)       AC_MSG_ERROR(["must give --with-goodpri an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-goodpri not supported."])
+               ;;
+    alert|crit|debug|emerg|err|info|notice|warning)
+               goodpri=$with_goodpri
+               ;;
+    *)         AC_MSG_ERROR(["$with_goodpri is not a supported syslog priority."])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(PRI_SUCCESS, "$goodpri", [The syslog priority sudo will use for successful attempts.])
+AC_MSG_RESULT($goodpri)
+
+AC_MSG_CHECKING(at which syslog priority to log failures)
+AC_ARG_WITH(badpri, [  --with-badpri           syslog priority for failures (def is "alert")],
+[case $with_badpri in  
+    yes)       AC_MSG_ERROR(["must give --with-badpri an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-badpri not supported."])
+               ;;
+    alert|crit|debug|emerg|err|info|notice|warning)
+               badpri=$with_badpri
+               ;;
+    *)         AC_MSG_ERROR([$with_badpri is not a supported syslog priority.])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(PRI_FAILURE, "$badpri", [The syslog priority sudo will use for unsuccessful attempts/errors.])
+AC_MSG_RESULT(badpri)
+
+AC_ARG_WITH(logpath, [  --with-logpath          path to the sudo log file],
+[case $with_logpath in  
+    yes)       AC_MSG_ERROR(["must give --with-logpath an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-logpath not supported."])
+               ;;
+esac])
+
+AC_MSG_CHECKING(how long a line in the log file should be)
+AC_ARG_WITH(loglen, [  --with-loglen           maximum length of a log file line (default is 80)],
+[case $with_loglen in  
+    yes)       AC_MSG_ERROR(["must give --with-loglen an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-loglen not supported."])
+               ;;
+    [[0-9]]*)  loglen=$with_loglen
+               ;;
+    *)         AC_MSG_ERROR(["you must enter a number, not $with_loglen"])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(MAXLOGFILELEN, $loglen, [The max number of chars per log file line (for line wrapping).])
+AC_MSG_RESULT($loglen)
+
+AC_MSG_CHECKING(whether sudo should ignore '.' or '' in \$PATH)
+AC_ARG_WITH(ignore-dot, [  --with-ignore-dot       ignore '.' in the PATH],
+[case $with_ignore_dot in  
+    yes)       ignore_dot=on
+               ;;
+    no)                ignore_dot=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-ignore-dot does not take an argument."])
+               ;;
+esac])
+if test "$ignore_dot" = "on"; then
+    AC_DEFINE(IGNORE_DOT_PATH, 1, [Define if you want to ignore '.' and empty \$PATH elements])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when a user is not in sudoers)
+AC_ARG_WITH(mail-if-no-user, [  --without-mail-if-no-user do not send mail if user not in sudoers],
+[case $with_mail_if_no_user in  
+    yes)       mail_no_user=on
+               ;;
+    no)                mail_no_user=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-mail-if-no-user does not take an argument."])
+               ;;
+esac])
+if test "$mail_no_user" = "on"; then
+    AC_DEFINE(SEND_MAIL_WHEN_NO_USER, 1, [Define to send mail when the user is not in the sudoers file.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when user listed but not for this host)
+AC_ARG_WITH(mail-if-no-host, [  --with-mail-if-no-host  send mail if user in sudoers but not for this host],
+[case $with_mail_if_no_host in  
+    yes)       mail_no_host=on
+               ;;
+    no)                mail_no_host=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-mail-if-no-host does not take an argument."])
+               ;;
+esac])
+if test "$mail_no_host" = "on"; then
+    AC_DEFINE(SEND_MAIL_WHEN_NO_HOST, 1, [Define to send mail when the user is not not allowed to run sudo on this host.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when a user tries a disallowed command)
+AC_ARG_WITH(mail-if-noperms, [  --with-mail-if-noperms  send mail if user not allowed to run command],
+[case $with_mail_if_noperms in  
+    yes)       mail_noperms=on
+               ;;
+    no)                mail_noperms=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-mail-if-noperms does not take an argument."])
+               ;;
+esac])
+if test "$mail_noperms" = "on"; then
+    AC_DEFINE(SEND_MAIL_WHEN_NOT_OK, 1, [Define to send mail when the user is not not allowed to run a command.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(who should get the mail that sudo sends)
+AC_ARG_WITH(mailto, [  --with-mailto           who should get sudo mail (default is "root")],
+[case $with_mailto in  
+    yes)       AC_MSG_ERROR(["must give --with-mailto an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-mailto not supported."])
+               ;;
+    *)         mailto=$with_mailto
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(MAILTO, "$mailto", [The user or email address that sudo mail is sent to.])
+AC_MSG_RESULT([$mailto])
+
+AC_ARG_WITH(mailsubject, [  --with-mailsubject      subject of sudo mail],
+[case $with_mailsubject in  
+    yes)       AC_MSG_ERROR(["must give --with-mailsubject an argument."])
+               ;;
+    no)                echo "Sorry, --without-mailsubject not supported."
+               ;;
+    *)         mailsub="$with_mailsubject"
+               AC_MSG_CHECKING(sudo mail subject)
+               AC_MSG_RESULT([Using alert mail subject: $mailsub])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(MAILSUBJECT, "$mailsub", [The subject of the mail sent by sudo to the MAILTO user/address.])
+
+AC_MSG_CHECKING(for bad password prompt)
+AC_ARG_WITH(passprompt, [  --with-passprompt       default password prompt],
+[case $with_passprompt in  
+    yes)       AC_MSG_ERROR(["must give --with-passprompt an argument."])
+               ;;
+    no)                echo "Sorry, --without-passprompt not supported."
+               ;;
+    *)         passprompt="$with_passprompt"
+esac])
+AC_MSG_RESULT($passprompt)
+AC_DEFINE_UNQUOTED(PASSPROMPT, "$passprompt", [The default password prompt.])
+
+AC_MSG_CHECKING(for bad password message)
+AC_ARG_WITH(badpass-message, [  --with-badpass-message  message the user sees when the password is wrong],
+[case $with_badpass_message in  
+    yes)       AC_MSG_ERROR(["Must give --with-badpass-message an argument."])
+               ;;
+    no)                echo "Sorry, --without-badpass-message not supported."
+               ;;
+    *)         badpass_message="$with_badpass_message"
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(INCORRECT_PASSWORD, "$badpass_message", [The message given when a bad password is entered.])
+AC_MSG_RESULT([$badpass_message])
+
+AC_MSG_CHECKING(whether to expect fully qualified hosts in sudoers)
+AC_ARG_WITH(fqdn, [  --with-fqdn             expect fully qualified hosts in sudoers],
+[case $with_fqdn in  
+    yes)       fqdn=on
+               ;;
+    no)                fqdn=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-fqdn does not take an argument."])
+               ;;
+esac])
+if test "$fqdn" = "on"; then
+    AC_DEFINE(FQDN, 1, [Define if you want to require fully qualified hosts in sudoers.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_ARG_WITH(timedir, [  --with-timedir          path to the sudo timestamp dir],
+[case $with_timedir in  
+    yes)       AC_MSG_ERROR(["must give --with-timedir an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-timedir not supported."])
+               ;;
+esac])
+
+AC_ARG_WITH(sendmail, [  --with-sendmail=path    set path to sendmail
+  --without-sendmail      do not send mail at all],
+[case $with_sendmail in  
+    yes)       with_sendmail=""
+               ;;
+    no)                ;;
+    *)         SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SENDMAIL, "$with_sendmail")
+               ;;
+esac])
+
+AC_ARG_WITH(sudoers-mode, [  --with-sudoers-mode     mode of sudoers file (defaults to 0440)],
+[case $with_sudoers_mode in  
+    yes)       AC_MSG_ERROR(["must give --with-sudoers-mode an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-sudoers-mode not supported."])
+               ;;
+    [[1-9]]*)  SUDOERS_MODE=0${with_sudoers_mode}
+               ;;
+    0*)                SUDOERS_MODE=$with_sudoers_mode
+               ;;
+    *)         AC_MSG_ERROR(["you must use a numeric uid, not a name."])
+               ;;
+esac])
+
+AC_ARG_WITH(sudoers-uid, [  --with-sudoers-uid      uid that owns sudoers file (defaults to 0)],
+[case $with_sudoers_uid in  
+    yes)       AC_MSG_ERROR(["must give --with-sudoers-uid an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-sudoers-uid not supported."])
+               ;;
+    [[0-9]]*)  SUDOERS_UID=$with_sudoers_uid
+               ;;
+    *)         AC_MSG_ERROR(["you must use a numeric uid, not a name."])
+               ;;
+esac])
+
+AC_ARG_WITH(sudoers-gid, [  --with-sudoers-gid      gid that owns sudoers file (defaults to 0)],
+[case $with_sudoers_gid in  
+    yes)       AC_MSG_ERROR(["must give --with-sudoers-gid an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-sudoers-gid not supported."])
+               ;;
+    [[0-9]]*)  SUDOERS_GID=$with_sudoers_gid
+               ;;
+    *)         AC_MSG_ERROR(["you must use a numeric gid, not a name."])
+               ;;
+esac])
+
+AC_MSG_CHECKING(for umask programs should be run with)
+AC_ARG_WITH(umask, [  --with-umask            umask with which the prog should run (default is 022)
+  --without-umask         Preserves the umask of the user invoking sudo.],
+[case $with_umask in  
+    yes)       AC_MSG_ERROR(["must give --with-umask an argument."])
+               ;;
+    no)                sudo_umask=0777
+               ;;
+    [[0-9]]*)  sudo_umask=$with_umask
+               ;;
+    *)         AC_MSG_ERROR(["you must enter a numeric mask."])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(SUDO_UMASK, $sudo_umask, [The umask that the root-run prog should use.])
+if test "$sudo_umask" = "0777"; then
+    AC_MSG_RESULT(user)
+else
+    AC_MSG_RESULT($sudo_umask)
+fi
+
+AC_MSG_CHECKING(for default user to run commands as)
+AC_ARG_WITH(runas-default, [  --with-runas-default    User to run commands as (default is "root")],
+[case $with_runas_default in  
+    yes)       AC_MSG_ERROR(["must give --with-runas-default an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-runas-default not supported."])
+               ;;
+    *)         runas_default="$with_runas_default"
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(RUNAS_DEFAULT, "$runas_default", [The user sudo should run commands as by default.])
+AC_MSG_RESULT([$runas_default])
+
+AC_ARG_WITH(exempt, [  --with-exempt=group     no passwd needed for users in this group],
+[case $with_exempt in  
+    yes)       AC_MSG_ERROR(["must give --with-exempt an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-exempt not supported."])
+               ;;
+    *)         AC_DEFINE_UNQUOTED(EXEMPTGROUP, "$with_exempt", [If defined, users in this group need not enter a passwd (ie "sudo").])
+               AC_MSG_CHECKING(for group to be exempt from password)
+               AC_MSG_RESULT([$with_exempt])
+               ;;
+esac])
+
+AC_MSG_CHECKING(for editor that visudo should use)
+AC_ARG_WITH(editor, [  --with-editor=path      Default editor for visudo (defaults to vi)],
+[case $with_editor in  
+    yes)       AC_MSG_ERROR(["must give --with-editor an argument."])
+               ;;
+    no)                AC_MSG_ERROR(["--without-editor not supported."])
+               ;;
+    *)         AC_DEFINE_UNQUOTED(EDITOR, "$with_editor", [A colon-separated list of pathnames to be used as the editor for visudo.])
+               AC_MSG_RESULT([$with_editor])
+               ;;
+esac], [AC_DEFINE(EDITOR, _PATH_VI) AC_MSG_RESULT(vi)])
+
+AC_MSG_CHECKING(whether to obey EDITOR and VISUAL environment variables)
+AC_ARG_WITH(env-editor, [  --with-env-editor       Use the environment variable EDITOR for visudo],
+[case $with_env_editor in  
+    yes)       env_editor=on
+               ;;
+    no)                env_editor=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-env-editor does not take an argument."])
+               ;;
+esac])
+if test "$env_editor" = "on"; then
+    AC_DEFINE(ENV_EDITOR, 1, [Define if you want visudo to honor the EDITOR and VISUAL env variables.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(number of tries a user gets to enter their password)
+AC_ARG_WITH(passwd-tries, [  --with-passwd-tries     number of tries to enter password (default is 3)],
+[case $with_passwd_tries in  
+    yes)       ;;
+    no)                AC_MSG_ERROR(["--without-editor not supported."])
+               ;;
+    [[1-9]]*)  passwd_tries=$with_passwd_tries
+               ;;
+    *)         AC_MSG_ERROR(["you must enter the numer of tries, > 0"])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(TRIES_FOR_PASSWORD, $passwd_tries, [The number of tries a user gets to enter their password.])
+AC_MSG_RESULT($passwd_tries)
+
+AC_MSG_CHECKING(time in minutes after which sudo will ask for a password again)
+AC_ARG_WITH(timeout, [  --with-timeout          minutes before sudo asks for passwd again (def is 5 minutes)],
+[echo $with_timeout; case $with_timeout in  
+    yes)       ;;
+    no)                timeout=0
+               ;;
+    [[0-9]]*)  timeout=$with_timeout
+               ;;
+    *)         AC_MSG_ERROR(["you must enter the numer of minutes."])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(TIMEOUT, $timeout, [The number of minutes before sudo asks for a password again.])
+AC_MSG_RESULT($timeout)
+
+AC_MSG_CHECKING(time in minutes after the password prompt will time out)
+AC_ARG_WITH(password-timeout, [  --with-password-timeout passwd prompt timeout in minutes (default is 5 minutes)],
+[case $with_password_timeout in  
+    yes)       ;;
+    no)                password_timeout=0
+               ;;
+    [[0-9]]*)  password_timeout=$with_password_timeout
+               ;;
+    *)         AC_MSG_ERROR(["you must enter the numer of minutes."])
+               ;;
+esac])
+AC_DEFINE_UNQUOTED(PASSWORD_TIMEOUT, $password_timeout, [The passwd prompt timeout (in minutes).])
+AC_MSG_RESULT($password_timeout)
+
+AC_ARG_WITH(execv, [  --with-execv            use execv() instead of execvp()],
+[case $with_execv in  
+    yes)       AC_MSG_CHECKING(whether to use execvp or execv)
+               AC_MSG_RESULT(execv)
+               AC_DEFINE(USE_EXECV, 1, [Define if you wish to use execv() instead of execvp() when running programs.])
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-execv does not take an argument."])
+               ;;
+esac])
+
+AC_MSG_CHECKING(whether to use per-tty ticket files)
+AC_ARG_WITH(tty-tickets, [  --with-tty-tickets      use a different ticket file for each tty],
+[case $with_tty_tickets in  
+    yes)       tty_tickets=on
+               ;;
+    no)                tty_tickets=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-tty-tickets does not take an argument."])
+               ;;
+esac])
+if test "$tty_tickets" = "on"; then
+    AC_DEFINE(USE_TTY_TICKETS, 1, [Define if you want a different ticket file for each tty.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to include insults)
+AC_ARG_WITH(insults, [  --with-insults          insult the user for entering an incorrect password],
+[case $with_insults in  
+    yes)       insults=on
+               with_classic_insults=yes
+               with_csops_insults=yes
+               ;;
+    no)                insults=off
+               ;;
+    *)         AC_MSG_ERROR(["--with-insults does not take an argument."])
+               ;;
+esac])
+if test "$insults" = "on"; then
+    AC_DEFINE(USE_INSULTS, 1, [Define if you want to insult the user for entering an incorrect password.])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_ARG_WITH(all-insults, [  --with-all-insults      include all the sudo insult sets],
+[case $with_all_insults in  
+    yes)       with_classic_insults=yes
+               with_csops_insults=yes
+               with_hal_insults=yes
+               with_goons_insults=yes
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-all-insults does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(classic-insults, [  --with-classic-insults  include the insults from the "classic" sudo],
+[case $with_classic_insults in  
+    yes)       AC_DEFINE(CLASSIC_INSULTS, 1, [Define if you want the insults from the "classic" version sudo.])
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-classic-insults does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(csops-insults, [  --with-csops-insults    include CSOps insults],
+[case $with_csops_insults in  
+    yes)       AC_DEFINE(CSOPS_INSULTS, 1, [Define if you want insults culled from the twisted minds of CSOps.])
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-csops-insults does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(hal-insults, [  --with-hal-insults      include 2001-like insults],
+[case $with_hal_insults in  
+    yes)       AC_DEFINE(HAL_INSULTS, 1, [Define if you want 2001-like insults.])
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-hal-insults does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(goons-insults, [  --with-goons-insults    include the insults from the "Goon Show"],
+[case $with_goons_insults in  
+    yes)       AC_DEFINE(GOONS_INSULTS, 1, [Define if you want insults from the "Goon Show".])
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-goons-insults does not take an argument."])
+               ;;
+esac])
+
+dnl include all insult sets on one line
+if test "$insults" = "on"; then
+    AC_MSG_CHECKING(which insult sets to include)
+    i=""
+    test "$with_goons_insults" = "yes" && i="goons ${i}"
+    test "$with_hal_insults" = "yes" && i="hal ${i}"
+    test "$with_csops_insults" = "yes" && i="csops ${i}"
+    test "$with_classic_insults" = "yes" && i="classic ${i}"
+    AC_MSG_RESULT([$i])
+fi
+
+AC_MSG_CHECKING(whether to override the user's path)
+AC_ARG_WITH(secure-path, [  --with-secure-path      override the user's path with a builtin one],
+[case $with_secure_path in  
+    yes)       AC_DEFINE_UNQUOTED(SECURE_PATH, "/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc", [Define to override the user's path with a builtin one.])
+               AC_MSG_RESULT([:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc])
+               ;;
+    no)                AC_MSG_RESULT(no)
+               ;;
+    *)         AC_DEFINE_UNQUOTED(SECURE_PATH, "$with_secure_path")
+               AC_MSG_RESULT([$with_secure_path])
+               ;;
+esac], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to get ip addresses from the network interfaces)
+AC_ARG_WITH(interfaces, [  --without-interfaces    don't try to read the ip addr of ether interfaces],
+[case $with_interfaces in  
+    yes)       AC_MSG_RESULT(yes)
+               ;;
+    no)                AC_DEFINE(STUB_LOAD_INTERFACES, 1, [Define if the code in interfaces.c does not compile for you.])
+               AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_ERROR(["--with-interfaces does not take an argument."])
+               ;;
+esac], AC_MSG_RESULT(yes))
+
+dnl
+dnl Options for --enable
+dnl
+
+AC_MSG_CHECKING(whether to do user authentication by default)
+AC_ARG_ENABLE(authentication,
+[  --disable-authentication
+                          Do not require authentication by default],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(yes)
+               ;;
+    no)                AC_MSG_RESULT(no)
+               AC_DEFINE(NO_AUTHENTICATION, 1, [Define if you don't want sudo to prompt for a password by default.])
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-authentication: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(yes))
+
+AC_MSG_CHECKING(whether to disable running the mailer as root)
+AC_ARG_ENABLE(root-mailer,
+[  --disable-root-mailer   Don't run the mailer as root, run as the user],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(no)
+               ;;
+    no)                AC_MSG_RESULT(yes)
+               AC_DEFINE(NO_ROOT_MAILER, 1, [Define to avoid runing the mailer as root.])
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-root-mailer: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_ARG_ENABLE(setreuid,
+[  --disable-setreuid      Don't try to use the setreuid() function],
+[ case "$enableval" in
+    no)                BROKEN_SETREUID=1
+               ;;
+    *)         ;;
+  esac
+])
+
+AC_MSG_CHECKING(whether to disable use of POSIX saved ids)
+AC_ARG_ENABLE(saved-ids,
+[  --disable-saved-ids     Don't try to use POSIX saved ids],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(no)
+               ;;
+    no)                AC_MSG_RESULT(yes)
+               AC_DEFINE(NO_SAVED_IDS, 1, [Define to avoid using POSIX saved ids.])
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-saved-ids: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to disable shadow password support)
+AC_ARG_ENABLE(shadow,
+[  --disable-shadow        Never use shadow passwords],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(no)
+               ;;
+    no)                AC_MSG_RESULT(yes)
+               CHECKSHADOW="false"
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-shadow: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether root should be allowed to use sudo)
+AC_ARG_ENABLE(root-sudo,
+[  --disable-root-sudo     Don't allow root to run sudo],
+[ case "$enableval" in  
+    yes)       AC_MSG_RESULT(yes)
+               ;;
+    no)                AC_DEFINE(NO_ROOT_SUDO, 1, [Define if root should not be allowed to use sudo.])
+               AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_ERROR(["--enable-root-sudo does not take an argument."])
+               ;;
+  esac
+], AC_MSG_RESULT(yes))
+
+AC_MSG_CHECKING(whether to log the hostname in the log file)
+AC_ARG_ENABLE(log-host,
+[  --enable-log-host       Log the hostname in the log file],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(yes)
+               AC_DEFINE(HOST_IN_LOG, 1, [Define if you want the hostname to be entered into the log file.])
+               ;;
+    no)                AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-log-host: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to invoke a shell if sudo is given no arguments)
+AC_ARG_ENABLE(noargs-shell,
+[  --enable-noargs-shell   If sudo is given no arguments run a shell],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(yes)
+               AC_DEFINE(SHELL_IF_NO_ARGS, 1, [Define if you want sudo to start a shell if given no arguments.])
+               ;;
+    no)                AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-noargs-shell: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to set \$HOME to target user in shell mode)
+AC_ARG_ENABLE(shell-sets-home,
+[  --enable-shell-sets-home
+                          set $HOME to target user in shell mode],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(yes)
+               AC_DEFINE(SHELL_SETS_HOME, 1, [Define if you want sudo to set $HOME in shell mode.])
+               ;;
+    no)                AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-shell-sets-home: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to disable 'command not found' messages)
+AC_ARG_ENABLE(path_info,
+[  --disable-path-info     Print 'command not allowed' not 'command not found'],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(no)
+               ;;
+    no)                AC_MSG_RESULT(yes)
+               AC_DEFINE(DONT_LEAK_PATH_INFO, 1, [Define if you want sudo to display "command not allowed" instead of "command not found" when a command cannot be found.])
+               ;;
+    *)         AC_MSG_RESULT(no)
+               echo "Ignoring unknown argument to --enable-path-info: $enableval"
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+dnl
+dnl If we don't have egrep we can't do anything...
+dnl
+AC_CHECK_PROG(EGREPPROG, egrep, egrep, )
+if test -z "$EGREPPROG"; then
+    echo "Sorry, configure requires egrep to run."
+    exit
+fi
+
+dnl
+dnl Prevent configure from adding the -g flag unless in devel mode
+dnl
+if test "$with_devel" != "yes"; then
+    ac_cv_prog_cc_g=no
+fi
+
+dnl
+dnl C compiler checks
+dnl XXX - the cross-compiler check gets false positives so we override it
+dnl
+AC_ISC_POSIX
+ac_cv_prog_cc_cross="no"
+cross_compiling="no"
+AC_PROG_CC_STDC
+ac_cv_prog_cc_cross="no"
+cross_compiling="no"
+AC_PROG_CPP
+
+dnl
+dnl It is now safe to modify CFLAGS and CPPFLAGS
+dnl
+if test "$with_devel" = "yes" -a -n "$GCC"; then
+    CFLAGS="${CFLAGS} -Wall"
+fi
+
+dnl
+dnl Find programs we use
+dnl
+AC_CHECK_PROG(UNAMEPROG, uname, uname, )
+AC_CHECK_PROG(TRPROG, tr, tr, )
+AC_CHECK_PROG(SEDPROG, sed, sed, )
+AC_CHECK_PROG(NROFFPROG, nroff, nroff, )
+if test -z "$NROFFPROG"; then
+    MANTYPE="cat"
+    mansrcdir='$(srcdir)'
+fi
+
+dnl
+dnl What kind of beastie are we being run on?
+dnl Barf if config.cache was generated on another host.
+dnl
+AC_CANONICAL_HOST
+if test -n "$sudo_cv_prev_host"; then
+    if test "$sudo_cv_prev_host" != "$host"; then
+       echo ""
+       echo "Fatal Error: config.cache exists from another platform!"
+       echo "Please remove it and re-run configure."
+       echo ""
+       exit 1
+    else
+       AC_MSG_CHECKING(previous host type)
+       AC_CACHE_VAL(sudo_cv_prev_host, sudo_cv_prev_host="$host")
+       echo $sudo_cv_prev_host
+    fi
+else
+    # this will produce no output since there is no cached value
+    AC_CACHE_VAL(sudo_cv_prev_host, sudo_cv_prev_host="$host")
+fi
+
+dnl
+dnl We want to be able to differentiate between different rev's
+dnl
+if test -n "$host_os"; then
+    OS=`echo $host_os | sed 's/[[0-9]].*//'`
+    OSREV=`echo $host_os | sed 's/^[[^0-9]]*\([[0-9]][[0-9]]*\).*$/\1/'`
+else
+    OS="unknown"
+    OSREV=0
+fi
+
+case "$host" in
+    *-*-sunos4*)
+               # getcwd(3) opens a pipe to getpwd(1)!?!
+               BROKEN_GETCWD=1
+
+               # system headers lack prototypes but gcc helps...
+               if test -n "$GCC"; then
+                   CPPFLAGS="${CPPFLAGS} -D__USE_FIXED_PROTOTYPES__"
+               fi
+
+               # check for password adjunct functions (shadow passwords)
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_FUNCS(getpwanam issecure, , [break])
+                   AH_TEMPLATE([HAVE_GETPWANAM], [Define if you have the `getpwanam' function. (SunOS 4.x shadow passwords)])
+                   AH_TEMPLATE([HAVE_ISSECURE], [Define if you have the `issecure' function. (SunOS 4.x check for shadow enabled)])
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-solaris2*)
+               # To get the crypt(3) prototype (so we pass -Wall)
+               CPPFLAGS="${CPPFLAGS} -D__EXTENSIONS__"
+               # AFS support needs -lucb
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lucb"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-aix*)
+               # To get all prototypes (so we pass -Wall)
+               CPPFLAGS="${CPPFLAGS} -D_XOPEN_EXTENDED_SOURCE"
+               SUDO_DEFINE(_ALL_SOURCE)
+               SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp"
+               ;;
+    *-*-hiuxmpp*)
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(sec, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1], AC_CHECK_LIB(security, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity"; SECUREWARE=1]))
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux1[[0-9]]*)
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(sec, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) AC_CHECK_LIB(sec, iscomsec, AC_DEFINE(HAVE_ISCOMSEC, 1, [Define if you have the `iscomsec' function. (HP-UX >= 10.x check for shadow enabled)])) [SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1])
+                   CHECKSHADOW="false"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux9*)
+               AC_DEFINE(BROKEN_SYSLOG, 1, [Define if the `syslog' function returns a non-zero int to denote failure.])
+
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_FUNCS(getspwuid)
+                   AH_TEMPLATE([HAVE_GETSPWUID], [Define if you have the `getspwuid' function. (HP-UX <= 9.X shadow passwords)])
+                   CHECKSHADOW="false"
+               fi
+
+               # DCE support (requires ANSI C compiler)
+               if test "$with_DCE" = "yes"; then
+                   # order of libs in 9.X is important. -lc_r must be last
+                   SUDO_LIBS="${SUDO_LIBS} -ldce -lM -lc_r"
+                   LIBS="${LIBS} -ldce -lM -lc_r"
+                   CPPFLAGS="${CPPFLAGS} -D_REENTRANT -I/usr/include/reentrant"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-hpux*)
+               AC_DEFINE(BROKEN_SYSLOG)
+
+               # Not sure if setuid binaries are safe in < 9.x
+               if test -n "$GCC"; then
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -static"
+               else
+                   SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive"
+               fi
+
+               # AFS support needs -lBSD
+               if test "$with_AFS" = "yes"; then
+                   AFS_LIBS="-lc -lBSD"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-dec-osf*)
+               # ignore envariables wrt dynamic lib path
+               SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-no_library_replacement"
+
+               AC_MSG_CHECKING(whether to disable sia support on Digital UNIX)
+               AC_ARG_ENABLE(sia,
+               [  --disable-sia           Never use SIA on Digital UNIX],
+               [ case "$enableval" in
+                   yes)        AC_MSG_RESULT(no)
+                               ;;
+                   no)         AC_MSG_RESULT(yes)
+                               CHECKSIA=false
+                               ;;
+                   *)          AC_MSG_RESULT(no)
+                               echo "Ignoring unknown argument to --enable-sia: $enableval"
+                               ;;
+                 esac
+               ], AC_MSG_RESULT(no))
+
+               # use SIA by default, if we have it, else SecureWare
+               # unless overridden on the command line
+               if test "$CHECKSIA" = "true"; then
+                   AC_CHECK_FUNC(sia_ses_init, AC_DEFINE(HAVE_SIA, 1, [Define if you use SIA.]) [
+                   if test -n "$with_skey" -o -n "$with_opie" -o -n "$with_otp_only" -o -n "$with_long_otp_prompt" -o -n "$with_SecurID" -o -n "$with_fwtk" -o -n "$with_kerb4" -o -n "$with_kerb5" -o -n "$with_pam" -o -n "$with_AFS" -o -n "$with_DCE"; then
+                       AC_MSG_ERROR(["you cannot mix SIA and other authentication schemes.  You can turn off SIA support via the --disable-sia option"])
+                   fi]; CHECKSHADOW=false)
+               fi
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(security, getprpwnam, SECUREWARE=1)
+                   CHECKSHADOW="false"
+               fi
+
+               if test -n "$SECUREWARE"; then
+                   AC_DEFINE(HAVE_GETPRPWNAM, 1, [Define if you have the `getprpwnam' function.  (SecureWare-style shadow passwords)])
+                   # -ldb includes bogus versions of snprintf/vsnprintf
+                   AC_CHECK_FUNCS(snprintf, , [NEED_SNPRINTF=1])
+                   AC_CHECK_FUNCS(vsnprintf, , [NEED_SNPRINTF=1])
+                   # 4.x and higher need -ldb too...
+                   AC_CHECK_LIB(db, dbopen, [SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"], [SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"])
+                   AC_CHECK_FUNCS(dispcrypt)
+                   AC_MSG_CHECKING([for broken /usr/include/prot.h])
+                   AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/security.h>
+#include <prot.h>
+                   ], [exit(0);], AC_MSG_RESULT(no),
+                   [AC_MSG_RESULT([yes, fixing locally])
+                   sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h
+                   ])
+               elif test "$CHECKSIA" = "true"; then
+                   with_passwd=no
+                   AUTH_OBJS="sia.o"
+               fi
+               test -n "$mansectsu" || mansectsu=8
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-irix*)
+               CPPFLAGS="${CPPFLAGS} -D_BSD_TYPES"
+               if test -z "$NROFFPROG"; then
+                   MAN_POSTINSTALL='   /bin/rm -f $(mandir8)/sudo.$(mansect8).z $(mandir8)/visudo.$(mansect8).z $(mandir5)/sudoers.$(mansect5).z ; /usr/bin/pack $(mandir8)/sudo.$(mansect8) $(mandir8)/visudo.$(mansect8) $(mandir5)/sudoers.$(mansect5)'
+                   if test "$prefix" = "/usr/local" -a "$mandir" = '$(prefix)/man'; then
+                       if test -d /usr/share/catman/local; then
+                           mandir="/usr/share/catman/local"
+                       else
+                           mandir="/usr/catman/local"
+                       fi
+                   fi
+               else
+                   if test "$prefix" = "/usr/local" -a "$mandir" = '$(prefix)/man'; then
+                       if test -d "/usr/share/man/local"; then
+                           mandir="/usr/share/man/local"
+                       else
+                           mandir="/usr/man/local"
+                       fi
+                   fi
+               fi
+               # IRIX <= 4 needs -lsun
+               if test "$OSREV" -le 4; then
+                   AC_CHECK_LIB(sun, getpwnam, [LIBS="${LIBS} -lsun"])
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-linux*)
+               # Some Linux versions need to link with -lshadow
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_FUNCS(getspnam, , [AC_CHECK_LIB(shadow, getspnam, AC_DEFINE(HAVE_GETSPNAM) [SUDO_LIBS="${SUDO_LIBS} -lshadow"; LIBS="${LIBS} -lshadow"])])
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-convex-bsd*)
+               SUDO_DEFINE(_CONVEX_SOURCE)
+               if test -z "$GCC"; then
+                   CFLAGS="${CFLAGS} -D__STDC__"
+               fi
+
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(sec, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [SUDO_LIBS="${SUDO_LIBS} -lprot"; LIBS="${LIBS} -lprot"; OSDEFS="${OSDEFS} -D_AUDIT -D_ACL -DSecureWare"; SECUREWARE=1])
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-ultrix*)
+               OS="ultrix"
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(auth, getauthuid, AC_DEFINE(HAVE_GETAUTHUID, 1, [Define if you have the `getauthuid' function.  (ULTRIX 4.x shadow passwords)]) [SUDO_LIBS="${SUDO_LIBS} -lauth"; LIBS="${LIBS} -lauth"])
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-riscos*)
+               LIBS="${LIBS} -lsun -lbsd"
+               CPPFLAGS="${CPPFLAGS} -I/usr/include -I/usr/include/bsd"
+               OSDEFS="${OSDEFS} -D_MIPS"
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-isc*)
+               OSDEFS="${OSDEFS} -D_ISC"
+               LIB_CRYPT=1
+               SUDO_LIBS="${SUDO_LIBS} -lcrypt"
+               LIBS="${LIBS} -lcrypt"
+
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(sec, getspnam, AC_DEFINE(HAVE_GETSPNAM) [SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"])
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-sco*|*-sco-*)
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(prot, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [SUDO_LIBS="${SUDO_LIBS} -lprot -lx"; LIBS="${LIBS} -lprot -lx"; SECUREWARE=1], , -lx)
+                   AC_CHECK_LIB(gen, getspnam, AC_DEFINE(HAVE_GETSPNAM) [SUDO_LIBS="${SUDO_LIBS} -lgen"; LIBS="${LIBS} -lgen"])
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    m88k-motorola-sysv*)
+               # motorolla's cc (a variant of gcc) does -O but not -O2
+               CFLAGS=`echo $CFLAGS | sed 's/-O2/-O/g'`
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-sequent-sysv*)
+               if test "$CHECKSHADOW" = "true"; then
+                   AC_CHECK_LIB(sec, getspnam, AC_DEFINE(HAVE_GETSPNAM) [SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"])
+                   CHECKSHADOW="false"
+               fi
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-ncr-sysv4*|*-ncr-sysvr4*)
+               AC_CHECK_LIB(c89, strcasecmp, AC_DEFINE(HAVE_STRCASECMP) [LIBS="${LIBS} -lc89"; ac_cv_func_strcasecmp=yes])
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-ccur-sysv4*|*-ccur-sysvr4*)
+               LIBS="${LIBS} -lgen"
+               SUDO_LIBS="${SUDO_LIBS} -lgen"
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+    *-*-bsdi*)
+               BROKEN_SETREUID=yes
+               # Use shlicc for BSD/OS [23].x unless asked to do otherwise
+               if test "${with_CC+set}" != set -a "$ac_cv_prog_CC" = gcc; then
+                   case "$OSREV" in
+                       2|3)    echo 'using shlicc as CC'
+                               ac_cv_prog_CC=shlicc
+                               CC="$ac_cv_prog_CC"
+                               ;;
+                   esac
+               fi
+               ;;
+    *-*-freebsd*)
+               # FreeBSD has a real setreuid(2) starting with 2.1 and
+               # backported to 2.0.5.  We just take 2.1 and above...
+               case "`echo $host_os | sed 's/^freebsd\([[0-9\.]]*\).*$/\1/'`" in
+               0.*|1.*|2.0*)
+                   BROKEN_SETREUID=yes
+                   ;;
+               esac
+               if test "$with_logincap" = "yes"; then
+                   SUDO_LIBS="${SUDO_LIBS} -lutil"
+               fi
+               if test "$with_skey" = "yes"; then
+                    SUDO_LIBS="${SUDO_LIBS} -lmd"
+               fi
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*openbsd*)
+               BROKEN_SETREUID=yes
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*netbsd*)
+               # NetBSD has a real setreuid(2) starting with 1.3.2
+               case "`echo $host_os | sed 's/^netbsd\([[0-9\.]]*\).*$/\1/'`" in
+               0.9*|1.[012]*|1.3|1.3.1)
+                   BROKEN_SETREUID=yes
+                   ;;
+               esac
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-*bsd*)
+               if test "$CHECKSHADOW" = "true"; then
+                   CHECKSHADOW="false"
+               fi
+               ;;
+    *-*-nextstep*)
+               # lockf() on is broken on the NeXT -- use flock instead
+               ac_cv_func_lockf=no
+               ac_cv_func_flock=yes
+               ;;
+    *-*-sysv*)
+               test -n "$mansectsu" || mansectsu=1m
+               test -n "$mansectform" || mansectform=4
+               ;;
+esac
+
+dnl
+dnl Use BSD-style man sections by default
+dnl
+test -n "$mansectsu" || mansectsu=8
+test -n "$mansectform" || mansectform=5
+
+dnl
+dnl Check for shadow password routines if we have not already done so.
+dnl We check for SVR4-style first and then SecureWare-style.
+dnl
+if test "$CHECKSHADOW" = "true"; then
+    AC_CHECK_FUNCS(getspnam, [CHECKSHADOW="false"], [AC_CHECK_LIB(gen, getspnam, AC_DEFINE(HAVE_GETSPNAM, 1, [Define if you have the `getspnam' function (SVR4-style shadow passwords)]) [SUDO_LIBS="${SUDO_LIBS} -lgen"; LIBS="${LIBS} -lgen"])])
+fi
+if test "$CHECKSHADOW" = "true"; then
+    AC_CHECK_FUNC(getprpwnam, [AC_DEFINE(HAVE_GETPRPWNAM) [CHECKSHADOW="false"; SECUREWARE=1], AC_CHECK_LIB(sec, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"], AC_CHECK_LIB(security, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity"], AC_CHECK_LIB(prot, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) [CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lprot"; LIBS="${LIBS} -lprot"])))])
+fi
+
+dnl
+dnl C compiler checks (to be done after os checks)
+dnl
+AC_PROG_GCC_TRADITIONAL
+AC_C_CONST
+AC_C_VOLATILE
+dnl
+dnl Program checks
+dnl
+AC_PROG_YACC
+SUDO_PROG_MV
+SUDO_PROG_BSHELL
+if test -z "$with_sendmail"; then
+    SUDO_PROG_SENDMAIL
+fi
+if test -z "$with_editor"; then
+    SUDO_PROG_VI
+fi
+dnl
+dnl Header file checks
+dnl
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_CHECK_HEADERS(malloc.h paths.h utime.h netgroup.h sys/sockio.h sys/bsdtypes.h sys/select.h)
+dnl ultrix termio/termios are broken
+if test "$OS" != "ultrix"; then
+    AC_SYS_POSIX_TERMIOS
+    if test "$ac_cv_sys_posix_termios" = "yes"; then
+       AC_DEFINE(HAVE_TERMIOS_H, 1, [Define if you have the <termios.h> header file and the `tcgetattr' function.])
+    else
+       AC_CHECK_HEADERS(termio.h)
+    fi
+fi
+if test "$with_logincap" = "yes"; then
+    AC_CHECK_HEADERS(login_cap.h)
+fi
+if test "$with_bsdauth" = "yes"; then
+    AC_CHECK_HEADER(bsd_auth.h, AC_DEFINE(HAVE_BSD_AUTH_H, 1, [Define if you use BSD authentication.]) [with_passwd=no; AUTH_OBJS=bsdauth.o])
+fi
+dnl
+dnl typedef checks
+dnl
+AC_TYPE_MODE_T
+AC_TYPE_UID_T
+AC_CHECK_TYPES([sig_atomic_t], , [AC_DEFINE(sig_atomic_t, int, [Define to `int' if <signal.h> does not define.])], [#include <sys/types.h>
+#include <signal.h>])
+AC_CHECK_TYPES([sigaction_t], [AC_DEFINE(HAVE_SIGACTION_T, 1, [Define if <signal.h> has the sigaction_t typedef.])], ,[#include <sys/types.h>
+#include <signal.h>])
+SUDO_TYPE_SIZE_T
+SUDO_TYPE_SSIZE_T
+SUDO_TYPE_DEV_T
+SUDO_TYPE_INO_T
+SUDO_FULL_VOID
+SUDO_UID_T_LEN
+SUDO_LONG_LONG
+SUDO_SOCK_SA_LEN
+dnl
+dnl only set RETSIGTYPE if it is not set already
+dnl
+case "$DEFS" in
+    *"RETSIGTYPE"*)    ;;
+    *)                 AC_TYPE_SIGNAL;;
+esac
+dnl
+dnl Function checks
+dnl
+AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf tzset \
+              seteuid setegid strftime setrlimit initgroups fstat)
+if test -z "$BROKEN_SETREUID"; then
+    AC_CHECK_FUNCS(setreuid)
+fi
+if test X"$with_interfaces" != X"no"; then
+    AC_CHECK_FUNCS(getifaddrs, AC_CHECK_FUNCS(freeifaddrs))
+fi
+if test -n "$SECUREWARE"; then
+    AC_CHECK_FUNCS(bigcrypt set_auth_parameters initprivs)
+fi
+if test -z "$BROKEN_GETCWD"; then
+    AC_REPLACE_FUNCS(getcwd)
+fi
+AC_CHECK_FUNCS(lockf flock, [break])
+AC_CHECK_FUNCS(waitpid wait3, [break])
+AC_CHECK_FUNCS(innetgr _innetgr, AC_CHECK_FUNCS(getdomainname) [break])
+AC_CHECK_FUNCS(lsearch, , [AC_CHECK_LIB(compat, lsearch, AC_CHECK_HEADER(search.h, AC_DEFINE(HAVE_LSEARCH) [LIBS="${LIBS} -lcompat"], AC_LIBOBJ(lsearch)), AC_LIBOBJ(lsearch))])
+AC_CHECK_FUNCS(utime, SUDO_FUNC_UTIME_POSIX, AC_LIBOBJ(utime))
+SUDO_FUNC_FNMATCH(AC_DEFINE(HAVE_FNMATCH, 1, [Define if you have the `fnmatch' function.]), AC_LIBOBJ(fnmatch))
+SUDO_FUNC_ISBLANK
+AC_REPLACE_FUNCS(strerror strcasecmp sigaction)
+AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
+dnl
+dnl If NEED_SNPRINTF is set, add snprintf.c to LIBOBJS
+dnl (it contains snprintf, vsnprintf, asprintf, and vasprintf)
+dnl
+if test -n "$NEED_SNPRINTF"; then
+    AC_LIBOBJ(snprintf)
+fi
+dnl
+dnl if crypt(3) not in libc, look elsewhere
+dnl
+if test -z "$LIB_CRYPT"; then
+    AC_CHECK_FUNC(crypt, , [AC_CHECK_LIB(crypt, crypt, [SUDO_LIBS="${SUDO_LIBS} -lcrypt"; LIBS="${LIBS} -lcrypt"], AC_CHECK_LIB(crypt_d, crypt, [SUDO_LIBS="${SUDO_LIBS} -lcrypt_d"; LIBS="${LIBS} -lcrypt_d"], AC_CHECK_LIB(ufc, crypt, [SUDO_LIBS="${SUDO_LIBS} -lufc"; LIBS="${LIBS} -lufc"])))])
+fi
+dnl
+dnl If socket(2) not in libc, check -lsocket and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
+dnl In this case we look for main(), not socket() to avoid using a cached value
+dnl
+AC_CHECK_FUNC(socket, , [AC_CHECK_LIB(socket, socket, [NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"], AC_CHECK_LIB(inet, socket, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"], AC_MSG_WARN(unable to find socket() trying -lsocket -lnsl)
+AC_CHECK_LIB(socket, socket, [NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"], , -lnsl)))])
+dnl
+dnl If inet_addr(3) not in libc, check -lnsl and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
+dnl
+AC_CHECK_FUNC(inet_addr, , [AC_CHECK_FUNC(__inet_addr, , AC_CHECK_LIB(nsl, inet_addr, [NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"], AC_CHECK_LIB(inet, inet_addr, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"], AC_MSG_WARN(unable to find inet_addr() trying -lsocket -lnsl)
+AC_CHECK_LIB(socket, inet_addr, [NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"], , -lnsl))))])
+dnl
+dnl If syslog(3) not in libc, check -lsocket, -lnsl and -linet
+dnl
+AC_CHECK_FUNC(syslog, , [AC_CHECK_LIB(socket, syslog, [NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"], AC_CHECK_LIB(nsl, syslog, [NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"], AC_CHECK_LIB(inet, syslog, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"])))])
+dnl
+dnl Bison and DCE use alloca(3), if not in libc, use the sudo one (from gcc)
+dnl (gcc includes its own alloca(3) but other compilers may not)
+dnl
+if test "$with_DCE" = "yes" -o "$ac_cv_prog_YACC" = "bison -y"; then
+    AC_FUNC_ALLOCA
+fi
+
+dnl
+dnl Kerberos 5
+dnl
+if test "$with_kerb5" = "yes"; then
+    AC_DEFINE(HAVE_KERB5, 1, [Define if you use Kerberos V.])
+    if test -f "/usr/local/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+    elif test -f "/usr/local/kerberos/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/kerberos/include"
+    elif test -f "/usr/krb5/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/krb5/include"
+    elif test -f "/usr/local/krb5/include/krb5.h"; then
+       CPPFLAGS="$CPPFLAGS -I/usr/local/krb5/include"
+    else
+       echo 'Unable to locate kerberos 5 include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS'
+    fi
+
+    if test -f "/usr/local/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test -f "/usr/local/kerberos/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/kerberos/lib"
+    elif test -f "/usr/krb5/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/krb5/lib"
+    elif test -f "/usr/local/krb5/lib/libkrb5.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/krb5/lib"
+    else
+       echo 'Unable to locate kerberos 5 libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDO_LDFLAGS'
+    fi
+
+    SUDO_LIBS="${SUDO_LIBS} -lkrb5 -lk5crypto -lcom_err"
+    AUTH_OBJS="${AUTH_OBJS} kerb5.o"
+fi
+
+dnl
+dnl PAM libs
+dnl
+if test "$with_pam" = "yes"; then
+    AC_HAVE_LIBRARY(dl, SUDO_LIBS="${SUDO_LIBS} -ldl -lpam", SUDO_LIBS="${SUDO_LIBS} -lpam")
+fi
+
+dnl
+dnl Find kerberos 4 includes and libs or complain
+dnl
+if test "$with_kerb4" = "yes"; then
+    AC_DEFINE(HAVE_KERB4, 1, [Define if you use Kerberos IV.])
+    if test -f "/usr/include/kerberosIV/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/include/kerberosIV"
+    elif test -f "/usr/local/include/kerberosIV/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include/kerberosIV"
+    elif test -f "/usr/kerberos/include/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/kerberos/include"
+    elif test -f "/usr/local/kerberos/include/krb.h"; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/kerberos/include"
+    else
+       echo 'Unable to locate kerberos 4 include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS'
+    fi
+
+    if test -d "/usr/kerberos/lib"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/kerberos/lib"
+    elif test -d "/usr/lib/kerberos"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/lib/kerberos"
+    elif test -f "/usr/local/lib/libkrb.a"; then
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test ! -f "/usr/lib/libkrb.a"; then
+       echo 'Unable to locate kerberos 4 libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDO_LDFLAGS'
+    fi
+
+    AC_HAVE_LIBRARY(des, SUDO_LIBS="${SUDO_LIBS} -lkrb -ldes", SUDO_LIBS="${SUDO_LIBS} -lkrb")
+    AUTH_OBJS="${AUTH_OBJS} kerb4.o"
+fi
+
+dnl
+dnl extra AFS libs and includes
+dnl
+if test "$with_AFS" = "yes"; then
+
+    # looks like the "standard" place for AFS libs is /usr/afsws/lib
+    AFSLIBDIRS="/usr/lib/afs /usr/afsws/lib /usr/afsws/lib/afs"
+    for i in $AFSLIBDIRS; do
+       if test -d ${i}; then
+           SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${i}"
+           FOUND_AFSLIBDIR=true
+       fi
+    done
+    if test -z "$FOUND_AFSLIBDIR"; then
+       echo 'Unable to locate AFS libraries, you will have to edit the Makefile and add -L/path/to/afs/libs to SUDO_LDFLAGS or rerun configure with the --with-libpath options.'
+    fi
+
+    # Order is important here.  Note that we build AFS_LIBS from right to left
+    # since AFS_LIBS may be initialized with BSD compat libs that must go last
+    AFS_LIBS="-laudit ${AFS_LIBS}"
+    for i in $AFSLIBDIRS; do
+       if test -f ${i}/util.a; then
+           AFS_LIBS="${i}/util.a ${AFS_LIBS}"
+           FOUND_UTIL_A=true
+           break;
+       fi
+    done
+    if test -z "$FOUND_UTIL_A"; then
+       AFS_LIBS="-lutil ${AFS_LIBS}"
+    fi
+    AFS_LIBS="-lkauth -lprot -lubik -lauth -lrxkad -lsys -ldes -lrx -llwp -lcom_err ${AFS_LIBS}"
+
+    # AFS includes may live in /usr/include on some machines...
+    for i in /usr/afsws/include; do
+       if test -d ${i}; then
+           CPPFLAGS="${CPPFLAGS} -I${i}"
+           FOUND_AFSINCDIR=true
+       fi
+    done
+
+    if test -z "$FOUND_AFSLIBDIR"; then
+       echo 'Unable to locate AFS include dir, you may have to edit the Makefile and add -I/path/to/afs/includes to CPPFLAGS or rerun configure with the --with-incpath options.'
+    fi
+fi
+
+dnl
+dnl extra DCE obj + lib
+dnl Order of libs in HP-UX 10.x is important, -ldce must be last.
+dnl
+if test "$with_DCE" = "yes"; then
+    DCE_OBJS="${DCE_OBJS} dce_pwent.o"
+    SUDO_LIBS="${SUDO_LIBS} -ldce"
+fi
+
+dnl
+dnl extra S/Key lib and includes
+dnl
+if test "$with_skey" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lskey"
+    if test -f /usr/include/skey.h -a -f /usr/lib/libskey.a; then
+       :
+    elif test -f /usr/local/include/skey.h; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    elif test "$with_csops" = "yes" -a -f /tools/cs/skey/include/skey.h -a -f /tools/cs/skey/lib/libskey.a; then
+       CPPFLAGS="${CPPFLAGS} -I/tools/cs/skey/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/tools/cs/skey/lib"
+    else
+       echo 'Unable to locate libskey.a and/or skey.h, you will have to edit the Makefile and add -L/path/to/skey/lib to SUDO_LDFLAGS and/or -I/path/to/skey.h to CPPFLAGS'
+    fi
+    AC_CHECK_LIB(skey, skeyaccess, AC_DEFINE(HAVE_SKEYACCESS, 1, [Define if your S/Key library has skeyaccess().]))
+fi
+
+dnl
+dnl extra OPIE lib and includes
+dnl
+if test "$with_opie" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lopie"
+    if test -f /usr/include/opie.h -a -f /usr/lib/libopie.a; then
+       :
+    elif test -f /usr/local/include/opie.h; then
+       CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+       SUDO_LDFLAGS="${SUDO_LDFLAGS} -L/usr/local/lib"
+    else
+       echo 'Unable to locate libopie.a and/or opie.h, you will have to edit the Makefile and add -L/path/to/opie/lib to SUDO_LDFLAGS and/or -I/path/to/opie.h to CPPFLAGS'
+    fi
+fi
+
+dnl
+dnl extra SecurID lib + includes
+dnl
+if test -n "$with_SecurID" -a "$with_SecurID" != "no"; then
+    if test "$with_SecurID" != "yes"; then
+       SUDO_LIBS="${SUDO_LIBS} ${with_SecurID}/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I${with_SecurID}"
+    elif test -f /usr/ace/examples/sdiclient.a; then
+       SUDO_LIBS="${SUDO_LIBS} /usr/ace/examples/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I/usr/ace/examples"
+    else
+       SUDO_LIBS="${SUDO_LIBS} /usr/ace/sdiclient.a"
+       CPPFLAGS="${CPPFLAGS} -I/usr/ace"
+    fi
+fi
+
+dnl
+dnl extra FWTK libs + includes
+dnl
+if test "$with_fwtk" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -lauth -lfwall"
+fi
+
+dnl
+dnl extra 'authenticate' lib (AIX only?)
+dnl
+if test "$with_authenticate" = "yes"; then
+    SUDO_LIBS="${SUDO_LIBS} -ls"
+fi
+
+dnl
+dnl Check for log file and timestamp locations
+dnl
+SUDO_LOGFILE
+SUDO_TIMEDIR
+
+dnl
+dnl Use passwd (and secureware) auth modules?
+dnl
+if test "$with_passwd" = "no"; then
+    AC_DEFINE(WITHOUT_PASSWD, 1. [Define to avoid using the passwd/shadow file for authentication.])
+    if test -z "$AUTH_OBJS"; then
+       AC_MSG_ERROR([no authentication methods defined.])
+    fi
+else
+    if test -n "$SECUREWARE"; then
+       AUTH_OBJS="${AUTH_OBJS} passwd.o secureware.o"
+    else
+       AUTH_OBJS="${AUTH_OBJS} passwd.o"
+    fi
+fi
+
+dnl
+dnl LIBS may contain duplicates from SUDO_LIBS or NET_LIBS so prune it.
+dnl
+if test -n "$LIBS"; then
+    L="$LIBS"
+    LIBS=
+    for l in ${L}; do
+       dupe=0
+       for sl in ${SUDO_LIBS} ${NET_LIBS}; do
+           test $l = $sl && dupe=1
+       done
+       test $dupe = 0 && LIBS="${LIBS} $l"
+    done
+fi
+
+dnl
+dnl Set exec_prefix
+dnl
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+dnl
+dnl Substitute into the Makefile and man pages
+dnl
+AC_OUTPUT([Makefile sudo.man visudo.man sudoers.man])
+
+dnl
+dnl Spew any text the user needs to know about
+dnl
+if test "$with_pam" = "yes"; then
+    echo ""
+    case $host in
+       *-*-linux*)
+           echo "You will need to customize sample.pam and install it as /etc/pam.d/sudo"
+           ;;
+    esac
+    echo ""
+fi
+
+dnl
+dnl Special bits for autoheader   
+dnl
+AH_VERBATIM([_GNU_SOURCE],
+[/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE   1
+#endif])
+
+AH_VERBATIM([_ALL_SOURCE],
+[/* Enable non-POSIX extensions on AIX. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif])
+
+AH_VERBATIM([_CONVEX_SOURCE],
+[/* Enable non-POSIX extensions on ConvexOS. */
+#ifndef _CONVEX_SOURCE
+# undef _CONVEX_SOURCE
+#endif])
+
+AH_TOP([#ifndef _SUDO_CONFIG_H
+#define _SUDO_CONFIG_H])
+
+AH_BOTTOM([/*
+ * Emulate a subset of waitpid() if we don't have it.
+ */
+#ifdef HAVE_WAITPID
+# define sudo_waitpid(p, s, o) waitpid(p, s, o)
+#else
+# ifdef HAVE_WAIT3
+#  define sudo_waitpid(p, s, o)        wait3(s, o, NULL)
+# endif
+#endif
+
+/* Solaris doesn't use const qualifiers in PAM. */
+#ifdef sun
+# define PAM_CONST
+#else
+# define PAM_CONST     const
+#endif
+
+#ifdef USE_EXECV
+# define EXEC  execv
+#else
+# define EXEC  execvp
+#endif /* USE_EXECV */
+
+/* New ANSI-style OS defs for HP-UX and ConvexOS. */
+#if defined(hpux) && !defined(__hpux)
+# define __hpux                1
+#endif /* hpux */
+
+#if defined(convex) && !defined(__convex__)
+# define __convex__    1
+#endif /* convex */
+
+/* BSD compatibility on some SVR4 systems. */
+#ifdef __svr4__
+# define BSD_COMP
+#endif /* __svr4__ */
+
+#endif /* _SUDO_CONFIG_H */])
diff --git a/def_data.c b/def_data.c
new file mode 100644 (file)
index 0000000..ec02d88
--- /dev/null
@@ -0,0 +1,179 @@
+struct sudo_defs_types sudo_defs_table[] = {
+    {
+       "syslog_ifac", T_UINT,
+       NULL
+    }, {
+       "syslog_igoodpri", T_UINT,
+       NULL
+    }, {
+       "syslog_ibadpri", T_UINT,
+       NULL
+    }, {
+       "syslog", T_LOGFAC|T_BOOL,
+       "Syslog facility if syslog is being used for logging: %s"
+    }, {
+       "syslog_goodpri", T_LOGPRI,
+       "Syslog priority to use when user authenticates successfully: %s"
+    }, {
+       "syslog_badpri", T_LOGPRI,
+       "Syslog priority to use when user authenticates unsuccessfully: %s"
+    }, {
+       "long_otp_prompt", T_FLAG,
+       "Put OTP prompt on its own line"
+    }, {
+       "ignore_dot", T_FLAG,
+       "Ignore '.' in $PATH"
+    }, {
+       "mail_always", T_FLAG,
+       "Always send mail when sudo is run"
+    }, {
+       "mail_badpass", T_FLAG,
+       "Send mail if user authentication fails"
+    }, {
+       "mail_no_user", T_FLAG,
+       "Send mail if the user is not in sudoers"
+    }, {
+       "mail_no_host", T_FLAG,
+       "Send mail if the user is not in sudoers for this host"
+    }, {
+       "mail_no_perms", T_FLAG,
+       "Send mail if the user is not allowed to run a command"
+    }, {
+       "tty_tickets", T_FLAG,
+       "Use a separate timestamp for each user/tty combo"
+    }, {
+       "lecture", T_FLAG,
+       "Lecture user the first time they run sudo"
+    }, {
+       "authenticate", T_FLAG,
+       "Require users to authenticate by default"
+    }, {
+       "root_sudo", T_FLAG,
+       "Root may run sudo"
+    }, {
+       "log_host", T_FLAG,
+       "Log the hostname in the (non-syslog) log file"
+    }, {
+       "log_year", T_FLAG,
+       "Log the year in the (non-syslog) log file"
+    }, {
+       "shell_noargs", T_FLAG,
+       "If sudo is invoked with no arguments, start a shell"
+    }, {
+       "set_home", T_FLAG,
+       "Set $HOME to the target user when starting a shell with -s"
+    }, {
+       "always_set_home", T_FLAG,
+       "Always set $HOME to the target user's home directory"
+    }, {
+       "path_info", T_FLAG,
+       "Allow some information gathering to give useful error messages"
+    }, {
+       "fqdn", T_FLAG,
+       "Require fully-qualified hostnames in the sudoers file"
+    }, {
+       "insults", T_FLAG,
+       "Insult the user when they enter an incorrect password"
+    }, {
+       "requiretty", T_FLAG,
+       "Only allow the user to run sudo if they have a tty"
+    }, {
+       "env_editor", T_FLAG,
+       "Visudo will honor the EDITOR environment variable"
+    }, {
+       "rootpw", T_FLAG,
+       "Prompt for root's password, not the users's"
+    }, {
+       "runaspw", T_FLAG,
+       "Prompt for the runas_default user's password, not the users's"
+    }, {
+       "targetpw", T_FLAG,
+       "Prompt for the target user's password, not the users's"
+    }, {
+       "use_loginclass", T_FLAG,
+       "Apply defaults in the target user's login class if there is one"
+    }, {
+       "set_logname", T_FLAG,
+       "Set the LOGNAME and USER environment variables"
+    }, {
+       "stay_setuid", T_FLAG,
+       "Only set the effective uid to the target user, not the real uid"
+    }, {
+       "env_reset", T_FLAG,
+       "Reset the environment to a default set of variables"
+    }, {
+       "preserve_groups", T_FLAG,
+       "Don't initialize the group vector to that of the target user"
+    }, {
+       "loglinelen", T_UINT|T_BOOL,
+       "Length at which to wrap log file lines (0 for no wrap): %d"
+    }, {
+       "timestamp_timeout", T_INT|T_BOOL,
+       "Authentication timestamp timeout: %d minutes"
+    }, {
+       "passwd_timeout", T_UINT|T_BOOL,
+       "Password prompt timeout: %d minutes"
+    }, {
+       "passwd_tries", T_UINT,
+       "Number of tries to enter a password: %d"
+    }, {
+       "umask", T_MODE|T_BOOL,
+       "Umask to use or 0777 to use user's: 0%o"
+    }, {
+       "logfile", T_STR|T_BOOL|T_PATH,
+       "Path to log file: %s"
+    }, {
+       "mailerpath", T_STR|T_BOOL|T_PATH,
+       "Path to mail program: %s"
+    }, {
+       "mailerflags", T_STR|T_BOOL,
+       "Flags for mail program: %s"
+    }, {
+       "mailto", T_STR|T_BOOL,
+       "Address to send mail to: %s"
+    }, {
+       "mailsub", T_STR,
+       "Subject line for mail messages: %s"
+    }, {
+       "badpass_message", T_STR,
+       "Incorrect password message: %s"
+    }, {
+       "timestampdir", T_STR|T_PATH,
+       "Path to authentication timestamp dir: %s"
+    }, {
+       "exempt_group", T_STR|T_BOOL,
+       "Users in this group are exempt from password and PATH requirements: %s"
+    }, {
+       "passprompt", T_STR,
+       "Default password prompt: %s"
+    }, {
+       "runas_default", T_STR,
+       "Default user to run commands as: %s"
+    }, {
+       "editor", T_STR|T_PATH,
+       "Path to the editor for use by visudo: %s"
+    }, {
+       "env_check", T_LIST|T_BOOL,
+       "Environment variables to check for sanity:"
+    }, {
+       "env_delete", T_LIST|T_BOOL,
+       "Environment variables to remove:"
+    }, {
+       "env_keep", T_LIST|T_BOOL,
+       "Environment variables to preserve:"
+    }, {
+       "listpw_i", T_UINT,
+       NULL
+    }, {
+       "verifypw_i", T_UINT,
+       NULL
+    }, {
+       "listpw", T_PWFLAG,
+       "When to require a password for 'list' pseudocommand: %s"
+    }, {
+       "verifypw", T_PWFLAG,
+       "When to require a password for 'verify' pseudocommand: %s"
+    }, {
+       NULL, 0, NULL
+    }
+};
diff --git a/def_data.h b/def_data.h
new file mode 100644 (file)
index 0000000..dcf2cc8
--- /dev/null
@@ -0,0 +1,58 @@
+#define I_SYSLOG_IFAC           0
+#define I_SYSLOG_IGOODPRI       1
+#define I_SYSLOG_IBADPRI        2
+#define I_SYSLOG                3
+#define I_SYSLOG_GOODPRI        4
+#define I_SYSLOG_BADPRI         5
+#define I_LONG_OTP_PROMPT       6
+#define I_IGNORE_DOT            7
+#define I_MAIL_ALWAYS           8
+#define I_MAIL_BADPASS          9
+#define I_MAIL_NO_USER          10
+#define I_MAIL_NO_HOST          11
+#define I_MAIL_NO_PERMS         12
+#define I_TTY_TICKETS           13
+#define I_LECTURE               14
+#define I_AUTHENTICATE          15
+#define I_ROOT_SUDO             16
+#define I_LOG_HOST              17
+#define I_LOG_YEAR              18
+#define I_SHELL_NOARGS          19
+#define I_SET_HOME              20
+#define I_ALWAYS_SET_HOME       21
+#define I_PATH_INFO             22
+#define I_FQDN                  23
+#define I_INSULTS               24
+#define I_REQUIRETTY            25
+#define I_ENV_EDITOR            26
+#define I_ROOTPW                27
+#define I_RUNASPW               28
+#define I_TARGETPW              29
+#define I_USE_LOGINCLASS        30
+#define I_SET_LOGNAME           31
+#define I_STAY_SETUID           32
+#define I_ENV_RESET             33
+#define I_PRESERVE_GROUPS       34
+#define I_LOGLINELEN            35
+#define I_TIMESTAMP_TIMEOUT     36
+#define I_PASSWD_TIMEOUT        37
+#define I_PASSWD_TRIES          38
+#define I_UMASK                 39
+#define I_LOGFILE               40
+#define I_MAILERPATH            41
+#define I_MAILERFLAGS           42
+#define I_MAILTO                43
+#define I_MAILSUB               44
+#define I_BADPASS_MESSAGE       45
+#define I_TIMESTAMPDIR          46
+#define I_EXEMPT_GROUP          47
+#define I_PASSPROMPT            48
+#define I_RUNAS_DEFAULT         49
+#define I_EDITOR                50
+#define I_ENV_CHECK             51
+#define I_ENV_DELETE            52
+#define I_ENV_KEEP              53
+#define I_LISTPW_I              54
+#define I_VERIFYPW_I            55
+#define I_LISTPW                56
+#define I_VERIFYPW              57
diff --git a/def_data.in b/def_data.in
new file mode 100644 (file)
index 0000000..3fac373
--- /dev/null
@@ -0,0 +1,182 @@
+#
+# Format:
+#
+# var_name
+#      TYPE
+#      description (or NULL)
+#
+
+syslog_ifac
+       T_UINT
+       NULL
+syslog_igoodpri
+       T_UINT
+       NULL
+syslog_ibadpri
+       T_UINT
+       NULL
+syslog
+       T_LOGFAC|T_BOOL
+       "Syslog facility if syslog is being used for logging: %s"
+syslog_goodpri
+       T_LOGPRI
+       "Syslog priority to use when user authenticates successfully: %s"
+syslog_badpri
+       T_LOGPRI
+       "Syslog priority to use when user authenticates unsuccessfully: %s"
+long_otp_prompt
+       T_FLAG
+       "Put OTP prompt on its own line"
+ignore_dot
+       T_FLAG
+       "Ignore '.' in $PATH"
+mail_always
+       T_FLAG
+       "Always send mail when sudo is run"
+mail_badpass
+       T_FLAG
+       "Send mail if user authentication fails"
+mail_no_user
+       T_FLAG
+       "Send mail if the user is not in sudoers"
+mail_no_host
+       T_FLAG
+       "Send mail if the user is not in sudoers for this host"
+mail_no_perms
+       T_FLAG
+       "Send mail if the user is not allowed to run a command"
+tty_tickets
+       T_FLAG
+       "Use a separate timestamp for each user/tty combo"
+lecture
+       T_FLAG
+       "Lecture user the first time they run sudo"
+authenticate
+       T_FLAG
+       "Require users to authenticate by default"
+root_sudo
+       T_FLAG
+       "Root may run sudo"
+log_host
+       T_FLAG
+       "Log the hostname in the (non-syslog) log file"
+log_year
+       T_FLAG
+       "Log the year in the (non-syslog) log file"
+shell_noargs
+       T_FLAG
+       "If sudo is invoked with no arguments, start a shell"
+set_home
+       T_FLAG
+       "Set $HOME to the target user when starting a shell with -s"
+always_set_home
+       T_FLAG
+       "Always set $HOME to the target user's home directory"
+path_info
+       T_FLAG
+       "Allow some information gathering to give useful error messages"
+fqdn
+       T_FLAG
+       "Require fully-qualified hostnames in the sudoers file"
+insults
+       T_FLAG
+       "Insult the user when they enter an incorrect password"
+requiretty
+       T_FLAG
+       "Only allow the user to run sudo if they have a tty"
+env_editor
+       T_FLAG
+       "Visudo will honor the EDITOR environment variable"
+rootpw
+       T_FLAG
+       "Prompt for root's password, not the users's"
+runaspw
+       T_FLAG
+       "Prompt for the runas_default user's password, not the users's"
+targetpw
+       T_FLAG
+       "Prompt for the target user's password, not the users's"
+use_loginclass
+       T_FLAG
+       "Apply defaults in the target user's login class if there is one"
+set_logname
+       T_FLAG
+       "Set the LOGNAME and USER environment variables"
+stay_setuid
+       T_FLAG
+       "Only set the effective uid to the target user, not the real uid"
+env_reset
+       T_FLAG
+       "Reset the environment to a default set of variables"
+preserve_groups
+       T_FLAG
+       "Don't initialize the group vector to that of the target user"
+loglinelen
+       T_UINT|T_BOOL
+       "Length at which to wrap log file lines (0 for no wrap): %d"
+timestamp_timeout
+       T_INT|T_BOOL
+       "Authentication timestamp timeout: %d minutes"
+passwd_timeout
+       T_UINT|T_BOOL
+       "Password prompt timeout: %d minutes"
+passwd_tries
+       T_UINT
+       "Number of tries to enter a password: %d"
+umask
+       T_MODE|T_BOOL
+       "Umask to use or 0777 to use user's: 0%o"
+logfile
+       T_STR|T_BOOL|T_PATH
+       "Path to log file: %s"
+mailerpath
+       T_STR|T_BOOL|T_PATH
+       "Path to mail program: %s"
+mailerflags
+       T_STR|T_BOOL
+       "Flags for mail program: %s"
+mailto
+       T_STR|T_BOOL
+       "Address to send mail to: %s"
+mailsub
+       T_STR
+       "Subject line for mail messages: %s"
+badpass_message
+       T_STR
+       "Incorrect password message: %s"
+timestampdir
+       T_STR|T_PATH
+       "Path to authentication timestamp dir: %s"
+exempt_group
+       T_STR|T_BOOL
+       "Users in this group are exempt from password and PATH requirements: %s"
+passprompt
+       T_STR
+       "Default password prompt: %s"
+runas_default
+       T_STR
+       "Default user to run commands as: %s"
+editor
+       T_STR|T_PATH
+       "Path to the editor for use by visudo: %s"
+env_check
+       T_LIST|T_BOOL
+       "Environment variables to check for sanity:"
+env_delete
+       T_LIST|T_BOOL
+       "Environment variables to remove:"
+env_keep
+       T_LIST|T_BOOL
+       "Environment variables to preserve:"
+listpw_i
+       T_UINT
+       NULL
+verifypw_i
+       T_UINT
+       NULL
+listpw
+       T_PWFLAG
+       "When to require a password for 'list' pseudocommand: %s"
+verifypw
+       T_PWFLAG
+       "When to require a password for 'verify' pseudocommand: %s"
diff --git a/defaults.c b/defaults.c
new file mode 100644 (file)
index 0000000..4621bbe
--- /dev/null
@@ -0,0 +1,785 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+# ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: defaults.c,v 1.38 2001/12/30 18:40:09 millert Exp $";
+#endif /* lint */
+
+/*
+ * For converting between syslog numbers and strings.
+ */
+struct strmap {
+    char *name;
+    int num;
+};
+
+#ifdef LOG_NFACILITIES
+static struct strmap facilities[] = {
+#ifdef LOG_AUTHPRIV
+       { "authpriv",   LOG_AUTHPRIV },
+#endif
+       { "auth",       LOG_AUTH },
+       { "daemon",     LOG_DAEMON },
+       { "user",       LOG_USER },
+       { "local0",     LOG_LOCAL0 },
+       { "local1",     LOG_LOCAL1 },
+       { "local2",     LOG_LOCAL2 },
+       { "local3",     LOG_LOCAL3 },
+       { "local4",     LOG_LOCAL4 },
+       { "local5",     LOG_LOCAL5 },
+       { "local6",     LOG_LOCAL6 },
+       { "local7",     LOG_LOCAL7 },
+       { NULL,         -1 }
+};
+#endif /* LOG_NFACILITIES */
+
+static struct strmap priorities[] = {
+       { "alert",      LOG_ALERT },
+       { "crit",       LOG_CRIT },
+       { "debug",      LOG_DEBUG },
+       { "emerg",      LOG_EMERG },
+       { "err",        LOG_ERR },
+       { "info",       LOG_INFO },
+       { "notice",     LOG_NOTICE },
+       { "warning",    LOG_WARNING },
+       { NULL,         -1 }
+};
+
+extern int sudolineno;
+
+/*
+ * Local prototypes.
+ */
+static int store_int __P((char *, struct sudo_defs_types *, int));
+static int store_uint __P((char *, struct sudo_defs_types *, int));
+static int store_str __P((char *, struct sudo_defs_types *, int));
+static int store_syslogfac __P((char *, struct sudo_defs_types *, int));
+static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
+static int store_mode __P((char *, struct sudo_defs_types *, int));
+static int store_pwflag __P((char *, struct sudo_defs_types *, int));
+static int store_list __P((char *, struct sudo_defs_types *, int));
+static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops));
+
+/*
+ * Table describing compile-time and run-time options.
+ */
+#include <def_data.c>
+
+/*
+ * Print version and configure info.
+ */
+void
+dump_defaults()
+{
+    struct sudo_defs_types *cur;
+    struct list_member *item;
+
+    for (cur = sudo_defs_table; cur->name; cur++) {
+       if (cur->desc) {
+           switch (cur->type & T_MASK) {
+               case T_FLAG:
+                   if (cur->sd_un.flag)
+                       puts(cur->desc);
+                   break;
+               case T_STR:
+               case T_LOGFAC:
+               case T_LOGPRI:
+               case T_PWFLAG:
+                   if (cur->sd_un.str) {
+                       (void) printf(cur->desc, cur->sd_un.str);
+                       putchar('\n');
+                   }
+                   break;
+               case T_UINT:
+               case T_INT:
+                   (void) printf(cur->desc, cur->sd_un.ival);
+                   putchar('\n');
+                   break;
+               case T_MODE:
+                   (void) printf(cur->desc, cur->sd_un.mode);
+                   putchar('\n');
+                   break;
+               case T_LIST:
+                   if (cur->sd_un.list) {
+                       puts(cur->desc);
+                       for (item = cur->sd_un.list; item; item = item->next)
+                           printf("\t%s\n", item->value);
+                   }
+                   break;
+           }
+       }
+    }
+}
+
+/*
+ * List each option along with its description.
+ */
+void
+list_options()
+{
+    struct sudo_defs_types *cur;
+    char *p;
+
+    (void) puts("Available options in a sudoers ``Defaults'' line:\n");
+    for (cur = sudo_defs_table; cur->name; cur++) {
+       if (cur->name && cur->desc) {
+           switch (cur->type & T_MASK) {
+               case T_FLAG:
+                   (void) printf("%s: %s\n", cur->name, cur->desc);
+                   break;
+               default:
+                   p = strrchr(cur->desc, ':');
+                   if (p)
+                       (void) printf("%s: %.*s\n", cur->name,
+                           (int) (p - cur->desc), cur->desc);
+                   else
+                       (void) printf("%s: %s\n", cur->name, cur->desc);
+                   break;
+           }
+       }
+    }
+}
+
+/*
+ * Sets/clears an entry in the defaults structure
+ * If a variable that takes a value is used in a boolean
+ * context with op == 0, disable that variable.
+ * Eg. you may want to turn off logging to a file for some hosts.
+ * This is only meaningful for variables that are *optional*.
+ */
+int
+set_default(var, val, op)
+    char *var;
+    char *val;
+    int op;     /* TRUE or FALSE */
+{
+    struct sudo_defs_types *cur;
+    int num;
+
+    for (cur = sudo_defs_table, num = 0; cur->name; cur++, num++) {
+       if (strcmp(var, cur->name) == 0)
+           break;
+    }
+    if (!cur->name) {
+       (void) fprintf(stderr,
+           "%s: unknown defaults entry `%s' referenced near line %d\n", Argv[0],
+           var, sudolineno);
+       return(FALSE);
+    }
+
+    switch (cur->type & T_MASK) {
+       case T_LOGFAC:
+           if (!store_syslogfac(val, cur, op)) {
+               if (val)
+                   (void) fprintf(stderr,
+                       "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                       val, var);
+               else
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+               return(FALSE);
+           }
+           break;
+       case T_LOGPRI:
+           if (!store_syslogpri(val, cur, op)) {
+               if (val)
+                   (void) fprintf(stderr,
+                       "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                       val, var);
+               else
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+               return(FALSE);
+           }
+           break;
+       case T_PWFLAG:
+           if (!store_pwflag(val, cur, op)) {
+               if (val)
+                   (void) fprintf(stderr,
+                       "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                       val, var);
+               else
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+               return(FALSE);
+           }
+           break;
+       case T_STR:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if ((cur->type & T_PATH) && val && *val != '/') {
+               (void) fprintf(stderr,
+                   "%s: values for `%s' must start with a '/'\n", Argv[0],
+                   var);
+               return(FALSE);
+           }
+           if (!store_str(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
+           break;
+       case T_INT:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if (!store_int(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
+           break;
+       case T_UINT:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if (!store_uint(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
+           break;
+       case T_MODE:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if (!store_mode(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
+           break;
+       case T_FLAG:
+           if (val) {
+               (void) fprintf(stderr,
+                   "%s: option `%s' does not take a value on line %d\n",
+                   Argv[0], var, sudolineno);
+               return(FALSE);
+           }
+           cur->sd_un.flag = op;
+
+           /* Special action for I_FQDN.  Move to own switch if we get more */
+           if (num == I_FQDN && op)
+               set_fqdn();
+           break;
+       case T_LIST:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if (!store_list(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
+    }
+
+    return(TRUE);
+}
+
+/*
+ * Set default options to compiled-in values.
+ * Any of these may be overridden at runtime by a "Defaults" file.
+ */
+void
+init_defaults()
+{
+    static int firsttime = 1;
+    struct sudo_defs_types *def;
+
+    /* Free any strings that were set. */
+    if (!firsttime) {
+       for (def = sudo_defs_table; def->name; def++)
+           switch (def->type & T_MASK) {
+               case T_STR:
+               case T_LOGFAC:
+               case T_LOGPRI:
+               case T_PWFLAG:
+                   if (def->sd_un.str) {
+                       free(def->sd_un.str);
+                       def->sd_un.str = NULL;
+                   }
+                   break;
+               case T_LIST:
+                   list_op(NULL, 0, def, freeall);
+                   break;
+           }
+    }
+
+    /* First initialize the flags. */
+#ifdef LONG_OTP_PROMPT
+    def_flag(I_LONG_OTP_PROMPT) = TRUE;
+#endif
+#ifdef IGNORE_DOT_PATH
+    def_flag(I_IGNORE_DOT) = TRUE;
+#endif
+#ifdef ALWAYS_SEND_MAIL
+    def_flag(I_MAIL_ALWAYS) = TRUE;
+#endif
+#ifdef SEND_MAIL_WHEN_NO_USER
+    def_flag(I_MAIL_NO_USER) = TRUE;
+#endif
+#ifdef SEND_MAIL_WHEN_NO_HOST
+    def_flag(I_MAIL_NO_HOST) = TRUE;
+#endif
+#ifdef SEND_MAIL_WHEN_NOT_OK
+    def_flag(I_MAIL_NO_PERMS) = TRUE;
+#endif
+#ifdef USE_TTY_TICKETS
+    def_flag(I_TTY_TICKETS) = TRUE;
+#endif
+#ifndef NO_LECTURE
+    def_flag(I_LECTURE) = TRUE;
+#endif
+#ifndef NO_AUTHENTICATION
+    def_flag(I_AUTHENTICATE) = TRUE;
+#endif
+#ifndef NO_ROOT_SUDO
+    def_flag(I_ROOT_SUDO) = TRUE;
+#endif
+#ifdef HOST_IN_LOG
+    def_flag(I_LOG_HOST) = TRUE;
+#endif
+#ifdef SHELL_IF_NO_ARGS
+    def_flag(I_SHELL_NOARGS) = TRUE;
+#endif
+#ifdef SHELL_SETS_HOME
+    def_flag(I_SET_HOME) = TRUE;
+#endif
+#ifndef DONT_LEAK_PATH_INFO
+    def_flag(I_PATH_INFO) = TRUE;
+#endif
+#ifdef FQDN
+    def_flag(I_FQDN) = TRUE;
+#endif
+#ifdef USE_INSULTS
+    def_flag(I_INSULTS) = TRUE;
+#endif
+#ifdef ENV_EDITOR
+    def_flag(I_ENV_EDITOR) = TRUE;
+#endif
+    def_flag(I_SET_LOGNAME) = TRUE;
+
+    /* Syslog options need special care since they both strings and ints */
+#if (LOGGING & SLOG_SYSLOG)
+    (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], TRUE);
+    (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI],
+       TRUE);
+    (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI],
+       TRUE);
+#endif
+
+    /* Password flags also have a string and integer component. */
+    (void) store_pwflag("any", &sudo_defs_table[I_LISTPW], TRUE);
+    (void) store_pwflag("all", &sudo_defs_table[I_VERIFYPW], TRUE);
+
+    /* Then initialize the int-like things. */
+#ifdef SUDO_UMASK
+    def_mode(I_UMASK) = SUDO_UMASK;
+#else
+    def_mode(I_UMASK) = 0777;
+#endif
+    def_ival(I_LOGLINELEN) = MAXLOGFILELEN;
+    def_ival(I_TIMESTAMP_TIMEOUT) = TIMEOUT;
+    def_ival(I_PASSWD_TIMEOUT) = PASSWORD_TIMEOUT;
+    def_ival(I_PASSWD_TRIES) = TRIES_FOR_PASSWORD;
+
+    /* Now do the strings */
+    def_str(I_MAILTO) = estrdup(MAILTO);
+    def_str(I_MAILSUB) = estrdup(MAILSUBJECT);
+    def_str(I_BADPASS_MESSAGE) = estrdup(INCORRECT_PASSWORD);
+    def_str(I_TIMESTAMPDIR) = estrdup(_PATH_SUDO_TIMEDIR);
+    def_str(I_PASSPROMPT) = estrdup(PASSPROMPT);
+    def_str(I_RUNAS_DEFAULT) = estrdup(RUNAS_DEFAULT);
+#ifdef _PATH_SUDO_SENDMAIL
+    def_str(I_MAILERPATH) = estrdup(_PATH_SUDO_SENDMAIL);
+    def_str(I_MAILERFLAGS) = estrdup("-t");
+#endif
+#if (LOGGING & SLOG_FILE)
+    def_str(I_LOGFILE) = estrdup(_PATH_SUDO_LOGFILE);
+#endif
+#ifdef EXEMPTGROUP
+    def_str(I_EXEMPT_GROUP) = estrdup(EXEMPTGROUP);
+#endif
+    def_str(I_EDITOR) = estrdup(EDITOR);
+
+    /* Finally do the lists (currently just environment tables). */
+    init_envtables();
+
+    /*
+     * The following depend on the above values.
+     * We use a pointer to the string so that if its
+     * value changes we get the change.
+     */
+    if (user_runas == NULL)
+       user_runas = &def_str(I_RUNAS_DEFAULT);
+
+    firsttime = 0;
+}
+
+static int
+store_int(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    char *endp;
+    long l;
+
+    if (op == FALSE) {
+       def->sd_un.ival = 0;
+    } else {
+       l = strtol(val, &endp, 10);
+       if (*endp != '\0')
+           return(FALSE);
+       /* XXX - should check against INT_MAX */
+       def->sd_un.ival = (unsigned int)l;
+    }
+    return(TRUE);
+}
+
+static int
+store_uint(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    char *endp;
+    long l;
+
+    if (op == FALSE) {
+       def->sd_un.ival = 0;
+    } else {
+       l = strtol(val, &endp, 10);
+       if (*endp != '\0' || l < 0)
+           return(FALSE);
+       /* XXX - should check against INT_MAX */
+       def->sd_un.ival = (unsigned int)l;
+    }
+    return(TRUE);
+}
+
+static int
+store_str(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+
+    if (def->sd_un.str)
+       free(def->sd_un.str);
+    if (op == FALSE)
+       def->sd_un.str = NULL;
+    else
+       def->sd_un.str = estrdup(val);
+    return(TRUE);
+}
+
+static int
+store_list(str, def, op)
+    char *str;
+    struct sudo_defs_types *def;
+    int op;
+{
+    char *start, *end;
+
+    /* Remove all old members. */
+    if (op == FALSE || op == TRUE)
+       list_op(NULL, 0, def, freeall);
+
+    /* Split str into multiple space-separated words and act on each one. */
+    if (op != FALSE) {
+       end = str;
+       do {
+           /* Remove leading blanks, if nothing but blanks we are done. */
+           for (start = end; isblank(*start); start++)
+               ;
+           if (*start == '\0')
+               break;
+
+           /* Find end position and perform operation. */
+           for (end = start; *end && !isblank(*end); end++) 
+               ;
+           list_op(start, end - start, def, op == '-' ? delete : add);
+       } while (*end++ != '\0');
+    }
+    return(TRUE);
+}
+
+static int
+store_syslogfac(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    struct strmap *fac;
+
+    if (op == FALSE) {
+       if (def->sd_un.str) {
+           free(def->sd_un.str);
+           def->sd_un.str = NULL;
+       }
+       return(TRUE);
+    }
+#ifdef LOG_NFACILITIES
+    if (!val)
+       return(FALSE);
+    for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
+       ;
+    if (fac->name == NULL)
+       return(FALSE);                          /* not found */
+
+    /* Store both name and number. */
+    if (def->sd_un.str)
+       free(def->sd_un.str);
+    def->sd_un.str = estrdup(fac->name);
+    sudo_defs_table[I_LOGFAC].sd_un.ival = fac->num;
+#else
+    if (def->sd_un.str)
+       free(def->sd_un.str);
+    def->sd_un.str = estrdup("default");
+#endif /* LOG_NFACILITIES */
+    return(TRUE);
+}
+
+static int
+store_syslogpri(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    struct strmap *pri;
+    struct sudo_defs_types *idef;
+
+    if (op == FALSE || !val)
+       return(FALSE);
+    if (def == &sudo_defs_table[I_SYSLOG_GOODPRI])
+       idef = &sudo_defs_table[I_GOODPRI];
+    else if (def == &sudo_defs_table[I_SYSLOG_BADPRI])
+       idef = &sudo_defs_table[I_BADPRI];
+    else
+       return(FALSE);
+
+    for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
+       ;
+    if (pri->name == NULL)
+       return(FALSE);                          /* not found */
+
+    /* Store both name and number. */
+    if (def->sd_un.str)
+       free(def->sd_un.str);
+    def->sd_un.str = estrdup(pri->name);
+    idef->sd_un.ival = pri->num;
+    return(TRUE);
+}
+
+static int
+store_mode(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    char *endp;
+    long l;
+
+    if (op == FALSE) {
+       def->sd_un.mode = (mode_t)0777;
+    } else {
+       l = strtol(val, &endp, 8);
+       if (*endp != '\0' || l < 0 || l > 0777)
+           return(FALSE);
+       def->sd_un.mode = (mode_t)l;
+    }
+    return(TRUE);
+}
+
+static int
+store_pwflag(val, def, op)
+    char *val;
+    struct sudo_defs_types *def;
+    int op;
+{
+    int isub, flags;
+
+    if (strcmp(def->name, "verifypw") == 0)
+       isub = I_VERIFYPW_I;
+    else
+       isub = I_LISTPW_I;
+
+    /* Handle !foo. */
+    if (op == FALSE) {
+       if (def->sd_un.str) {
+           free(def->sd_un.str);
+           def->sd_un.str = NULL;
+       }
+       def->sd_un.str = estrdup("never");
+       sudo_defs_table[isub].sd_un.ival = PWCHECK_NEVER;
+       return(TRUE);
+    }
+    if (!val)
+       return(FALSE);
+
+    /* Convert strings to integer values. */
+    if (strcmp(val, "all") == 0)
+       flags = PWCHECK_ALL;
+    else if (strcmp(val, "any") == 0)
+       flags = PWCHECK_ANY;
+    else if (strcmp(val, "never") == 0)
+       flags = PWCHECK_NEVER;
+    else if (strcmp(val, "always") == 0)
+       flags = PWCHECK_ALWAYS;
+    else
+       return(FALSE);
+
+    /* Store both name and number. */
+    if (def->sd_un.str)
+       free(def->sd_un.str);
+    def->sd_un.str = estrdup(val);
+    sudo_defs_table[isub].sd_un.ival = flags;
+
+    return(TRUE);
+}
+
+static void
+list_op(val, len, def, op)
+    char *val;
+    size_t len;
+    struct sudo_defs_types *def;
+    enum list_ops op;
+{
+    struct list_member *cur, *prev, *tmp;
+
+    if (op == freeall) {
+       for (cur = def->sd_un.list; cur; ) {
+           tmp = cur;
+           cur = tmp->next;
+           free(tmp->value);
+           free(tmp);
+       }
+       def->sd_un.list = NULL;
+       return;
+    }
+
+    for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
+       if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
+
+           if (op == add)
+               return;                 /* already exists */
+
+           /* Delete node */
+           if (prev != NULL)
+               prev->next = cur->next;
+           else
+               def->sd_un.list = cur->next;
+           free(cur->value);
+           free(cur);
+           break;
+       }
+    }
+
+    /* Add new node to the head of the list. */
+    if (op == add) {
+       cur = emalloc(sizeof(struct list_member));
+       cur->value = emalloc(len + 1);
+       (void) memcpy(cur->value, val, len);
+       cur->value[len] = '\0';
+       cur->next = def->sd_un.list;
+       def->sd_un.list = cur;
+    }
+}
diff --git a/defaults.h b/defaults.h
new file mode 100644 (file)
index 0000000..9d69a47
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: defaults.h,v 1.23 2001/12/14 19:54:56 millert Exp $
+ */
+
+#ifndef _SUDO_DEFAULTS_H
+#define _SUDO_DEFAULTS_H
+
+struct list_member {
+    char *value;
+    struct list_member *next;
+};
+
+enum list_ops {
+    add,
+    delete,
+    freeall
+};
+
+/*
+ * Structure describing compile-time and run-time options.
+ */
+struct sudo_defs_types {
+    char *name;
+    int type;
+    char *desc;
+    union {
+       int flag;
+       int ival;
+       char *str;
+       mode_t mode;
+       struct list_member *list;
+    } sd_un;
+};
+
+/*
+ * Four types of defaults: strings, integers, and flags.
+ * Also, T_INT or T_STR may be ANDed with T_BOOL to indicate that
+ * a value is not required.  Flags are boolean by nature...
+ */
+#undef T_INT
+#define T_INT          0x001
+#undef T_UINT
+#define T_UINT         0x002
+#undef T_STR
+#define T_STR          0x003
+#undef T_FLAG
+#define T_FLAG         0x004
+#undef T_MODE
+#define T_MODE         0x005
+#undef T_LIST
+#define T_LIST         0x006
+#undef T_LOGFAC
+#define T_LOGFAC       0x007
+#undef T_LOGPRI
+#define T_LOGPRI       0x008
+#undef T_PWFLAG
+#define T_PWFLAG       0x009
+#undef T_MASK
+#define T_MASK         0x0FF
+#undef T_BOOL
+#define T_BOOL         0x100
+#undef T_PATH
+#define T_PATH         0x200
+
+/*
+ * Indexes into sudo_defs_table
+ */
+#include <def_data.h>
+#define I_LOGFAC       I_SYSLOG_IFAC
+#define I_GOODPRI      I_SYSLOG_IGOODPRI
+#define I_BADPRI       I_SYSLOG_IBADPRI 
+
+/*
+ * Macros for accessing sudo_defs_table.
+ */
+#define def_flag(_i)   (sudo_defs_table[(_i)].sd_un.flag)
+#define def_ival(_i)   (sudo_defs_table[(_i)].sd_un.ival)
+#define def_str(_i)    (sudo_defs_table[(_i)].sd_un.str)
+#define def_list(_i)   (sudo_defs_table[(_i)].sd_un.list)
+#define def_mode(_i)   (sudo_defs_table[(_i)].sd_un.mode)
+
+/*
+ * Prototypes
+ */
+void dump_default      __P((void));
+int set_default                __P((char *, char *, int));
+void init_defaults     __P((void));
+void list_options      __P((void));
+
+extern struct sudo_defs_types sudo_defs_table[];
+
+#endif /* _SUDO_DEFAULTS_H */
diff --git a/emul/fnmatch.h b/emul/fnmatch.h
new file mode 100644 (file)
index 0000000..7a66a46
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)fnmatch.h   8.1 (Berkeley) 6/2/93
+ *     $OpenBSD: fnmatch.h,v 1.4 1997/09/22 05:25:32 millert Exp $
+ */
+
+#ifndef        _FNMATCH_H_
+#define        _FNMATCH_H_
+
+#define        FNM_NOMATCH     1       /* Match failed. */
+
+#define        FNM_NOESCAPE    0x01    /* Disable backslash escaping. */
+#define        FNM_PATHNAME    0x02    /* Slash must be matched by slash. */
+#define        FNM_PERIOD      0x04    /* Period must be matched by period. */
+#define        FNM_LEADING_DIR 0x08    /* Ignore /<tail> after Imatch. */
+#define        FNM_CASEFOLD    0x10    /* Case insensitive search. */
+#define        FNM_IGNORECASE  FNM_CASEFOLD
+#define        FNM_FILE_NAME   FNM_PATHNAME
+
+int     fnmatch __P((const char *, const char *, int));
+
+#endif /* !_FNMATCH_H_ */
diff --git a/emul/search.h b/emul/search.h
new file mode 100644 (file)
index 0000000..2ca992c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: search.h,v 1.8 1999/07/31 16:19:50 millert Exp $
+ */
+
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+VOID *lfind __P((const VOID *, const VOID *, size_t *, size_t,
+               int (*)(const VOID *, const VOID *)));
+VOID *lsearch __P((const VOID *, const VOID *, size_t *, size_t,
+                 int (*)(const VOID *, const VOID *)));
+
+#endif /* _SEARCH_H */
diff --git a/emul/utime.h b/emul/utime.h
new file mode 100644 (file)
index 0000000..be03349
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        _UTIME_H
+#define        _UTIME_H
+
+struct utimbuf {
+       time_t  actime;         /* access time */
+       time_t  modtime;        /* mod time */
+};
+
+int utime      __P((const char *, const struct utimbuf *));
+
+#endif /* _UTIME_H */
diff --git a/env.c b/env.c
new file mode 100644 (file)
index 0000000..f49e51e
--- /dev/null
+++ b/env.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2000, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <errno.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: env.c,v 1.16 2002/04/18 15:38:52 millert Exp $";
+#endif /* lint */
+
+/*
+ * Flags used in env_reset()
+ */
+#undef DID_TERM
+#define DID_TERM       0x01
+#undef DID_PATH
+#define DID_PATH       0x02
+#undef DID_HOME
+#define DID_HOME       0x04
+#undef DID_SHELL
+#define DID_SHELL      0x08
+#undef DID_LOGNAME
+#define DID_LOGNAME    0x10
+#undef DID_USER    
+#define DID_USER       0x12
+
+/*
+ * Prototypes
+ */
+char **rebuild_env             __P((int, char **));
+char **zero_env                        __P((char **));
+static void insert_env         __P((char **, char *));
+static char *format_env                __P((char *, char *));
+
+/*
+ * Default table of "bad" variables to remove from the environment.
+ * XXX - how to omit TERMCAP if it starts with '/'?
+ */
+char *initial_badenv_table[] = {
+    "IFS",
+    "LOCALDOMAIN",
+    "RES_OPTIONS",
+    "HOSTALIASES",
+    "NLSPATH",
+    "PATH_LOCALE",
+    "LD_*",
+    "_RLD*",
+#ifdef __hpux
+    "SHLIB_PATH",
+#endif /* __hpux */
+#ifdef _AIX
+    "LIBPATH",
+#endif /* _AIX */
+#ifdef HAVE_KERB4
+    "KRB_CONF*",
+    "KRBCONFDIR"
+    "KRBTKFILE",
+#endif /* HAVE_KERB4 */
+#ifdef HAVE_KERB5
+    "KRB5_CONFIG*",
+#endif /* HAVE_KERB5 */
+#ifdef HAVE_SECURID
+    "VAR_ACE",
+    "USR_ACE",
+    "DLC_ACE",
+#endif /* HAVE_SECURID */
+    "TERMINFO",
+    "TERMINFO_DIRS",
+    "TERMPATH",
+    "TERMCAP",                 /* XXX - only if it starts with '/' */
+    "ENV",
+    "BASH_ENV",
+    NULL
+};
+
+/*
+ * Default table of variables to check for '%' and '/' characters.
+ */
+char *initial_checkenv_table[] = {
+    "LC_*",
+    "LANG",
+    "LANGUAGE",
+    NULL
+};
+
+/*
+ * Zero out environment and replace with a minimal set of
+ * USER, LOGNAME, HOME, TZ, PATH (XXX - should just set path to default)
+ * May set user_path, user_shell, and/or user_prompt as side effects.
+ */
+char **
+zero_env(envp)
+    char **envp;
+{
+    char **ep, **nep;
+    static char *newenv[7];
+
+    for (ep = envp; *ep; ep++) {
+       switch (**ep) {
+           case 'H':
+               if (strncmp("HOME=", *ep, 5) == 0)
+                   break;
+               continue;
+           case 'L':
+               if (strncmp("LOGNAME=", *ep, 8) == 0)
+                   break;
+               continue;
+           case 'P':
+               if (strncmp("PATH=", *ep, 5) == 0) {
+                   user_path = *ep + 5;
+                   /* XXX - set to sane default instead of user's? */
+                   break;
+               }
+               continue;
+           case 'S':
+               if (strncmp("SHELL=", *ep, 6) == 0)
+                   user_shell = *ep + 6;
+               else if (!user_prompt && !strncmp("SUDO_PROMPT=", *ep, 12))
+                   user_prompt = *ep + 12;
+               continue;
+           case 'T':
+               if (strncmp("TZ=", *ep, 3) == 0)
+                   break;
+               continue;
+           case 'U':
+               if (strncmp("USER=", *ep, 5) == 0)
+                   break;
+               continue;
+           default:
+               continue;
+       }
+
+       /* Deal with multiply defined variables (take first instance) */
+       for (nep = newenv; *nep; nep++) {
+           if (**nep == **ep)
+               break;
+       }
+       if (*nep == NULL)
+           *nep++ = *ep;
+    }
+    return(&newenv[0]);
+}
+
+/*
+ * Given a variable and value, allocate and format an environment string.
+ */
+static char *
+format_env(var, val)
+    char *var;
+    char *val;
+{
+    char *estring, *p;
+    size_t varlen, vallen;
+
+    varlen = strlen(var);
+    vallen = strlen(val);
+    p = estring = (char *) emalloc(varlen + vallen + 2);
+    strcpy(p, var);
+    p += varlen;
+    *p++ = '=';
+    strcpy(p, val);
+
+    return(estring);
+}
+
+/*
+ * Insert str into envp.
+ * Assumes str has an '=' in it and does not check for available space!
+ */
+static void
+insert_env(envp, str)
+    char **envp;
+    char *str;
+{
+    char **ep;
+    size_t varlen;
+
+    varlen = (strchr(str, '=') - str) + 1;
+
+    for (ep = envp; *ep; ep++) {
+       if (strncmp(str, *ep, varlen) == 0) {
+           *ep = str;
+           break;
+       }
+    }
+    if (*ep == NULL) {
+       *ep++ = str;
+       *ep = NULL;
+    }
+}
+
+/*
+ * Build a new environment and ether clear potentially dangerous
+ * variables from the old one or start with a clean slate.
+ * Also adds sudo-specific variables (SUDO_*).
+ */
+char **
+rebuild_env(sudo_mode, envp)
+    int sudo_mode;
+    char **envp;
+{
+    char **newenvp, **ep, **nep, *cp, *ps1;
+    int okvar, iswild, didvar;
+    size_t env_size, len;
+    struct list_member *cur;
+
+    /* Count number of items in "env_keep" list (if any) */
+    for (len = 0, cur = def_list(I_ENV_KEEP); cur; cur = cur->next)
+       len++;
+
+    /*
+     * Either clean out the environment or reset to a safe default.
+     */
+    ps1 = NULL;
+    didvar = 0;
+    if (def_flag(I_ENV_RESET)) {
+       int keepit;
+
+       /* Alloc space for new environment. */
+       env_size = 32 + len;
+       nep = newenvp = (char **) emalloc(env_size * sizeof(char *));
+
+       /* Pull in vars we want to keep from the old environment. */
+       for (ep = envp; *ep; ep++) {
+           keepit = 0;
+           for (cur = def_list(I_ENV_KEEP); cur; cur = cur->next) {
+               len = strlen(cur->value);
+               /* Deal with '*' wildcard */
+               if (cur->value[len - 1] == '*') {
+                   len--;
+                   iswild = 1;
+               } else
+                   iswild = 0;
+               if (strncmp(cur->value, *ep, len) == 0 &&
+                   (iswild || (*ep)[len] == '=')) {
+                   /* We always preserve TERM, no special treatment needed. */
+                   if (strncmp(*ep, "TERM=", 5) != 0)
+                       keepit = 1;
+                   break;
+               }
+           }
+
+           /* For SUDO_PS1 -> PS1 conversion. */
+           if (strncmp(*ep, "SUDO_PS1=", 8) == 0)
+               ps1 = *ep + 5;
+
+           if (keepit) {
+               /* Preserve variable. */
+               switch (**ep) {
+                   case 'H':
+                       if (strncmp(*ep, "HOME=", 5) == 0)
+                           didvar |= DID_HOME;
+                           break;
+                   case 'S':
+                       if (strncmp(*ep, "SHELL=", 6) == 0)
+                           didvar |= DID_SHELL;
+                           break;
+                   case 'L':
+                       if (strncmp(*ep, "LOGNAME=", 8) == 0)
+                           didvar |= DID_LOGNAME;
+                           break;
+                   case 'U':
+                       if (strncmp(*ep, "USER=", 5) == 0)
+                           didvar |= DID_USER;
+                           break;
+               }
+               *nep++ = *ep;
+           } else {
+               /* Preserve TERM and PATH, ignore anything else. */
+               if (!(didvar & DID_TERM) && !strncmp(*ep, "TERM=", 5)) {
+                   *nep++ = *ep;
+                   didvar |= DID_TERM;
+               } else if (!(didvar & DID_PATH) && !strncmp(*ep, "PATH=", 5)) {
+                   *nep++ = *ep;
+                   didvar |= DID_PATH;
+               }
+           }
+       }
+
+       /*
+        * Add in defaults unless they were preserved from the
+        * user's environment.
+        */
+       if (!(didvar & DID_HOME))
+           *nep++ = format_env("HOME", user_dir);
+       if (!(didvar & DID_SHELL))
+           *nep++ = format_env("SHELL", sudo_user.pw->pw_shell);
+       if (!(didvar & DID_LOGNAME))
+           *nep++ = format_env("LOGNAME", user_name);
+       if (!(didvar & DID_USER))
+           *nep++ = format_env("USER", user_name);
+    } else {
+       /* Alloc space for new environment. */
+       for (env_size = 16 + len, ep = envp; *ep; ep++, env_size++)
+           ;
+       nep = newenvp = (char **) emalloc(env_size * sizeof(char *));
+
+       /*
+        * Copy envp entries as long as they don't match env_delete or
+        * env_check.
+        */
+       for (ep = envp; *ep; ep++) {
+           okvar = 1;
+
+           /* Skip anything listed in env_delete. */
+           for (cur = def_list(I_ENV_DELETE); cur && okvar; cur = cur->next) {
+               len = strlen(cur->value);
+               /* Deal with '*' wildcard */
+               if (cur->value[len - 1] == '*') {
+                   len--;
+                   iswild = 1;
+               } else
+                   iswild = 0;
+               if (strncmp(cur->value, *ep, len) == 0 &&
+                   (iswild || (*ep)[len] == '=')) {
+                   okvar = 0;
+               }
+           }
+
+           /* Check certain variables for '%' and '/' characters. */
+           for (cur = def_list(I_ENV_CHECK); cur && okvar; cur = cur->next) {
+               len = strlen(cur->value);
+               /* Deal with '*' wildcard */
+               if (cur->value[len - 1] == '*') {
+                   len--;
+                   iswild = 1;
+               } else
+                   iswild = 0;
+               if (strncmp(cur->value, *ep, len) == 0 &&
+                   (iswild || (*ep)[len] == '=') &&
+                   strpbrk(*ep, "/%")) {
+                   okvar = 0;
+               }
+           }
+
+           if (okvar) {
+               if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
+                   ps1 = *ep + 5;
+               else if (strncmp(*ep, "PATH=", 5) == 0)
+                   didvar |= DID_PATH;
+               else if (strncmp(*ep, "TERM=", 5) == 0)
+                   didvar |= DID_TERM;
+               *nep++ = *ep;
+           }
+       }
+    }
+    /* Provide default values for $TERM and $PATH if they are not set. */
+    if (!(didvar & DID_TERM))
+       *nep++ = "TERM=unknown";
+    if (!(didvar & DID_PATH))
+       *nep++ = format_env("PATH", _PATH_DEFPATH);
+    *nep = NULL;
+
+    /*
+     * At this point we must use insert_env() to modify newenvp.
+     * Access via 'nep' is not allowed (since we must check for dupes).
+     */
+
+#ifdef SECURE_PATH
+    /* Replace the PATH envariable with a secure one. */
+    insert_env(newenvp, format_env("PATH", SECURE_PATH));
+#endif
+
+    /* Set $USER and $LOGNAME to target if "set_logname" is true. */
+    if (def_flag(I_SET_LOGNAME) && runas_pw->pw_name) {
+       insert_env(newenvp, format_env("LOGNAME", runas_pw->pw_name));
+       insert_env(newenvp, format_env("USER", runas_pw->pw_name));
+    }
+
+    /* Set $HOME for `sudo -H'.  Only valid at PERM_RUNAS. */
+    if ((sudo_mode & MODE_RESET_HOME) && runas_pw->pw_dir)
+       insert_env(newenvp, format_env("HOME", runas_pw->pw_dir));
+
+    /* Set PS1 if SUDO_PS1 is set. */
+    if (ps1)
+       insert_env(newenvp, ps1);
+
+    /* Add the SUDO_COMMAND envariable (cmnd + args). */
+    if (user_args) {
+       easprintf(&cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args);
+       insert_env(newenvp, cp);
+    } else
+       insert_env(newenvp, format_env("SUDO_COMMAND", user_cmnd));
+
+    /* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
+    insert_env(newenvp, format_env("SUDO_USER", user_name));
+    easprintf(&cp, "SUDO_UID=%ld", (long) user_uid);
+    insert_env(newenvp, cp);
+    easprintf(&cp, "SUDO_GID=%ld", (long) user_gid);
+    insert_env(newenvp, cp);
+
+    return(newenvp);
+}
+
+void
+dump_badenv()
+{
+    struct list_member *cur;
+
+    puts("Default table of environment variables to clear");
+    for (cur = def_list(I_ENV_DELETE); cur; cur = cur->next)
+       printf("\t%s\n", cur->value);
+
+    puts("Default table of environment variables to sanity check");
+    for (cur = def_list(I_ENV_CHECK); cur; cur = cur->next)
+       printf("\t%s\n", cur->value);
+}
+
+void
+init_envtables()
+{
+    struct list_member *cur;
+    char **p;
+
+    /* Fill in "env_delete" variable. */
+    for (p = initial_badenv_table; *p; p++) {
+       cur = emalloc(sizeof(struct list_member));
+       cur->value = estrdup(*p);
+       cur->next = def_list(I_ENV_DELETE);
+       def_list(I_ENV_DELETE) = cur;
+    }
+
+    /* Fill in "env_check" variable. */
+    for (p = initial_checkenv_table; *p; p++) {
+       cur = emalloc(sizeof(struct list_member));
+       cur->value = estrdup(*p);
+       cur->next = def_list(I_ENV_CHECK);
+       def_list(I_ENV_CHECK) = cur;
+    }
+}
diff --git a/fileops.c b/fileops.c
new file mode 100644 (file)
index 0000000..a3dd56d
--- /dev/null
+++ b/fileops.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef HAVE_FLOCK
+# include <sys/file.h>
+#endif /* HAVE_FLOCK */
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
+#include <time.h>
+#ifdef HAVE_UTIME
+# ifdef HAVE_UTIME_H
+#  include <utime.h>
+# endif /* HAVE_UTIME_H */
+#else
+# include "emul/utime.h"
+#endif /* HAVE_UTIME */
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: fileops.c,v 1.3 2001/12/14 19:52:47 millert Exp $";
+#endif /* lint */
+
+/*
+ * Update the access and modify times on a file.
+ */
+int
+touch(path, when)
+    char *path;
+    time_t when;
+{
+#ifdef HAVE_UTIME_POSIX
+    struct utimbuf ut, *utp;
+
+    ut.actime = ut.modtime = when;
+    utp = &ut;
+#else
+    /* BSD <= 4.3 has no struct utimbuf */
+    time_t utp[2];
+
+    utp[0] = utp[1] = when;
+#endif /* HAVE_UTIME_POSIX */
+
+    return(utime(path, utp));
+}
+
+/*
+ * Lock/unlock a file.
+ */
+#ifdef HAVE_LOCKF
+int
+lock_file(fd, lockit)
+    int fd;
+    int lockit;
+{
+    int op = 0;
+
+    switch (lockit) {
+       case SUDO_LOCK:
+           op = F_LOCK;
+           break;
+       case SUDO_TLOCK:
+           op = F_TLOCK;
+           break;
+       case SUDO_UNLOCK:
+           op = F_ULOCK;
+           break;
+    }
+    return(lockf(fd, op, 0) == 0);
+}
+#elif HAVE_FLOCK
+int
+lock_file(fd, lockit)
+    int fd;
+    int lockit;
+{
+    int op = 0;
+
+    switch (lockit) {
+       case SUDO_LOCK:
+           op = LOCK_EX;
+           break;
+       case SUDO_TLOCK:
+           op = LOCK_EX | LOCK_NB;
+           break;
+       case SUDO_UNLOCK:
+           op = LOCK_UN;
+           break;
+    }
+    return(flock(fd, op) == 0);
+}
+#else
+int
+lock_file(fd, lockit)
+    int fd;
+    int lockit;
+{
+#ifdef F_SETLK
+    int func;
+    struct flock lock;
+
+    lock.l_start = 0;
+    lock.l_len = 0;
+    lock.l_pid = getpid();
+    lock.l_type = (lockit == SUDO_UNLOCK) ? F_UNLCK : F_WRLCK;
+    lock.l_whence = SEEK_SET;
+    func = (lockit == SUDO_TLOCK) ? F_SETLK : F_SETLKW;
+
+    return(fcntl(fd, func, &lock) == 0);
+#else
+    return(TRUE);
+#endif
+}
+#endif
diff --git a/find_path.c b/find_path.c
new file mode 100644 (file)
index 0000000..b4282cf
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: find_path.c,v 1.98 2001/12/14 06:40:03 millert Exp $";
+#endif /* lint */
+
+/*
+ * This function finds the full pathname for a command and
+ * stores it in a statically allocated array, filling in a pointer
+ * to the array.  Returns FOUND if the command was found, NOT_FOUND
+ * if it was not found, or NOT_FOUND_DOT if it would have been found
+ * but it is in '.' and IGNORE_DOT is set.
+ */
+int
+find_path(infile, outfile, path)
+    char *infile;              /* file to find */
+    char **outfile;            /* result parameter */
+    char *path;                        /* path to search */
+{
+    static char command[MAXPATHLEN]; /* qualified filename */
+    char *n;                   /* for traversing path */
+    char *origpath;            /* so we can free path later */
+    char *result = NULL;       /* result of path/file lookup */
+    int checkdot = 0;          /* check current dir? */
+
+    if (strlen(infile) >= MAXPATHLEN) {
+       (void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
+       exit(1);
+    }
+
+    /*
+     * If we were given a fully qualified or relative path
+     * there is no need to look at $PATH.
+     */
+    if (strchr(infile, '/')) {
+       (void) strcpy(command, infile);
+       if (sudo_goodpath(command)) {
+           *outfile = command;
+           return(FOUND);
+       } else
+           return(NOT_FOUND);
+    }
+
+    /* Use PATH passed in unless SECURE_PATH is in effect.  */
+#ifdef SECURE_PATH
+    if (!user_is_exempt())
+       path = SECURE_PATH;
+#endif /* SECURE_PATH */
+    if (path == NULL)
+       return(NOT_FOUND);
+    path = estrdup(path);
+    origpath = path;
+
+    do {
+       if ((n = strchr(path, ':')))
+           *n = '\0';
+
+       /*
+        * Search current dir last if it is in PATH This will miss sneaky
+        * things like using './' or './/' 
+        */
+       if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
+           checkdot = 1;
+           path = n + 1;
+           continue;
+       }
+
+       /*
+        * Resolve the path and exit the loop if found.
+        */
+       if (strlen(path) + strlen(infile) + 1 >= MAXPATHLEN) {
+           (void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
+           exit(1);
+       }
+       (void) sprintf(command, "%s/%s", path, infile);
+       if ((result = sudo_goodpath(command)))
+           break;
+
+       path = n + 1;
+
+    } while (n);
+    free(origpath);
+
+    /*
+     * Check current dir if dot was in the PATH
+     */
+    if (!result && checkdot) {
+       result = sudo_goodpath(infile);
+       if (result && def_flag(I_IGNORE_DOT))
+           return(NOT_FOUND_DOT);
+    }
+
+    if (result) {
+       *outfile = result;
+       return(FOUND);
+    } else
+       return(NOT_FOUND);
+}
diff --git a/fnmatch.3 b/fnmatch.3
new file mode 100644 (file)
index 0000000..d4efe72
--- /dev/null
+++ b/fnmatch.3
@@ -0,0 +1,148 @@
+.\"    $OpenBSD: fnmatch.3,v 1.7 1999/06/05 04:47:41 aaron Exp $
+.\"
+.\" Copyright (c) 1989, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Guido van Rossum.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)fnmatch.3  8.3 (Berkeley) 4/28/95
+.\"
+.Dd April 28, 1995
+.Dt FNMATCH 3
+.Os
+.Sh NAME
+.Nm fnmatch
+.Nd match filename or pathname using shell globbing rules
+.Sh SYNOPSIS
+.Fd #include <fnmatch.h>
+.Ft int
+.Fn fnmatch "const char *pattern" "const char *string" "int flags"
+.Sh DESCRIPTION
+The
+.Fn fnmatch
+function
+matches patterns according to the globbing rules used by the shell.
+It checks the string specified by the
+.Fa string
+argument to see if it matches the pattern specified by the
+.Fa pattern
+argument.
+.Pp
+The
+.Fa flags
+argument modifies the interpretation of
+.Fa pattern
+and
+.Fa string .
+The value of
+.Fa flags
+is the bitwise inclusive
+.Tn OR
+of any of the following
+constants, which are defined in the include file
+.Aq Pa fnmatch.h .
+.Bl -tag -width FNM_PATHNAME
+.It Dv FNM_NOESCAPE
+Normally, every occurrence of a backslash
+.Pq Sq \e
+followed by a character in
+.Fa pattern
+is replaced by that character.
+This is done to negate any special meaning for the character.
+If the
+.Dv FNM_NOESCAPE
+flag is set, a backslash character is treated as an ordinary character.
+.It Dv FNM_PATHNAME
+Slash characters in
+.Fa string
+must be explicitly matched by slashes in
+.Fa pattern .
+If this flag is not set, then slashes are treated as regular characters.
+.It Dv FNM_PERIOD
+Leading periods in
+.Fa string
+must be explicitly matched by periods in
+.Fa pattern .
+If this flag is not set, then leading periods are treated as regular
+characters.
+The definition of
+.Dq leading
+is related to the specification of
+.Dv FNM_PATHNAME .
+A period is always leading
+if it is the first character in
+.Fa string .
+Additionally, if
+.Dv FNM_PATHNAME
+is set,
+a period is leading
+if it immediately follows a slash.
+.It Dv FNM_LEADING_DIR
+Ignore
+.Nm /*
+rest after successful
+.Fa pattern
+matching.
+.It Dv FNM_CASEFOLD
+Ignore case distinctions in both the
+.Fa pattern
+and the
+.Fa string .
+.El
+.Sh RETURN VALUES
+The
+.Fn fnmatch
+function returns zero if
+.Fa string
+matches the pattern specified by
+.Fa pattern ,
+otherwise, it returns the value
+.Dv FNM_NOMATCH .
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr glob 3 ,
+.Xr regex 3
+.Sh STANDARDS
+The
+.Fn fnmatch
+function conforms to
+.St -p1003.2-92 .
+.Sh HISTORY
+The
+.Fn fnmatch
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The pattern
+.Ql *
+matches the empty string, even if
+.Dv FNM_PATHNAME
+is specified.
diff --git a/fnmatch.c b/fnmatch.c
new file mode 100644 (file)
index 0000000..2ccea59
--- /dev/null
+++ b/fnmatch.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+
+#include "compat.h"
+#include "emul/fnmatch.h"
+
+#undef EOS
+#define        EOS     '\0'
+
+#define        RANGE_MATCH     1
+#define        RANGE_NOMATCH   0
+#define        RANGE_ERROR     (-1)
+
+static int rangematch __P((const char *, char, int, char **));
+
+int
+fnmatch(pattern, string, flags)
+       const char *pattern, *string;
+       int flags;
+{
+       const char *stringstart;
+       char *newp;
+       char c, test;
+
+       for (stringstart = string;;)
+               switch (c = *pattern++) {
+               case EOS:
+                       if ((flags & FNM_LEADING_DIR) && *string == '/')
+                               return (0);
+                       return (*string == EOS ? 0 : FNM_NOMATCH);
+               case '?':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && (flags & FNM_PATHNAME))
+                               return (FNM_NOMATCH);
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               case '*':
+                       c = *pattern;
+                       /* Collapse multiple stars. */
+                       while (c == '*')
+                               c = *++pattern;
+
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+
+                       /* Optimize for pattern with * at end or before /. */
+                       if (c == EOS) {
+                               if (flags & FNM_PATHNAME)
+                                       return ((flags & FNM_LEADING_DIR) ||
+                                           strchr(string, '/') == NULL ?
+                                           0 : FNM_NOMATCH);
+                               else
+                                       return (0);
+                       } else if (c == '/' && (flags & FNM_PATHNAME)) {
+                               if ((string = strchr(string, '/')) == NULL)
+                                       return (FNM_NOMATCH);
+                               break;
+                       }
+
+                       /* General case, use recursion. */
+                       while ((test = *string) != EOS) {
+                               if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+                                       return (0);
+                               if (test == '/' && (flags & FNM_PATHNAME))
+                                       break;
+                               ++string;
+                       }
+                       return (FNM_NOMATCH);
+               case '[':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && (flags & FNM_PATHNAME))
+                               return (FNM_NOMATCH);
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+
+                       switch (rangematch(pattern, *string, flags, &newp)) {
+                       case RANGE_ERROR:
+                               /* not a good range, treat as normal text */
+                               goto normal;
+                       case RANGE_MATCH:
+                               pattern = newp;
+                               break;
+                       case RANGE_NOMATCH:
+                               return (FNM_NOMATCH);
+                       }
+                       ++string;
+                       break;
+               case '\\':
+                       if (!(flags & FNM_NOESCAPE)) {
+                               if ((c = *pattern++) == EOS) {
+                                       c = '\\';
+                                       --pattern;
+                               }
+                       }
+                       /* FALLTHROUGH */
+               default:
+               normal:
+                       if (c != *string && !((flags & FNM_CASEFOLD) &&
+                                (tolower((unsigned char)c) ==
+                                tolower((unsigned char)*string))))
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               }
+       /* NOTREACHED */
+}
+
+static int
+#ifdef __STDC__
+rangematch(const char *pattern, char test, int flags, char **newp)
+#else
+rangematch(pattern, test, flags, newp)
+       const char *pattern;
+       char test;
+       int flags;
+       char **newp;
+#endif
+{
+       int negate, ok;
+       char c, c2;
+
+       /*
+        * A bracket expression starting with an unquoted circumflex
+        * character produces unspecified results (IEEE 1003.2-1992,
+        * 3.13.2).  This implementation treats it like '!', for
+        * consistency with the regular expression syntax.
+        * J.T. Conklin (conklin@ngai.kaleida.com)
+        */
+       if ((negate = (*pattern == '!' || *pattern == '^')))
+               ++pattern;
+
+       if (flags & FNM_CASEFOLD)
+               test = tolower((unsigned char)test);
+
+       /*
+        * A right bracket shall lose its special meaning and represent
+        * itself in a bracket expression if it occurs first in the list.
+        * -- POSIX.2 2.8.3.2
+        */
+       ok = 0;
+       c = *pattern++;
+       do {
+               if (c == '\\' && !(flags & FNM_NOESCAPE))
+                       c = *pattern++;
+               if (c == EOS)
+                       return (RANGE_ERROR);
+               if (c == '/' && (flags & FNM_PATHNAME))
+                       return (RANGE_NOMATCH);
+               if ((flags & FNM_CASEFOLD))
+                       c = tolower((unsigned char)c);
+               if (*pattern == '-'
+                   && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+                       pattern += 2;
+                       if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+                               c2 = *pattern++;
+                       if (c2 == EOS)
+                               return (RANGE_ERROR);
+                       if (flags & FNM_CASEFOLD)
+                               c2 = tolower((unsigned char)c2);
+                       if (c <= test && test <= c2)
+                               ok = 1;
+               } else if (c == test)
+                       ok = 1;
+       } while ((c = *pattern++) != ']');
+
+       *newp = (char *)pattern;
+       return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+}
diff --git a/getcwd.c b/getcwd.c
new file mode 100644 (file)
index 0000000..ca7ae66
--- /dev/null
+++ b/getcwd.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 1989, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>   
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#include "compat.h"
+
+#ifndef dirfd
+#  define dirfd(dirp)  ((dirp)->dd_fd)
+#endif
+
+#define        ISDOT(dp) \
+       (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
+           (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: getcwd.c,v 1.22 2001/12/14 19:52:47 millert Exp $";
+#endif /* lint */
+
+char *
+getcwd(pt, size)
+       char *pt;
+       size_t size;
+{
+       struct dirent *dp;
+       DIR *dir = NULL;
+       dev_t dev;
+       ino_t ino;
+       int first;
+       char *bpt, *bup;
+       struct stat s;
+       dev_t root_dev;
+       ino_t root_ino;
+       size_t ptsize, upsize;
+       int save_errno;
+       char *ept, *eup, *up;
+
+       /*
+        * If no buffer specified by the user, allocate one as necessary.
+        * If a buffer is specified, the size has to be non-zero.  The path
+        * is built from the end of the buffer backwards.
+        */
+       if (pt) {
+               ptsize = 0;
+               if (!size) {
+                       errno = EINVAL;
+                       return (NULL);
+               }
+               ept = pt + size;
+       } else {
+               if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
+                       return (NULL);
+               ept = pt + ptsize;
+       }
+       bpt = ept - 1;
+       *bpt = '\0';
+
+       /*
+        * Allocate bytes (1024 - malloc space) for the string of "../"'s.
+        * Should always be enough (it's 340 levels).  If it's not, allocate
+        * as necessary.  Special * case the first stat, it's ".", not "..".
+        */
+       if ((up = malloc(upsize = 1024 - 4)) == NULL)
+               goto err;
+       eup = up + MAXPATHLEN;
+       bup = up;
+       up[0] = '.';
+       up[1] = '\0';
+
+       /* Save root values, so know when to stop. */
+       if (stat("/", &s))
+               goto err;
+       root_dev = s.st_dev;
+       root_ino = s.st_ino;
+
+       errno = 0;                      /* XXX readdir has no error return. */
+
+       for (first = 1;; first = 0) {
+               /* Stat the current level. */
+               if (lstat(up, &s))
+                       goto err;
+
+               /* Save current node values. */
+               ino = s.st_ino;
+               dev = s.st_dev;
+
+               /* Check for reaching root. */
+               if (root_dev == dev && root_ino == ino) {
+                       *--bpt = '/';
+                       /*
+                        * It's unclear that it's a requirement to copy the
+                        * path to the beginning of the buffer, but it's always
+                        * been that way and stuff would probably break.
+                        */
+                       bcopy(bpt, pt, ept - bpt);
+                       free(up);
+                       return (pt);
+               }
+
+               /*
+                * Build pointer to the parent directory, allocating memory
+                * as necessary.  Max length is 3 for "../", the largest
+                * possible component name, plus a trailing NULL.
+                */
+               if (bup + 3  + MAXNAMLEN + 1 >= eup) {
+                       char *nup;
+
+                       if ((nup = realloc(up, upsize *= 2)) == NULL)
+                               goto err;
+                       up = nup;
+                       bup = up;
+                       eup = up + upsize;
+               }
+               *bup++ = '.';
+               *bup++ = '.';
+               *bup = '\0';
+
+               /* Open and stat parent directory. */
+               if (!(dir = opendir(up)) || fstat(dirfd(dir), &s))
+                       goto err;
+
+               /* Add trailing slash for next directory. */
+               *bup++ = '/';
+
+               /*
+                * If it's a mount point, have to stat each element because
+                * the inode number in the directory is for the entry in the
+                * parent directory, not the inode number of the mounted file.
+                */
+               save_errno = 0;
+               if (s.st_dev == dev) {
+                       for (;;) {
+                               if (!(dp = readdir(dir)))
+                                       goto notfound;
+                               if (dp->d_fileno == ino)
+                                       break;
+                       }
+               } else
+                       for (;;) {
+                               if (!(dp = readdir(dir)))
+                                       goto notfound;
+                               if (ISDOT(dp))
+                                       continue;
+                               bcopy(dp->d_name, bup, NAMLEN(dp) + 1);
+
+                               /* Save the first error for later. */
+                               if (lstat(up, &s)) {
+                                       if (!save_errno)
+                                               save_errno = errno;
+                                       errno = 0;
+                                       continue;
+                               }
+                               if (s.st_dev == dev && s.st_ino == ino)
+                                       break;
+                       }
+
+               /*
+                * Check for length of the current name, preceding slash,
+                * leading slash.
+                */
+               if (bpt - pt <= NAMLEN(dp) + (first ? 1 : 2)) {
+                       size_t len, off;
+                       char *npt;
+
+                       if (!ptsize) {
+                               errno = ERANGE;
+                               goto err;
+                       }
+                       off = bpt - pt;
+                       len = ept - bpt;
+                       if ((npt = realloc(pt, ptsize *= 2)) == NULL)
+                               goto err;
+                       pt = npt;
+                       bpt = pt + off;
+                       ept = pt + ptsize;
+                       bcopy(bpt, ept - len, len);
+                       bpt = ept - len;
+               }
+               if (!first)
+                       *--bpt = '/';
+               bpt -= NAMLEN(dp);
+               bcopy(dp->d_name, bpt, NAMLEN(dp));
+               (void)closedir(dir);
+
+               /* Truncate any file name. */
+               *bup = '\0';
+       }
+
+notfound:
+       /*
+        * If readdir set errno, use it, not any saved error; otherwise,
+        * didn't find the current directory in its parent directory, set
+        * errno to ENOENT.
+        */
+       if (!errno)
+               errno = save_errno ? save_errno : ENOENT;
+       /* FALLTHROUGH */
+err:
+       if (ptsize)
+               free(pt);
+       if (up)
+               free(up);
+       if (dir)
+               (void)closedir(dir);
+       return (NULL);
+}
diff --git a/getspwuid.c b/getspwuid.c
new file mode 100644 (file)
index 0000000..8b328c7
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#ifdef HAVE_GETSPNAM
+# include <shadow.h>
+#endif /* HAVE_GETSPNAM */
+#ifdef HAVE_GETPRPWNAM
+# ifdef __hpux
+#  undef MAXINT
+#  include <hpsecurity.h>
+# else
+#  include <sys/security.h>
+# endif /* __hpux */
+# include <prot.h>
+#endif /* HAVE_GETPRPWNAM */
+#ifdef HAVE_GETPWANAM
+# include <sys/label.h>
+# include <sys/audit.h>
+# include <pwdadj.h>
+#endif /* HAVE_GETPWANAM */
+#ifdef HAVE_GETAUTHUID
+# include <auth.h>
+#endif /* HAVE_GETAUTHUID */
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: getspwuid.c,v 1.62 2002/01/15 23:43:59 millert Exp $";
+#endif /* lint */
+
+/*
+ * Global variables (yuck)
+ */
+#if defined(HAVE_GETPRPWNAM) && defined(__alpha)
+int crypt_type = INT_MAX;
+#endif /* HAVE_GETPRPWNAM && __alpha */
+
+
+/*
+ * Local functions not visible outside getspwuid.c
+ */
+static struct passwd *sudo_pwdup       __P((struct passwd *));
+
+
+/*
+ * Return a copy of the encrypted password for the user described by pw.
+ * If shadow passwords are in use, look in the shadow file.
+ */
+char *
+sudo_getepw(pw)
+    struct passwd *pw;
+{
+    char *epw;
+
+    /* If there is a function to check for shadow enabled, use it... */
+#ifdef HAVE_ISCOMSEC
+    if (!iscomsec())
+       return(estrdup(pw->pw_passwd));
+#endif /* HAVE_ISCOMSEC */
+#ifdef HAVE_ISSECURE
+    if (!issecure())
+       return(estrdup(pw->pw_passwd));
+#endif /* HAVE_ISSECURE */
+
+    epw = NULL;
+#ifdef HAVE_GETPRPWNAM
+    {
+       struct pr_passwd *spw;
+
+       setprpwent();
+       if ((spw = getprpwnam(pw->pw_name)) && spw->ufld.fd_encrypt) {
+# ifdef __alpha
+           crypt_type = spw->ufld.fd_oldcrypt;
+# endif /* __alpha */
+           epw = estrdup(spw->ufld.fd_encrypt);
+       }
+       endprpwent();
+       if (epw)
+           return(epw);
+    }
+#endif /* HAVE_GETPRPWNAM */
+#ifdef HAVE_GETSPNAM
+    {
+       struct spwd *spw;
+
+       setspent();
+       if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp)
+           epw = estrdup(spw->sp_pwdp);
+       endspent();
+       if (epw)
+           return(epw);
+    }
+#endif /* HAVE_GETSPNAM */
+#ifdef HAVE_GETSPWUID
+    {
+       struct s_passwd *spw;
+
+       setspwent();
+       if ((spw = getspwuid(pw->pw_uid)) && spw->pw_passwd)
+           epw = estrdup(spw->pw_passwd);
+       endspwent();
+       if (epw)
+           return(epw);
+    }
+#endif /* HAVE_GETSPWUID */
+#ifdef HAVE_GETPWANAM
+    {
+       struct passwd_adjunct *spw;
+
+       setpwaent();
+       if ((spw = getpwanam(pw->pw_name)) && spw->pwa_passwd)
+           epw = estrdup(spw->pwa_passwd);
+       endpwaent();
+       if (epw)
+           return(epw);
+    }
+#endif /* HAVE_GETPWANAM */
+#ifdef HAVE_GETAUTHUID
+    {
+       AUTHORIZATION *spw;
+
+       setauthent();
+       if ((spw = getauthuid(pw->pw_uid)) && spw->a_password)
+           epw = estrdup(spw->a_password);
+       endauthent();
+       if (epw)
+           return(epw);
+    }
+#endif /* HAVE_GETAUTHUID */
+
+    /* Fall back on normal password. */
+    return(estrdup(pw->pw_passwd));
+}
+
+/*
+ * Dynamically allocate space for a struct password and the constituent parts
+ * that we care about.  Fills in pw_passwd from shadow file if necessary.
+ */
+static struct passwd *
+sudo_pwdup(pw)
+    struct passwd *pw;
+{
+    struct passwd *local_pw;
+
+    /* Allocate space for a local copy of pw. */
+    local_pw = (struct passwd *) emalloc(sizeof(struct passwd));
+
+    /*
+     * Copy the struct passwd and the interesting strings...
+     */
+    (void) memcpy(local_pw, pw, sizeof(struct passwd));
+    local_pw->pw_name = estrdup(pw->pw_name);
+    local_pw->pw_dir = estrdup(pw->pw_dir);
+    local_pw->pw_gecos = estrdup(pw->pw_gecos);
+#ifdef HAVE_LOGIN_CAP_H
+    local_pw->pw_class = estrdup(pw->pw_class);
+#endif
+
+    /* If shell field is empty, expand to _PATH_BSHELL. */
+    if (local_pw->pw_shell[0] == '\0')
+       local_pw->pw_shell = _PATH_BSHELL;
+    else
+       local_pw->pw_shell = estrdup(pw->pw_shell);
+
+    /* pw_passwd gets a shadow password if applicable */
+    local_pw->pw_passwd = sudo_getepw(pw);
+
+    return(local_pw);
+}
+
+/*
+ * Get a password entry by uid and allocate space for it.
+ * Fills in pw_passwd from shadow file if necessary.
+ */
+struct passwd *
+sudo_getpwuid(uid)
+    uid_t uid;
+{
+    struct passwd *pw;
+
+    if ((pw = getpwuid(uid)) == NULL)
+       return(NULL);
+    else
+       return(sudo_pwdup(pw));
+}
+
+/*
+ * Get a password entry by name and allocate space for it.
+ * Fills in pw_passwd from shadow file if necessary.
+ */
+struct passwd *
+sudo_getpwnam(name)
+    const char *name;
+{
+    struct passwd *pw;
+
+    if ((pw = getpwnam(name)) == NULL)
+       return(NULL);
+    else
+       return(sudo_pwdup(pw));
+}
diff --git a/goodpath.c b/goodpath.c
new file mode 100644 (file)
index 0000000..96b8bd5
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2001
+ *     Todd C. Miller <Todd.Miller@courtesan.com>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: goodpath.c,v 1.38 2001/12/14 19:52:47 millert Exp $";
+#endif /* lint */
+
+/*
+ * Verify that path is a normal file and executable by root.
+ */
+char *
+sudo_goodpath(path)
+    const char *path;
+{
+    struct stat sb;
+
+    /* Check for brain damage */
+    if (path == NULL || path[0] == '\0')
+       return(NULL);
+
+    if (stat(path, &sb))
+       return(NULL);
+
+    /* Make sure path describes an executable regular file. */
+    if (!S_ISREG(sb.st_mode) || !(sb.st_mode & 0000111)) {
+       errno = EACCES;
+       return(NULL);
+    }
+
+    return((char *)path);
+}
diff --git a/indent.pro b/indent.pro
new file mode 100644 (file)
index 0000000..b8269d8
--- /dev/null
@@ -0,0 +1,35 @@
+-di4
+-br
+-cdb
+-ce
+-d0
+-ei
+-lp
+-npcs
+-ps
+-npsl
+-sc
+-TYYSTYPE
+-TLIST
+-TLINK
+-Tu_char
+-Tu_short
+-Tu_int
+-Tu_long
+-Tushort
+-Tuint
+-Tdaddr_t
+-Tcaddr_t
+-Tino_t
+-Tswblk_t
+-Tsize_t
+-Ttime_t
+-Tdev_t
+-Toff_t
+-Tuid_t
+-Tgid_t
+-Tfixpt_t
+-Tkey_t
+-Tpaddr_t
+-Tfd_mask
+-Tfd_set
diff --git a/ins_2001.h b/ins_2001.h
new file mode 100644 (file)
index 0000000..bd29863
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: ins_2001.h,v 1.28 1999/07/31 16:19:45 millert Exp $
+ */
+
+#ifndef _SUDO_INS_2001_H
+#define _SUDO_INS_2001_H
+
+    /*
+     * HAL insults (paraphrased) from 2001.
+     */
+
+    "Just what do you think you're doing Dave?",
+    "It can only be attributed to human error.",
+    "That's something I cannot allow to happen.",
+    "My mind is going. I can feel it.",
+    "Sorry about this, I know it's a bit silly.",
+    "Take a stress pill and think things over.",
+    "This mission is too important for me to allow you to jeopardize it.",
+    "I feel much better now.",
+
+#endif /* _SUDO_INS_2001_H */
diff --git a/ins_classic.h b/ins_classic.h
new file mode 100644 (file)
index 0000000..975f381
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: ins_classic.h,v 1.28 1999/07/31 16:19:45 millert Exp $
+ */
+
+#ifndef _SUDO_INS_CLASSIC_H
+#define _SUDO_INS_CLASSIC_H
+
+    /*
+     * Insults from the original sudo(8).
+     */
+
+    "Wrong!  You cheating scum!",
+    "No soap, honkie-lips.",
+    "Where did you learn to type?",
+    "Are you on drugs?",
+    "My pet ferret can type better than you!",
+    "You type like i drive.",
+    "Do you think like you type?",
+    "Your mind just hasn't been the same since the electro-shock, has it?",
+
+#endif /* _SUDO_INS_CLASSIC_H */
diff --git a/ins_csops.h b/ins_csops.h
new file mode 100644 (file)
index 0000000..3baac82
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: ins_csops.h,v 1.27 1999/07/31 16:19:45 millert Exp $
+ */
+
+#ifndef _SUDO_INS_CSOPS_H
+#define _SUDO_INS_CSOPS_H
+
+    /*
+     * CSOps insults (may be site dependent).
+     */
+
+    "Maybe if you used more than just two fingers...",
+    "BOB says:  You seem to have forgotten your passwd, enter another!",
+    "stty: unknown mode: doofus",
+    "I can't hear you -- I'm using the scrambler.",
+    "The more you drive -- the dumber you get.",
+    "Listen, burrito brains, I don't have time to listen to this trash.",
+    "I've seen penguins that can type better than that.",
+    "Have you considered trying to match wits with a rutabaga?",
+    "You speak an infinite deal of nothing",
+
+#endif /* _SUDO_INS_CSOPS_H */
diff --git a/ins_goons.h b/ins_goons.h
new file mode 100644 (file)
index 0000000..4cf6462
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: ins_goons.h,v 1.28 1999/07/31 16:19:45 millert Exp $
+ */
+
+#ifndef _SUDO_INS_GOONS_H
+#define _SUDO_INS_GOONS_H
+
+    /*
+     * Insults from the "Goon Show."
+     */
+
+    "You silly, twisted boy you.",
+    "He has fallen in the water!",
+    "We'll all be murdered in our beds!",
+    "You can't come in. Our tiger has got flu",
+    "I don't wish to know that.",
+    "What, what, what, what, what, what, what, what, what, what?",
+    "You can't get the wood, you know.",
+    "You'll starve!",
+    "... and it used to be so popular...",
+    "Pauses for audience applause, not a sausage",
+    "Hold it up to the light --- not a brain in sight!",
+    "Have a gorilla...",
+    "There must be cure for it!",
+    "There's a lot of it about, you know.",
+    "You do that again and see what happens...",
+    "Ying Tong Iddle I Po",
+    "Harm can come to a young lad like that!",
+    "And with that remarks folks, the case of the Crown vs yourself was proven.",
+    "Speak English you fool --- there are no subtitles in this scene.",
+    "You gotta go owwwww!",
+    "I have been called worse.",
+    "It's only your word against mine.",
+    "I think ... err ... I think ... I think I'll go home",
+
+#endif /* _SUDO_INS_GOONS_H */
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..5a6d399
--- /dev/null
@@ -0,0 +1,227 @@
+#! /bin/sh
+
+## (From INN-1.4, written by Rich Salz)
+##  $Revision: 1.9 $
+##  A script to install files and directories.
+
+PROGNAME=`basename $0`
+
+##  Paths to programs.  CHOWN, STRIP and WHOAMI are checked below.
+CHOWN=chown
+CHGRP=chgrp
+CHMOD=chmod
+CP=cp
+LN=ln
+MKDIR=mkdir
+MV=mv
+RM=rm
+STRIP=strip
+WHOAMI="echo root"
+
+##  Some systems don't support -x, so we have to use -f.
+for d in /sbin /etc /usr/sbin /usr/etc; do
+    if [ -f $d/chown ]; then
+       CHOWN=${d}/chown
+       break
+    fi
+done
+
+for d in /usr/bin /bin /usr/ucb /usr/bsd; do
+    if [ -f $d/whoami ]; then
+       WHOAMI=${d}/whoami
+       break
+    elif [ -f $d/id ]; then
+       WHOAMI=${d}/id | sed -n 's/^[^(]*(\([^)]*\)).*/\1/p'
+    fi
+done
+
+for d in /usr/ccs/bin /usr/bin /bin; do
+    if [ -f $d/strip ]; then
+       STRIP=${d}/strip
+       break
+    fi
+done
+
+##  Defaults.
+CHOWNIT=false
+CHGROUPIT=false
+CHMODIT=false
+STRIPIT=false
+BACKIT=false
+TOUCHIT=true
+SAVESRC=false
+
+case `${WHOAMI}` in
+root)
+    ROOT=true
+    ;;
+*)
+    ROOT=false
+    ;;
+esac
+
+##  Process JCL.
+MORETODO=true
+while ${MORETODO} ; do
+    case X"$1" in
+    X-b)
+       BACKIT=true
+       BACKUP="$2"
+       shift
+       ;;
+    X-b*)
+       BACKIT=true
+       BACKUP=`expr "$1" : '-b\(.*\)'`
+       ;;
+    X-c)
+       SAVESRC=true
+       ;;
+    X-g)
+       GROUP="$2"
+       CHGROUPIT=true
+       shift
+       ;;
+    X-g*)
+       GROUP=`expr "$1" : '-g\(.*\)'`
+       CHGROUPIT=true
+       ;;
+    X-G)
+       GROUP="$2"
+       shift
+       ${ROOT} && CHGROUPIT=true
+       ;;
+    X-G*)
+       if ${ROOT} ; then
+           GROUP=`expr "$1" : '-g\(.*\)'`
+           CHGROUPIT=true
+       fi
+       ;;
+    X-m)
+       MODE="$2"
+       CHMODIT=true
+       shift
+       ;;
+    X-m*)
+       MODE=`expr "$1" : '-m\(.*\)'`
+       CHMODIT=true
+       ;;
+    X-M)
+       MODE="$2"
+       ${ROOT} && CHMODIT=true
+       shift
+       ;;
+    X-M*)
+       MODE=`expr "$1" : '-m\(.*\)'`
+       ${ROOT} && CHMODIT=true
+       ;;
+    X-n)
+       TOUCHIT=false
+       ;;
+    X-o)
+       OWNER="$2"
+       CHOWNIT=true
+       shift
+       ;;
+    X-o*)
+       OWNER=`expr "$1" : '-o\(.*\)'`
+       CHOWNIT=true
+       ;;
+    X-O)
+       OWNER="$2"
+       shift
+       ${ROOT} && CHOWNIT=true
+       ;;
+    X-O*)
+       if ${ROOT} ; then
+           OWNER=`expr "$1" : '-o\(.*\)'`
+           CHOWNIT=true
+       fi
+       ;;
+    X-s)
+       STRIPIT=true
+       ;;
+    X--)
+       shift
+       MORETODO=false
+       ;;
+    X-*)
+       echo "${PROGNAME}:  Unknown flag $1" 1>&2
+       exit 1
+       ;;
+    *)
+       MORETODO=false
+       ;;
+    esac
+    ${MORETODO} && shift
+done
+
+##  Process arguments.
+if [ $# -ne 2 ] ; then
+    echo "Usage:  ${PROGNAME} [flags] source destination"
+    exit 1
+fi
+
+##  Making a directory?
+if [ X"$1" = X. ] ; then
+    DEST="$2"
+    if [ ! -d "${DEST}" ] ; then
+       ${MKDIR} "${DEST}" || exit 1
+    fi
+    if ${CHOWNIT} ; then
+       ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+    fi
+    if ${CHGROUPIT} ; then
+       ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+    fi
+    if ${CHMODIT} ; then
+       umask 0
+       ${CHMOD} "${MODE}"  "${DEST}" || exit 1
+    fi
+    exit 0
+fi
+
+##  Get the destination and a temp file in the destination diretory.
+if [ -d "$2" ] ; then
+    DEST="$2/$1"
+    TEMP="$2/$$.tmp"
+else
+    DEST="$2"
+    TEMP="`expr "$2" : '\(.*\)/.*'`/$$.tmp"
+fi
+
+##  If not given the same name, we must try to copy.
+if [ X"$1" != X"$2" -o $SAVESRC ] ; then
+    if cmp -s "$1" "${DEST}" ; then
+       ##  Files are same; touch or not.
+       ${TOUCHIT} && touch "${DEST}"
+    else
+       ##  If destination exists and we wish to backup, link to backup.
+       if [ -f "${DEST}" ] ; then
+           if ${BACKIT} ; then
+               ${RM} -f "${DEST}${BACKUP}"
+               ${LN} "${DEST}" "${DEST}${BACKUP}"
+           fi
+       fi
+       ##  Copy source to the right dir, then move to right spot.
+       ##  Done in two parts so we can hope for atomicity.
+       ${RM} -f "${TEMP}" || exit 1
+       ${CP} "$1" "${TEMP}" || exit 1
+       ${MV} -f "${TEMP}" "${DEST}" || exit 1
+    fi
+fi
+
+##  Strip and set the modes.
+if ${STRIPIT} ; then
+    ${STRIP} "${DEST}" || exit 1
+fi
+if ${CHOWNIT} ; then
+    ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+fi
+if ${CHGROUPIT} ; then
+    ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+fi
+if ${CHMODIT} ; then
+    umask 0
+    ${CHMOD} "${MODE}"  "${DEST}" || exit 1
+fi
+exit 0
diff --git a/insults.h b/insults.h
new file mode 100644 (file)
index 0000000..69271a6
--- /dev/null
+++ b/insults.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: insults.h,v 1.45 1999/12/06 06:47:13 millert Exp $
+ */
+
+#ifndef _SUDO_INSULTS_H
+#define _SUDO_INSULTS_H
+
+#if defined(HAL_INSULTS) || defined(GOONS_INSULTS) || defined(CLASSIC_INSULTS) || defined(CSOPS_INSULTS)
+
+/*
+ * Use one or more set of insults as determined by configure
+ */
+
+char *insults[] = {
+
+# ifdef HAL_INSULTS
+#  include "ins_2001.h"
+# endif
+
+# ifdef GOONS_INSULTS
+#  include "ins_goons.h"
+# endif
+
+# ifdef CLASSIC_INSULTS
+#  include "ins_classic.h"
+# endif
+
+# ifdef CSOPS_INSULTS
+#  include "ins_csops.h"
+# endif
+
+    (char *) 0
+
+};
+
+/*
+ * How may I insult you?  Let me count the ways...
+ */
+#define NOFINSULTS (sizeof(insults) / sizeof(insults[0]) - 1)
+
+/*
+ * return a pseudo-random insult.
+ */
+#define INSULT         (insults[time(NULL) % NOFINSULTS])
+
+#endif /* HAL_INSULTS || GOONS_INSULTS || CLASSIC_INSULTS || CSOPS_INSULTS */
+
+#endif /* _SUDO_INSULTS_H */
diff --git a/interfaces.c b/interfaces.c
new file mode 100644 (file)
index 0000000..eda0d60
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Supress a warning w/ gcc on Digital UN*X.
+ * The system headers should really do this....
+ */
+#if defined(__osf__) && !defined(__cplusplus)
+struct mbuf;
+struct rtentry;
+#endif
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#if defined(HAVE_SYS_SOCKIO_H) && !defined(SIOCGIFCONF)
+# include <sys/sockio.h>
+#endif
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <netdb.h>
+#include <errno.h>
+#ifdef _ISC
+# include <sys/stream.h>
+# include <sys/sioctl.h>
+# include <sys/stropts.h>
+# include <net/errno.h>
+# define STRSET(cmd, param, len) {strioctl.ic_cmd=(cmd);\
+                                strioctl.ic_dp=(param);\
+                                strioctl.ic_timout=0;\
+                                strioctl.ic_len=(len);}
+#endif /* _ISC */
+#ifdef _MIPS
+# include <net/soioctl.h>
+#endif /* _MIPS */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#ifdef HAVE_GETIFADDRS
+# include <ifaddrs.h>
+#endif
+
+#include "sudo.h"
+#include "interfaces.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: interfaces.c,v 1.63 2002/01/18 19:17:07 millert Exp $";
+#endif /* lint */
+
+
+#ifdef HAVE_GETIFADDRS
+
+/*
+ * Allocate and fill in the interfaces global variable with the
+ * machine's ip addresses and netmasks.
+ */
+void
+load_interfaces()
+{
+    struct ifaddrs *ifa, *ifaddrs;
+    /* XXX - sockaddr_in6 sin6; */
+    struct sockaddr_in *sin;
+    int i;
+
+    if (getifaddrs(&ifaddrs))
+       return;
+
+    /* Allocate space for the interfaces list. */
+    for (ifa = ifaddrs; ifa -> ifa_next; ifa = ifa -> ifa_next) {
+       /* Skip interfaces marked "down" and "loopback". */
+       if (ifa->ifa_addr == NULL || !(ifa->ifa_flags & IFF_UP) ||
+           (ifa->ifa_flags & IFF_LOOPBACK))
+           continue;
+
+       switch(ifa->ifa_addr->sa_family) {
+           /* XXX - AF_INET6 */
+           case AF_INET:
+               num_interfaces++;
+               break;
+       }
+    }
+    interfaces =
+       (struct interface *) emalloc(sizeof(struct interface) * num_interfaces);
+
+    /* Store the ip addr / netmask pairs. */
+    for (ifa = ifaddrs, i = 0; ifa -> ifa_next; ifa = ifa -> ifa_next) {
+       /* Skip interfaces marked "down" and "loopback". */
+       if (ifa->ifa_addr == NULL || !(ifa->ifa_flags & IFF_UP) ||
+           (ifa->ifa_flags & IFF_LOOPBACK))
+               continue;
+
+       switch(ifa->ifa_addr->sa_family) {
+           /* XXX - AF_INET6 */
+           case AF_INET:
+               sin = (struct sockaddr_in *)ifa->ifa_addr;
+               memcpy(&interfaces[i].addr, &sin->sin_addr,
+                   sizeof(struct in_addr));
+               sin = (struct sockaddr_in *)ifa->ifa_netmask;
+               memcpy(&interfaces[i].netmask, &sin->sin_addr,
+                   sizeof(struct in_addr));
+               i++;
+               break;
+       }
+    }
+#ifdef HAVE_FREEIFADDRS
+    freeifaddrs(ifaddrs);
+#else
+    free(ifaddrs);
+#endif
+}
+
+#elif defined(SIOCGIFCONF) && !defined(STUB_LOAD_INTERFACES)
+
+/*
+ * Allocate and fill in the interfaces global variable with the
+ * machine's ip addresses and netmasks.
+ */
+void
+load_interfaces()
+{
+    struct ifconf *ifconf;
+    struct ifreq *ifr, ifr_tmp;
+    struct sockaddr_in *sin;
+    int sock, n, i;
+    size_t len = sizeof(struct ifconf) + BUFSIZ;
+    char *previfname = "", *ifconf_buf = NULL;
+#ifdef _ISC
+    struct strioctl strioctl;
+#endif /* _ISC */
+
+    sock = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sock < 0) {
+       (void) fprintf(stderr, "%s: cannot open socket: %s\n",
+           Argv[0], strerror(errno));
+       exit(1);
+    }
+
+    /*
+     * Get interface configuration or return (leaving num_interfaces 0)
+     */
+    for (;;) {
+       ifconf_buf = erealloc(ifconf_buf, len);
+       ifconf = (struct ifconf *) ifconf_buf;
+       ifconf->ifc_len = len - sizeof(struct ifconf);
+       ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf));
+
+       /* Networking may not be installed in kernel... */
+#ifdef _ISC
+       STRSET(SIOCGIFCONF, (caddr_t) ifconf, len);
+       if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) {
+#else
+       if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0) {
+#endif /* _ISC */
+           free(ifconf_buf);
+           (void) close(sock);
+           return;
+       }
+
+       /* Break out of loop if we have a big enough buffer. */
+       if (ifconf->ifc_len + sizeof(struct ifreq) < len)
+           break;
+       len += BUFSIZ;
+    }
+
+    /* Allocate space for the maximum number of interfaces that could exist. */
+    n = ifconf->ifc_len / sizeof(struct ifreq);
+    interfaces = (struct interface *) emalloc(sizeof(struct interface) * n);
+
+    /* For each interface, store the ip address and netmask. */
+    for (i = 0; i < ifconf->ifc_len; ) {
+       /* Get a pointer to the current interface. */
+       ifr = (struct ifreq *) &ifconf->ifc_buf[i];
+
+       /* Set i to the subscript of the next interface. */
+       i += sizeof(struct ifreq);
+#ifdef HAVE_SA_LEN
+       if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
+           i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
+#endif /* HAVE_SA_LEN */
+
+       /* Skip duplicates and interfaces with NULL addresses. */
+       sin = (struct sockaddr_in *) &ifr->ifr_addr;
+       if (sin->sin_addr.s_addr == 0 ||
+           strncmp(previfname, ifr->ifr_name, sizeof(ifr->ifr_name) - 1) == 0)
+           continue;
+
+       if (ifr->ifr_addr.sa_family != AF_INET)
+               continue;
+
+#ifdef SIOCGIFFLAGS
+       memset(&ifr_tmp, 0, sizeof(ifr_tmp));
+       strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1);
+       if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr_tmp) < 0)
+#endif
+           ifr_tmp = *ifr;
+       
+       /* Skip interfaces marked "down" and "loopback". */
+       if (!(ifr_tmp.ifr_flags & IFF_UP) || (ifr_tmp.ifr_flags & IFF_LOOPBACK))
+               continue;
+
+       sin = (struct sockaddr_in *) &ifr->ifr_addr;
+       interfaces[num_interfaces].addr.s_addr = sin->sin_addr.s_addr;
+
+       /* Stash the name of the interface we saved. */
+       previfname = ifr->ifr_name;
+
+       /* Get the netmask. */
+       (void) memset(&ifr_tmp, 0, sizeof(ifr_tmp));
+       strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1);
+#ifdef SIOCGIFNETMASK
+#ifdef _ISC
+       STRSET(SIOCGIFNETMASK, (caddr_t) &ifr_tmp, sizeof(ifr_tmp));
+       if (ioctl(sock, I_STR, (caddr_t) &strioctl) == 0) {
+#else
+       if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifr_tmp) == 0) {
+#endif /* _ISC */
+           sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr;
+
+           interfaces[num_interfaces].netmask.s_addr = sin->sin_addr.s_addr;
+       } else {
+#else
+       {
+#endif /* SIOCGIFNETMASK */
+           if (IN_CLASSC(interfaces[num_interfaces].addr.s_addr))
+               interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSC_NET);
+           else if (IN_CLASSB(interfaces[num_interfaces].addr.s_addr))
+               interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSB_NET);
+           else
+               interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSA_NET);
+       }
+
+       /* Only now can we be sure it was a good/interesting interface. */
+       num_interfaces++;
+    }
+
+    /* If the expected size < real size, realloc the array. */
+    if (n != num_interfaces) {
+       if (num_interfaces != 0)
+           interfaces = (struct interface *) erealloc(interfaces,
+               sizeof(struct interface) * num_interfaces);
+       else
+           free(interfaces);
+    }
+    free(ifconf_buf);
+    (void) close(sock);
+}
+
+#else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */
+
+/*
+ * Stub function for those without SIOCGIFCONF
+ */
+void
+load_interfaces()
+{
+    return;
+}
+
+#endif /* SIOCGIFCONF && !STUB_LOAD_INTERFACES */
+
+void
+dump_interfaces()
+{
+    int i;
+
+    puts("Local IP address and netmask pairs:");
+    for (i = 0; i < num_interfaces; i++)
+       printf("\t%s / 0x%x\n", inet_ntoa(interfaces[i].addr),
+           ntohl(interfaces[i].netmask.s_addr));
+}
diff --git a/interfaces.h b/interfaces.h
new file mode 100644 (file)
index 0000000..e04809e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: interfaces.h,v 1.5 2001/12/14 19:54:56 millert Exp $
+ */
+
+#ifndef _SUDO_INTERFACES_H
+#define _SUDO_INTERFACES_H
+
+/*
+ * IP address and netmask pairs for checking against local interfaces.
+ */
+struct interface {
+    struct in_addr addr;
+    struct in_addr netmask;
+};
+
+/*
+ * Prototypes for external functions.
+ */
+void load_interfaces   __P((void));
+void dump_interfaces   __P((void));
+
+/*
+ * Definitions for external variables.
+ */
+#ifndef MAIN
+extern struct interface *interfaces;
+extern int num_interfaces;
+#endif
+
+#endif /* _SUDO_INTERFACES_H */
diff --git a/lex.yy.c b/lex.yy.c
new file mode 100644 (file)
index 0000000..653b8f8
--- /dev/null
+++ b/lex.yy.c
@@ -0,0 +1,2556 @@
+/*     $OpenBSD: flex.skl,v 1.6 2001/01/05 18:26:23 millert Exp $      */
+
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/cvs-sudo/sudo/lex.yy.c,v 1.37 2002/03/16 00:45:21 millert Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <errno.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+#ifdef __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               *yy_cp = yy_hold_char; \
+               YY_RESTORE_YY_MORE_OFFSET \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+       };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;                /* whether we need to initialize */
+static int yy_start = 0;       /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
+       *yy_cp = '\0'; \
+       yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 35
+#define YY_END_OF_BUFFER 36
+static yyconst short int yy_accept[299] =
+    {   0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,   36,   25,   31,   30,   29,   34,   25,   20,
+       34,   25,   26,   25,   25,   25,   25,   28,   27,   21,
+       21,   21,   34,   21,   21,   21,   21,   21,   22,   34,
+       22,   23,   22,   22,   22,   22,   22,   21,   21,   21,
+       34,    1,   11,   10,   11,   10,   10,   34,   34,    2,
+        8,    8,    8,    3,    8,    4,   34,   25,    0,   31,
+       29,    0,   33,   17,    0,   16,    0,   24,   24,    0,
+       25,   25,   25,   25,   25,   21,   21,   21,   25,   32,
+       25,   25,   25,   25,   25,   22,    0,   22,   17,    0,
+
+       16,    0,   22,    0,   22,   22,   22,   22,   22,   21,
+       21,   21,   22,    1,   11,   11,    9,    9,    0,    2,
+        8,    0,    8,    0,    0,    5,    6,    8,    8,    0,
+       25,   25,   25,   21,   21,   25,   25,   25,   25,   25,
+       22,   22,   22,   21,   21,    7,    7,    0,    7,    8,
+       25,   25,   25,   25,   25,   21,   21,   25,   25,   25,
+       22,   22,   22,   22,   22,   21,   21,    7,   25,   25,
+       25,   21,   21,   25,   25,   22,   22,   22,   21,   21,
+       25,   25,   25,   25,   25,   21,   21,   25,   25,   22,
+       22,   22,   22,   22,   21,   21,   18,   18,   18,   21,
+
+        0,   15,   25,   25,   18,   18,   18,   21,   25,   18,
+       18,   18,   18,   21,   25,   12,   22,   18,   18,   18,
+       18,   21,   25,   19,   19,   19,    0,   14,   25,   12,
+       22,   19,   19,   19,   25,   25,   19,   19,   19,   19,
+       19,   13,   22,   22,   19,   19,   19,   19,   19,   25,
+       25,   25,   19,   19,   22,   22,   22,   19,   19,   25,
+       25,   25,   25,   25,   22,   22,   22,   22,   22,   25,
+       25,   25,   22,   22,   22,   25,   25,   25,   25,   25,
+       22,   22,   22,   22,   22,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,    0
+
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    6,    1,    7,    1,    1,    8,
+        9,    1,   10,   11,   12,   13,   14,   15,   16,   17,
+       18,   19,   20,   21,   21,   21,   21,   22,    1,    1,
+       23,    1,    1,   24,   25,   26,   27,   28,   26,   26,
+       26,   29,   26,   26,   26,   26,   26,   30,   31,   32,
+       26,   33,   34,   26,   35,   26,   36,   26,   26,   26,
+        1,   37,    1,    1,   38,    1,   39,   40,   40,   41,
+
+       42,   43,   40,   40,   44,   40,   40,   45,   46,   47,
+       48,   40,   40,   49,   50,   51,   52,   40,   40,   40,
+       40,   40,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[53] =
+    {   0,
+        1,    2,    2,    3,    1,    4,    1,    3,    3,    1,
+        2,    5,    1,    1,    5,    5,    5,    5,    5,    5,
+        5,    6,    4,    3,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    7,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8
+    } ;
+
+static yyconst short int yy_base[319] =
+    {   0,
+        0,   26,   61,    0,  112,  113,  120,  156,  192,  243,
+      294,  330,  627,  589,  623, 1808,  619,  619,  584, 1808,
+     1808,  583, 1808,  124,  355,  119,  134, 1808, 1808,  380,
+      586,  579,  417,  557,  558,  551,  546,  545,  556,    0,
+      553, 1808,  551,  160,  429,  155,  170,  454,  555,  545,
+      491,  565,    0, 1808,  561,    0, 1808,  307,   54,    0,
+      526,  343,   93, 1808,  104, 1808,  142,  521,  514,  555,
+      552,  544, 1808,  507,  537,  505,  560,  315,  503,  583,
+      593,  143,    0,    0,  503,    0,  489,  485,  144, 1808,
+      118,  140,  154,  145,  163,  480,  629,    0,  475,  652,
+
+      474,  675,  353,  698,  708,  186,    0,    0,  489,    0,
+      477,  467,  211,  496,    0,  492,  199, 1808,  204,    0,
+      431,  248,  380,  214,  215, 1808, 1808,  427,  219,  251,
+      733,  742,  751,  438,  428,   88,   21,  166,  171,  175,
+      760,  769,  778,  436,  421,  416, 1808,  221,  454,  613,
+      785,  242,  810,  819,  828,  409,  386,  178,  223,  226,
+      837,  264,  846,  855,  864,  360,  345,  265,  873,  882,
+      891,  335,  328,  241,  224,  900,  909,  918,  321,  323,
+      925,  290,  950,  959,  968,  311,  306,  227,  174,  977,
+      301,  986,  995, 1004,  285,  341, 1012,  414,  488,  288,
+
+      356, 1808,  278,  270, 1037,  511,  534,  283, 1044,  323,
+        0,    0,  247,  357,  228,  365, 1068,  351,    0,    0,
+      207,  362, 1077, 1086, 1095, 1104,  402, 1808,  275, 1808,
+     1113, 1122, 1131, 1140, 1147,  313, 1172, 1181, 1190, 1199,
+      559,  190, 1208,  414, 1217, 1226, 1235, 1244,  564, 1253,
+     1262, 1271, 1280,  421, 1289, 1298, 1307, 1316,  518, 1323,
+      439, 1348, 1357, 1366, 1373,  441, 1398, 1407, 1416, 1425,
+     1434, 1443, 1452, 1461, 1470, 1479,  560, 1488, 1497, 1506,
+     1515,  565, 1524, 1533, 1542, 1551, 1560, 1569, 1578, 1587,
+     1596,  172, 1603,  627,  129, 1626,  650, 1808, 1663, 1671,
+
+     1679, 1687, 1695, 1703, 1711, 1719, 1727,  158, 1735, 1743,
+     1751, 1759,  109, 1767, 1775, 1783, 1791, 1799
+    } ;
+
+static yyconst short int yy_def[319] =
+    {   0,
+      298,    1,  298,    3,    1,    1,  299,  299,  300,  300,
+      301,  301,  298,  302,  298,  298,  298,  303,  304,  298,
+      298,  305,  298,  306,  302,   25,   25,  298,  298,   25,
+       30,   30,  302,   30,   30,   30,   30,   30,  307,  308,
+      309,  298,  310,  311,  307,   45,   45,   45,   48,   48,
+      307,  298,  312,  298,  312,  312,  298,  298,  298,  313,
+      314,  315,  314,  298,  314,  298,  316,  302,  302,  298,
+      298,  303,  298,  304,  304,  305,  305,  306,  317,  302,
+      302,  302,   25,   25,   25,   30,   30,   30,  302,  298,
+      302,  302,  302,  302,  302,  307,  307,  308,  309,  309,
+
+      310,  310,  311,  307,  307,  307,   45,   45,   45,   48,
+       48,   48,  307,  298,  312,  312,  298,  298,  298,  313,
+      314,  314,  315,  318,  315,  298,  298,  314,  314,  298,
+       25,   25,   25,   30,   30,  302,  302,  302,  302,  302,
+       45,   45,   45,   48,   48,  314,  298,  318,  315,  315,
+      302,  302,   25,   25,   25,   30,   30,  302,  302,  302,
+       45,  307,   45,   45,   45,   48,   48,  318,   25,   25,
+       25,   30,   30,  302,  302,   45,   45,   45,   48,   48,
+      302,  302,   25,   25,   25,   30,   30,  302,  302,   45,
+      307,   45,   45,   45,   48,   48,  302,  197,  197,   30,
+
+      298,  298,  302,  302,   45,  205,  205,   48,  302,  302,
+      197,  197,  197,   30,  302,  302,  205,  307,  205,  205,
+      205,   48,   25,   25,   25,   25,  298,  298,  302,  298,
+       45,   45,   45,   45,  302,  302,   25,   25,   25,   25,
+      302,  302,   45,  307,   45,   45,   45,   45,  307,   25,
+       25,   25,   25,  302,   45,   45,   45,   45,  307,  302,
+      302,   25,   25,   25,  307,  307,   45,   45,   45,   25,
+       25,   25,   45,   45,   45,   25,  302,   25,   25,   25,
+       45,  307,   45,   45,   45,   25,   25,   25,   45,   45,
+       45,  302,  302,  302,  307,  307,  307,    0,  298,  298,
+
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298
+    } ;
+
+static yyconst short int yy_nxt[1861] =
+    {   0,
+       14,   15,   16,   17,   14,   18,   19,   20,   21,   22,
+       23,   14,   14,   24,   25,   26,   27,   25,   25,   25,
+       25,   28,   29,   21,   30,   30,   30,   30,   30,   31,
+       30,   32,   30,   30,   30,   30,   33,   14,   14,   14,
+       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
+       14,   14,   34,   35,   36,  119,   90,   69,   37,  159,
+       38,   39,   15,   16,   17,   39,   40,   41,   21,   42,
+       43,   23,   39,   39,   44,   45,   46,   47,   45,   45,
+       45,   45,   28,   29,   21,   48,   48,   48,   48,   48,
+       49,   48,   50,   48,   48,   48,   48,   51,   39,   39,
+
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   52,   52,  126,  120,   21,   21,   21,
+       21,   15,   54,   55,   69,   56,  127,   79,  158,  122,
+       57,   79,   79,   83,   83,   83,   83,   83,   83,   83,
+      122,   57,   56,  129,   90,  119,   90,   79,   84,   84,
+       84,   84,   84,   85,   69,   81,   58,   15,   54,   55,
+       80,   56,   98,   79,  136,   97,   57,   79,   79,  107,
+      107,  107,  107,  107,  107,  107,   69,   57,   56,   69,
+       69,   69,  137,   79,  108,  108,  108,  108,  108,  109,
+       69,  139,   58,   15,   16,   17,  104,   18,  105,   69,
+
+      119,   90,   69,  138,  140,  119,   90,   69,   69,  160,
+       69,   69,  119,   90,   69,  174,  158,  124,  147,  149,
+      119,   90,   97,  158,  204,  168,   69,   96,   59,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,   15,   16,   17,   97,   18,  121,
+      148,  150,   79,  121,  151,  122,   79,  148,  121,   69,
+       69,   79,   69,   69,   69,  188,  229,   68,  189,  147,
+      121,  203,   79,   79,  175,  158,  161,   69,   69,   59,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,   60,   15,   16,   17,   62,   18,
+
+       97,  148,  181,   63,   64,   65,   69,  201,  117,   90,
+      222,   69,  118,  190,   69,  214,   66,  118,   79,  216,
+      208,  215,   79,   79,  242,  235,   69,  202,  118,  118,
+       67,   15,   16,   17,   62,   18,  209,   97,   79,   63,
+       64,   65,  201,  118,  124,  124,  200,  121,  124,   69,
+      196,   80,   66,  124,  195,  187,   79,  201,  227,   69,
+       79,   79,  202,  227,  217,  124,   67,   81,  186,   82,
+       82,   82,   82,   82,   82,   82,   79,  202,  228,  125,
+      180,  124,  124,  228,  146,  124,  230,   97,  230,  104,
+      124,   69,   68,  179,   86,   86,   86,   86,   86,   86,
+
+       86,   69,  124,  227,   86,   86,   86,   86,   86,   86,
+       86,   86,   86,   86,   86,   86,  125,   86,   89,   90,
+       68,  173,   68,  228,   68,   68,  243,   68,  211,  211,
+      211,  211,  211,  211,  211,  254,  254,  254,   68,   68,
+       68,  105,  172,  106,  106,  106,  106,  106,  106,  106,
+       97,  260,  122,  265,  167,  124,  124,   69,  146,  124,
+      166,  157,  156,  122,  124,   97,   96,  122,  110,  110,
+      110,  110,  110,  110,  110,   69,  124,   97,  110,  110,
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
+      125,  110,  113,   90,   96,  116,   96,  114,   96,   96,
+
+      145,   96,  212,  212,  212,  212,  212,  213,  144,   96,
+      102,  100,   96,   96,   96,   68,   97,   68,  135,   68,
+      134,   68,   68,   68,   68,  219,  219,  219,  219,  219,
+      219,  219,  259,  259,  259,   68,   68,   68,   74,  130,
+       74,   77,   74,   75,   74,   74,   73,   74,  220,  220,
+      220,  220,  220,  221,   97,   71,   70,   69,   74,   74,
+       74,   76,  122,   76,  116,   76,  114,   76,   76,  112,
+       76,  235,  276,  254,  254,  254,  243,  281,  259,  259,
+      259,   76,   76,   76,   78,  111,   68,  102,   78,  100,
+       68,   68,   97,   78,   95,   69,   69,   94,   93,   92,
+
+       97,   97,   91,   88,   78,   78,   68,  131,  132,  133,
+      131,  131,  131,  131,  124,  124,   87,  149,  124,   77,
+       75,   73,   71,  124,   70,   69,  298,  298,  298,   69,
+       96,  298,   96,  298,   96,  124,   96,   96,  298,   96,
+      298,  292,  292,  292,  292,  292,  292,  298,  298,  125,
+       96,   96,   96,   99,  298,   99,  298,   99,  298,   99,
+       99,  298,   99,   69,  295,  295,  295,  295,  295,  295,
+      298,  298,  298,   99,   99,   99,  101,  298,  101,  298,
+      101,  298,  101,  101,  298,  101,   97,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  101,  101,  101,  103,
+
+      298,   96,  298,  103,  298,   96,   96,  298,  103,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  103,
+      103,   96,  141,  142,  143,  141,  141,  141,  141,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,   97,  151,  298,  152,  152,  152,
+      152,  152,  152,  152,  151,  298,  153,  153,  153,  153,
+      153,  153,  153,  151,  298,  154,  154,  154,  154,  154,
+      155,  152,  161,  298,  162,  162,  162,  162,  162,  162,
+      162,  161,  298,  163,  163,  163,  163,  163,  163,  163,
+      161,  298,  164,  164,  164,  164,  164,  165,  162,  169,
+
+      170,  171,  169,  169,  169,  169,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,   69,  151,  298,  152,  152,  152,  152,  152,  152,
+      152,  151,  298,  152,  152,  152,  152,  152,  152,  152,
+      151,  298,  152,  152,  152,  152,  152,  152,   68,   96,
+      298,  176,  177,  178,  176,  176,  176,  176,  161,  298,
+      162,  162,  162,  162,  162,  162,  162,  161,  298,  162,
+      162,  162,  162,  162,  162,  162,  161,  298,  162,  162,
+      162,  162,  162,  162,   96,  181,  298,  182,  182,  182,
+      182,  182,  182,  182,  181,  298,  183,  183,  183,  183,
+
+      183,  183,  183,  181,  298,  184,  184,  184,  184,  184,
+      185,  182,  190,  298,  191,  191,  191,  191,  191,  191,
+      191,  190,  298,  192,  192,  192,  192,  192,  192,  192,
+      190,  298,  193,  193,  193,  193,  193,  194,  191,  197,
+      198,  199,  197,  197,  197,  197,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,   69,  181,  298,  182,  182,  182,  182,  182,  182,
+      182,  181,  298,  182,  182,  182,  182,  182,  182,  182,
+      181,  298,  182,  182,  182,  182,  182,  182,   68,   96,
+      298,  205,  206,  207,  205,  205,  205,  205,  190,  298,
+
+      191,  191,  191,  191,  191,  191,  191,  190,  298,  191,
+      191,  191,  191,  191,  191,  191,  190,  298,  191,  191,
+      191,  191,  191,  191,   96,  209,  210,  210,  210,  210,
+      210,  210,  210,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,   69,   96,
+      217,  218,  218,  218,  218,  218,  218,  218,  223,  224,
+      225,  226,  223,  223,  223,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+       69,   96,  231,  232,  233,  234,  231,  231,  231,  235,
+      298,  236,  236,  236,  236,  236,  236,  236,  235,  298,
+
+      237,  237,  237,  237,  237,  237,  237,  235,  298,  238,
+      238,  238,  238,  238,  239,  240,  235,  298,  241,  241,
+      241,  236,  236,  236,  236,  243,  298,  244,  244,  244,
+      244,  244,  244,  244,  243,  298,  245,  245,  245,  245,
+      245,  245,  245,  243,  298,  246,  246,  246,  246,  246,
+      247,  248,  243,  298,  249,  249,  249,  244,  244,  244,
+      244,  250,  251,  252,  250,  250,  250,  250,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,   69,  235,  298,  240,  240,  240,  240,
+      240,  240,  240,  235,  298,  240,  240,  240,  240,  240,
+
+      240,  240,  235,  298,  240,  240,  240,  240,  240,  240,
+      253,  235,  298,  253,  253,  253,  253,  253,  253,  253,
+       96,  298,  255,  256,  257,  255,  255,  255,  255,  243,
+      298,  248,  248,  248,  248,  248,  248,  248,  243,  298,
+      248,  248,  248,  248,  248,  248,  248,  243,  298,  248,
+      248,  248,  248,  248,  248,  258,  243,  298,  258,  258,
+      258,  258,  258,  258,  258,  260,  298,  261,  261,  261,
+      261,  261,  261,  261,  260,  298,  262,  262,  262,  262,
+      262,  262,  262,  260,  298,  263,  263,  263,  263,  263,
+      264,  261,   68,  298,  253,  253,  253,  253,  253,  253,
+
+      253,  265,  298,  266,  266,  266,  266,  266,  266,  266,
+      265,  298,  267,  267,  267,  267,  267,  267,  267,  265,
+      298,  268,  268,  268,  268,  268,  269,  266,   96,  298,
+      258,  258,  258,  258,  258,  258,  258,  270,  271,  272,
+      270,  270,  270,  270,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,   69,
+      260,  298,  261,  261,  261,  261,  261,  261,  261,  260,
+      298,  261,  261,  261,  261,  261,  261,  261,  260,  298,
+      261,  261,  261,  261,  261,  261,   68,  273,  274,  275,
+      273,  273,  273,  273,  298,  298,  298,  298,  298,  298,
+
+      298,  298,  298,  298,  298,  298,  298,  298,  298,   97,
+      265,  298,  266,  266,  266,  266,  266,  266,  266,  265,
+      298,  266,  266,  266,  266,  266,  266,  266,  265,  298,
+      266,  266,  266,  266,  266,  266,   96,  276,  298,  277,
+      277,  277,  277,  277,  277,  277,  276,  298,  278,  278,
+      278,  278,  278,  278,  278,  276,  298,  279,  279,  279,
+      279,  279,  280,  277,  281,  298,  282,  282,  282,  282,
+      282,  282,  282,  281,  298,  283,  283,  283,  283,  283,
+      283,  283,  281,  298,  284,  284,  284,  284,  284,  285,
+      282,   68,  298,  286,  287,  288,  286,  286,  286,  286,
+
+      276,  298,  277,  277,  277,  277,  277,  277,  277,  276,
+      298,  277,  277,  277,  277,  277,  277,  277,  276,  298,
+      277,  277,  277,  277,  277,  277,   68,   96,  298,  289,
+      290,  291,  289,  289,  289,  289,  281,  298,  282,  282,
+      282,  282,  282,  282,  282,  281,  298,  282,  282,  282,
+      282,  282,  282,  282,  281,  298,  282,  282,  282,  282,
+      282,  282,   96,   68,  298,  292,  292,  292,  292,  292,
+      292,  292,   68,  298,  286,  286,  286,  286,  286,  286,
+      286,   68,  298,  293,  293,  293,  293,  293,  294,  292,
+       96,  298,  295,  295,  295,  295,  295,  295,  295,   96,
+
+      298,  289,  289,  289,  289,  289,  289,  289,   96,  298,
+      296,  296,  296,  296,  296,  297,  295,  292,  292,  292,
+      292,  292,  292,  292,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,   69,
+      295,  295,  295,  295,  295,  295,  295,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,   97,   53,   53,   53,   53,   53,   53,   53,
+       53,   21,   21,   21,   21,   21,   21,   21,   21,   61,
+       61,   61,   61,   61,   61,   61,   61,   68,  298,  298,
+      298,   68,  298,   68,   68,   72,   72,   72,   72,   72,
+
+       72,   72,   72,   74,  298,  298,  298,   74,  298,   74,
+       74,   76,  298,  298,  298,   76,  298,   76,   76,   78,
+      298,   78,  298,   78,  298,   78,   78,   96,  298,  298,
+      298,   96,  298,   96,   96,   99,  298,  298,  298,   99,
+      298,   99,   99,  101,  298,  298,  298,  101,  298,  101,
+      101,  103,  298,  103,  298,  103,  298,  103,  103,  115,
+      298,  115,  115,  115,  298,  298,  115,  121,  298,  121,
+      298,  121,  121,  121,  121,  123,  123,  123,  123,  123,
+      123,  123,  123,  128,  128,  128,  128,  128,  128,  128,
+      128,   79,  298,   79,  298,   79,  298,   79,   79,  124,
+
+      124,  124,  124,  124,  124,  124,  124,   13,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298
+    } ;
+
+static yyconst short int yy_chk[1861] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    2,    2,    2,   59,   59,  137,    2,  137,
+        2,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    5,    6,   63,  313,    5,    6,    5,
+        6,    7,    7,    7,  136,    7,   65,   24,  136,   63,
+        7,   24,   24,   26,   26,   26,   26,   26,   26,   26,
+       65,    7,    7,   67,   67,   89,   89,   24,   27,   27,
+       27,   27,   27,   27,   91,   82,    7,    8,    8,    8,
+       24,    8,  308,   44,   91,  295,    8,   44,   44,   46,
+       46,   46,   46,   46,   46,   46,   92,    8,    8,   82,
+       89,   94,   92,   44,   47,   47,   47,   47,   47,   47,
+       93,   94,    8,    9,    9,    9,   44,    9,  106,   95,
+
+      117,  117,  138,   93,   95,  119,  119,  139,  292,  139,
+      189,  140,  113,  113,  158,  158,  138,  125,  124,  125,
+      129,  129,  106,  140,  189,  148,  242,  221,    9,    9,
+        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
+        9,    9,    9,    9,   10,   10,   10,  113,   10,  122,
+      124,  125,  130,  122,  152,  129,  130,  148,  122,  159,
+      175,  130,  160,  188,  215,  174,  215,  213,  175,  168,
+      122,  188,  130,  130,  159,  160,  162,  174,  152,   10,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   10,   10,   10,   11,   11,   11,   11,   11,
+
+      162,  168,  182,   11,   11,   11,  204,  187,   58,   58,
+      208,  229,   58,  191,  203,  200,   11,   58,   78,  204,
+      195,  203,   78,   78,  229,  236,  182,  187,   58,   58,
+       11,   12,   12,   12,   12,   12,  210,  191,   78,   12,
+       12,   12,  196,   58,   62,   62,  186,   62,   62,  236,
+      180,   78,   12,   62,  179,  173,  103,  201,  214,  210,
+      103,  103,  196,  222,  218,   62,   12,   25,  172,   25,
+       25,   25,   25,   25,   25,   25,  103,  201,  214,   62,
+      167,  123,  123,  222,  123,  123,  216,  218,  216,  103,
+      123,   25,   30,  166,   30,   30,   30,   30,   30,   30,
+
+       30,  216,  123,  227,   30,   30,   30,   30,   30,   30,
+       30,   30,   30,   30,   30,   30,  123,   30,   33,   33,
+       33,  157,   33,  227,   33,   33,  244,   33,  198,  198,
+      198,  198,  198,  198,  198,  254,  254,  254,   33,   33,
+       33,   45,  156,   45,   45,   45,   45,   45,   45,   45,
+      244,  261,  146,  266,  145,  149,  149,  254,  149,  149,
+      144,  135,  134,  128,  149,   45,   48,  121,   48,   48,
+       48,   48,   48,   48,   48,  261,  149,  266,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+      149,   48,   51,   51,   51,  116,   51,  114,   51,   51,
+
+      112,   51,  199,  199,  199,  199,  199,  199,  111,  109,
+      101,   99,   51,   51,   51,   69,   96,   69,   88,   69,
+       87,   69,   69,   85,   69,  206,  206,  206,  206,  206,
+      206,  206,  259,  259,  259,   69,   69,   69,   75,   79,
+       75,   76,   75,   74,   75,   75,   72,   75,  207,  207,
+      207,  207,  207,  207,  259,   71,   70,   68,   75,   75,
+       75,   77,   61,   77,   55,   77,   52,   77,   77,   50,
+       77,  241,  277,  241,  241,  241,  249,  282,  249,  249,
+      249,   77,   77,   77,   80,   49,   80,   43,   80,   41,
+       80,   80,   39,   80,   38,  241,  277,   37,   36,   35,
+
+      249,  282,   34,   32,   80,   80,   80,   81,   81,   81,
+       81,   81,   81,   81,  150,  150,   31,  150,  150,   22,
+       19,   18,   17,  150,   15,   14,   13,    0,    0,   81,
+       97,    0,   97,    0,   97,  150,   97,   97,    0,   97,
+        0,  294,  294,  294,  294,  294,  294,    0,    0,  150,
+       97,   97,   97,  100,    0,  100,    0,  100,    0,  100,
+      100,    0,  100,  294,  297,  297,  297,  297,  297,  297,
+        0,    0,    0,  100,  100,  100,  102,    0,  102,    0,
+      102,    0,  102,  102,    0,  102,  297,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  102,  102,  102,  104,
+
+        0,  104,    0,  104,    0,  104,  104,    0,  104,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  104,
+      104,  104,  105,  105,  105,  105,  105,  105,  105,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  105,  131,    0,  131,  131,  131,
+      131,  131,  131,  131,  132,    0,  132,  132,  132,  132,
+      132,  132,  132,  133,    0,  133,  133,  133,  133,  133,
+      133,  133,  141,    0,  141,  141,  141,  141,  141,  141,
+      141,  142,    0,  142,  142,  142,  142,  142,  142,  142,
+      143,    0,  143,  143,  143,  143,  143,  143,  143,  151,
+
+      151,  151,  151,  151,  151,  151,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  151,  153,    0,  153,  153,  153,  153,  153,  153,
+      153,  154,    0,  154,  154,  154,  154,  154,  154,  154,
+      155,    0,  155,  155,  155,  155,  155,  155,  155,  161,
+        0,  161,  161,  161,  161,  161,  161,  161,  163,    0,
+      163,  163,  163,  163,  163,  163,  163,  164,    0,  164,
+      164,  164,  164,  164,  164,  164,  165,    0,  165,  165,
+      165,  165,  165,  165,  165,  169,    0,  169,  169,  169,
+      169,  169,  169,  169,  170,    0,  170,  170,  170,  170,
+
+      170,  170,  170,  171,    0,  171,  171,  171,  171,  171,
+      171,  171,  176,    0,  176,  176,  176,  176,  176,  176,
+      176,  177,    0,  177,  177,  177,  177,  177,  177,  177,
+      178,    0,  178,  178,  178,  178,  178,  178,  178,  181,
+      181,  181,  181,  181,  181,  181,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  181,  183,    0,  183,  183,  183,  183,  183,  183,
+      183,  184,    0,  184,  184,  184,  184,  184,  184,  184,
+      185,    0,  185,  185,  185,  185,  185,  185,  185,  190,
+        0,  190,  190,  190,  190,  190,  190,  190,  192,    0,
+
+      192,  192,  192,  192,  192,  192,  192,  193,    0,  193,
+      193,  193,  193,  193,  193,  193,  194,    0,  194,  194,
+      194,  194,  194,  194,  194,  197,  197,  197,  197,  197,
+      197,  197,  197,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  197,  205,
+      205,  205,  205,  205,  205,  205,  205,  205,  209,  209,
+      209,  209,  209,  209,  209,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      209,  217,  217,  217,  217,  217,  217,  217,  217,  223,
+        0,  223,  223,  223,  223,  223,  223,  223,  224,    0,
+
+      224,  224,  224,  224,  224,  224,  224,  225,    0,  225,
+      225,  225,  225,  225,  225,  225,  226,    0,  226,  226,
+      226,  226,  226,  226,  226,  231,    0,  231,  231,  231,
+      231,  231,  231,  231,  232,    0,  232,  232,  232,  232,
+      232,  232,  232,  233,    0,  233,  233,  233,  233,  233,
+      233,  233,  234,    0,  234,  234,  234,  234,  234,  234,
+      234,  235,  235,  235,  235,  235,  235,  235,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  235,  237,    0,  237,  237,  237,  237,
+      237,  237,  237,  238,    0,  238,  238,  238,  238,  238,
+
+      238,  238,  239,    0,  239,  239,  239,  239,  239,  239,
+      239,  240,    0,  240,  240,  240,  240,  240,  240,  240,
+      243,    0,  243,  243,  243,  243,  243,  243,  243,  245,
+        0,  245,  245,  245,  245,  245,  245,  245,  246,    0,
+      246,  246,  246,  246,  246,  246,  246,  247,    0,  247,
+      247,  247,  247,  247,  247,  247,  248,    0,  248,  248,
+      248,  248,  248,  248,  248,  250,    0,  250,  250,  250,
+      250,  250,  250,  250,  251,    0,  251,  251,  251,  251,
+      251,  251,  251,  252,    0,  252,  252,  252,  252,  252,
+      252,  252,  253,    0,  253,  253,  253,  253,  253,  253,
+
+      253,  255,    0,  255,  255,  255,  255,  255,  255,  255,
+      256,    0,  256,  256,  256,  256,  256,  256,  256,  257,
+        0,  257,  257,  257,  257,  257,  257,  257,  258,    0,
+      258,  258,  258,  258,  258,  258,  258,  260,  260,  260,
+      260,  260,  260,  260,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  260,
+      262,    0,  262,  262,  262,  262,  262,  262,  262,  263,
+        0,  263,  263,  263,  263,  263,  263,  263,  264,    0,
+      264,  264,  264,  264,  264,  264,  264,  265,  265,  265,
+      265,  265,  265,  265,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  265,
+      267,    0,  267,  267,  267,  267,  267,  267,  267,  268,
+        0,  268,  268,  268,  268,  268,  268,  268,  269,    0,
+      269,  269,  269,  269,  269,  269,  269,  270,    0,  270,
+      270,  270,  270,  270,  270,  270,  271,    0,  271,  271,
+      271,  271,  271,  271,  271,  272,    0,  272,  272,  272,
+      272,  272,  272,  272,  273,    0,  273,  273,  273,  273,
+      273,  273,  273,  274,    0,  274,  274,  274,  274,  274,
+      274,  274,  275,    0,  275,  275,  275,  275,  275,  275,
+      275,  276,    0,  276,  276,  276,  276,  276,  276,  276,
+
+      278,    0,  278,  278,  278,  278,  278,  278,  278,  279,
+        0,  279,  279,  279,  279,  279,  279,  279,  280,    0,
+      280,  280,  280,  280,  280,  280,  280,  281,    0,  281,
+      281,  281,  281,  281,  281,  281,  283,    0,  283,  283,
+      283,  283,  283,  283,  283,  284,    0,  284,  284,  284,
+      284,  284,  284,  284,  285,    0,  285,  285,  285,  285,
+      285,  285,  285,  286,    0,  286,  286,  286,  286,  286,
+      286,  286,  287,    0,  287,  287,  287,  287,  287,  287,
+      287,  288,    0,  288,  288,  288,  288,  288,  288,  288,
+      289,    0,  289,  289,  289,  289,  289,  289,  289,  290,
+
+        0,  290,  290,  290,  290,  290,  290,  290,  291,    0,
+      291,  291,  291,  291,  291,  291,  291,  293,  293,  293,
+      293,  293,  293,  293,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  293,
+      296,  296,  296,  296,  296,  296,  296,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  296,  299,  299,  299,  299,  299,  299,  299,
+      299,  300,  300,  300,  300,  300,  300,  300,  300,  301,
+      301,  301,  301,  301,  301,  301,  301,  302,    0,    0,
+        0,  302,    0,  302,  302,  303,  303,  303,  303,  303,
+
+      303,  303,  303,  304,    0,    0,    0,  304,    0,  304,
+      304,  305,    0,    0,    0,  305,    0,  305,  305,  306,
+        0,  306,    0,  306,    0,  306,  306,  307,    0,    0,
+        0,  307,    0,  307,  307,  309,    0,    0,    0,  309,
+        0,  309,  309,  310,    0,    0,    0,  310,    0,  310,
+      310,  311,    0,  311,    0,  311,    0,  311,  311,  312,
+        0,  312,  312,  312,    0,    0,  312,  314,    0,  314,
+        0,  314,  314,  314,  314,  315,  315,  315,  315,  315,
+      315,  315,  315,  316,  316,  316,  316,  316,  316,  316,
+      316,  317,    0,  317,    0,  317,    0,  317,  317,  318,
+
+      318,  318,  318,  318,  318,  318,  318,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298,
+      298,  298,  298,  298,  298,  298,  298,  298,  298,  298
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "parse.lex"
+#define INITIAL 0
+#line 2 "parse.lex"
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * This code is derived from software contributed by Chris Jepeway
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <ctype.h>
+#include "sudo.h"
+#include "parse.h"
+#include <sudo.tab.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: lex.yy.c,v 1.37 2002/03/16 00:45:21 millert Exp $";
+#endif /* lint */
+
+#undef yywrap          /* guard against a yywrap macro */
+
+extern YYSTYPE yylval;
+extern int clearaliases;
+int sudolineno = 1;
+static int sawspace = 0;
+static int arg_len = 0;
+static int arg_size = 0;
+
+static void fill               __P((char *, int));
+static void fill_cmnd          __P((char *, int));
+static void fill_args          __P((char *, int, int));
+extern void reset_aliases      __P((void));
+extern void yyerror            __P((char *));
+
+/* realloc() to size + COMMANDARGINC to make room for command args */
+#define COMMANDARGINC  64
+
+#ifdef TRACELEXER
+#define LEXTRACE(msg)  fputs(msg, stderr)
+#else
+#define LEXTRACE(msg)
+#endif
+/* XXX - convert GOTRUNAS to exclusive state (GOTDEFS cannot be) */
+#define GOTRUNAS 1
+
+#define GOTDEFS 2
+
+#define GOTCMND 3
+
+#define STARTDEFS 4
+
+#define INDEFS 5
+
+#line 984 "lex.yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#ifdef __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( yy_current_buffer->yy_is_interactive ) \
+               { \
+               int c = '*', n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       if ( yyleng > 0 ) \
+               yy_current_buffer->yy_at_bol = \
+                               (yytext[yyleng - 1] == '\n'); \
+       YY_USER_ACTION
+
+YY_DECL
+       {
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+
+#line 113 "parse.lex"
+
+#line 1140 "lex.yy.c"
+
+       if ( yy_init )
+               {
+               yy_init = 0;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
+
+               yy_load_buffer_state();
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = yy_c_buf_p;
+
+               /* Support of yytext. */
+               *yy_cp = yy_hold_char;
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = yy_start;
+               yy_current_state += YY_AT_BOL();
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 299 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 1808 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+
+do_action:     /* This label is used only to access EOF actions. */
+
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 114 "parse.lex"
+BEGIN STARTDEFS;
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 116 "parse.lex"
+{
+                           BEGIN INDEFS;
+                           LEXTRACE("DEFVAR ");
+                           fill(yytext, yyleng);
+                           return(DEFVAR);
+                       }
+       YY_BREAK
+
+case 3:
+YY_RULE_SETUP
+#line 124 "parse.lex"
+{
+                           BEGIN STARTDEFS;
+                           LEXTRACE(", ");
+                           return(',');
+                       }                       /* return ',' */
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 130 "parse.lex"
+{
+                           LEXTRACE("= ");
+                           return('=');
+                       }                       /* return '=' */
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 135 "parse.lex"
+{
+                           LEXTRACE("+= ");
+                           return('+');
+                       }                       /* return '+' */
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 140 "parse.lex"
+{
+                           LEXTRACE("-= ");
+                           return('-');
+                       }                       /* return '-' */
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 145 "parse.lex"
+{
+                           LEXTRACE("WORD(1) ");
+                           fill(yytext + 1, yyleng - 2);
+                           return(WORD);
+                       }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 151 "parse.lex"
+{
+                           LEXTRACE("WORD(2) ");
+                           fill(yytext, yyleng);
+                           return(WORD);
+                       }
+       YY_BREAK
+
+
+case 9:
+YY_RULE_SETUP
+#line 159 "parse.lex"
+{
+                           LEXTRACE("QUOTEDCHAR ");
+                           fill_args(yytext + 1, 1, sawspace);
+                           sawspace = FALSE;
+                       }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 165 "parse.lex"
+{
+                           BEGIN INITIAL;
+                           unput(*yytext);
+                           return(COMMAND);
+                       }                       /* end of command line args */
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 171 "parse.lex"
+{
+                           LEXTRACE("ARG ");
+                           fill_args(yytext, yyleng, sawspace);
+                           sawspace = FALSE;
+                       }                       /* a command line arg */
+       YY_BREAK
+
+case 12:
+YY_RULE_SETUP
+#line 178 "parse.lex"
+{
+                           BEGIN GOTDEFS;
+                           switch (yytext[8]) {
+                               case ':':
+                                   LEXTRACE("DEFAULTS_USER ");
+                                   return(DEFAULTS_USER);
+                               case '@':
+                                   LEXTRACE("DEFAULTS_HOST ");
+                                   return(DEFAULTS_HOST);
+                               default:
+                                   LEXTRACE("DEFAULTS ");
+                                   return(DEFAULTS);
+                           }
+                       }
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 193 "parse.lex"
+{
+                           fill(yytext, yyleng);
+                           switch (*yytext) {
+                               case 'H':
+                                   LEXTRACE("HOSTALIAS ");
+                                   return(HOSTALIAS);
+                               case 'C':
+                                   LEXTRACE("CMNDALIAS ");
+                                   return(CMNDALIAS);
+                               case 'U':
+                                   LEXTRACE("USERALIAS ");
+                                   return(USERALIAS);
+                               case 'R':
+                                   LEXTRACE("RUNASALIAS ");
+                                   BEGIN GOTRUNAS;
+                                   return(RUNASALIAS);
+                           }
+                       }
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 212 "parse.lex"
+{
+                               /* cmnd does not require passwd for this user */
+                               LEXTRACE("NOPASSWD ");
+                               return(NOPASSWD);
+                       }
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 218 "parse.lex"
+{
+                               /* cmnd requires passwd for this user */
+                               LEXTRACE("PASSWD ");
+                               return(PASSWD);
+                       }
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 224 "parse.lex"
+{
+                           /* netgroup */
+                           fill(yytext, yyleng);
+                           LEXTRACE("NETGROUP ");
+                           return(NETGROUP);
+                       }
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 231 "parse.lex"
+{
+                           /* UN*X group */
+                           fill(yytext, yyleng);
+                           LEXTRACE("GROUP ");
+                           return(USERGROUP);
+                       }
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 238 "parse.lex"
+{
+                           fill(yytext, yyleng);
+                           LEXTRACE("NTWKADDR ");
+                           return(NTWKADDR);
+                       }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 244 "parse.lex"
+{
+                           fill(yytext, yyleng);
+                           LEXTRACE("NTWKADDR ");
+                           return(NTWKADDR);
+                       }
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 250 "parse.lex"
+{
+                               BEGIN GOTRUNAS;
+                               LEXTRACE("RUNAS ");
+                               return (RUNAS);
+                       }
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 256 "parse.lex"
+{
+                           if (strcmp(yytext, "ALL") == 0) {
+                               LEXTRACE("ALL ");
+                               return(ALL);
+                           } else {
+                               fill(yytext, yyleng);
+                               LEXTRACE("ALIAS ");
+                               return(ALIAS);
+                           }
+                       }
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 267 "parse.lex"
+{
+                           /* username/uid that user can run command as */
+                           fill(yytext, yyleng);
+                           LEXTRACE("WORD(3) ");
+                           return(WORD);
+                       }
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 274 "parse.lex"
+{
+                           BEGIN INITIAL;
+                       }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 278 "parse.lex"
+{
+                           /* directories can't have args... */
+                           if (yytext[yyleng - 1] == '/') {
+                               LEXTRACE("COMMAND ");
+                               fill_cmnd(yytext, yyleng);
+                               return(COMMAND);
+                           } else {
+                               BEGIN GOTCMND;
+                               LEXTRACE("COMMAND ");
+                               fill_cmnd(yytext, yyleng);
+                           }
+                       }                       /* a pathname */
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 291 "parse.lex"
+{
+                           /* a word */
+                           fill(yytext, yyleng);
+                           LEXTRACE("WORD(4) ");
+                           return(WORD);
+                       }
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 298 "parse.lex"
+{
+                           LEXTRACE(", ");
+                           return(',');
+                       }                       /* return ',' */
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 303 "parse.lex"
+{
+                           LEXTRACE("= ");
+                           return('=');
+                       }                       /* return '=' */
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 308 "parse.lex"
+{
+                           LEXTRACE(": ");
+                           return(':');
+                       }                       /* return ':' */
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 313 "parse.lex"
+{
+                           if (yyleng % 2 == 1)
+                               return('!');    /* return '!' */
+                       }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 318 "parse.lex"
+{
+                           BEGIN INITIAL;
+                           ++sudolineno;
+                           LEXTRACE("\n");
+                           return(COMMENT);
+                       }                       /* return newline */
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 325 "parse.lex"
+{                      /* throw away space/tabs */
+                           sawspace = TRUE;    /* but remember for fill_args */
+                       }
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 329 "parse.lex"
+{
+                           sawspace = TRUE;    /* remember for fill_args */
+                           ++sudolineno;
+                           LEXTRACE("\n\t");
+                       }                       /* throw away EOL after \ */
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 335 "parse.lex"
+{
+                           BEGIN INITIAL;
+                           ++sudolineno;
+                           LEXTRACE("\n");
+                           return(COMMENT);
+                       }                       /* return comments */
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 342 "parse.lex"
+{
+                           LEXTRACE("ERROR ");
+                           return(ERROR);
+                       }       /* parse error */
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 347 "parse.lex"
+ECHO;
+       YY_BREAK
+#line 1564 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(GOTRUNAS):
+case YY_STATE_EOF(GOTDEFS):
+case YY_STATE_EOF(GOTCMND):
+case YY_STATE_EOF(STARTDEFS):
+case YY_STATE_EOF(INDEFS):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = yy_hold_char;
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between yy_current_buffer and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state();
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++yy_c_buf_p;
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = yy_c_buf_p;
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer() )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               yy_did_buffer_switch_on_eof = 0;
+
+                               if ( yywrap() )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state();
+
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+                               yy_current_state = yy_get_previous_state();
+
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+       } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+       else
+               {
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = yy_current_buffer;
+
+                       int yy_c_buf_p_offset =
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = yy_current_buffer->yy_buf_size -
+                                               number_to_move - 1;
+#endif
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
+
+               yy_current_buffer->yy_n_chars = yy_n_chars;
+               }
+
+       if ( yy_n_chars == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart( yyin );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       yy_current_buffer->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+       return ret_val;
+       }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+       {
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+
+       yy_current_state = yy_start;
+       yy_current_state += YY_AT_BOL();
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 299 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+       }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
+       register int yy_is_jam;
+       register char *yy_cp = yy_c_buf_p;
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 299 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 298);
+
+       return yy_is_jam ? 0 : yy_current_state;
+       }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
+
+       /* undo effects of setting up yytext */
+       *yy_cp = yy_hold_char;
+
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
+               register char *source =
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
+
+               while ( source > yy_current_buffer->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
+
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+       {
+       int c;
+
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+                       /* This was really a NUL. */
+                       *yy_c_buf_p = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
+
+                       switch ( yy_get_next_buffer() )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart( yyin );
+
+                                       /* fall through */
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap() )
+                                               return EOF;
+
+                                       if ( ! yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       yy_c_buf_p = yytext_ptr + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
+       yy_current_buffer->yy_at_bol = (c == '\n');
+
+       return c;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
+               return;
+
+       if ( yy_current_buffer )
+               {
+               /* Flush out information for old buffer. */
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
+               }
+
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       yy_did_buffer_switch_on_eof = 1;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
+       YY_BUFFER_STATE b;
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer( b, file );
+
+       return b;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
+       if ( ! b )
+               return;
+
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yy_flex_free( (void *) b->yy_ch_buf );
+
+       yy_flex_free( (void *) b );
+       }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       int oerrno = errno;
+
+       yy_flush_buffer( b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       errno = oerrno;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
+       }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
+       YY_BUFFER_STATE b;
+
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer( b );
+
+       return b;
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = len + 2;
+       buf = (char *) yy_flex_alloc( n );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < len; ++i )
+               buf[i] = bytes[i];
+
+       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer( buf, n );
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+       }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
+
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
+
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
+
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
+
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+       BEGIN(new_state);
+       }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
+
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+       }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+       }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
+       return (void *) malloc( size );
+       }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+       }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+       {
+       free( ptr );
+       }
+
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
+#endif
+#line 347 "parse.lex"
+
+static void
+fill(s, len)
+    char *s;
+    int len;
+{
+    int i, j;
+
+    yylval.string = (char *) malloc(len + 1);
+    if (yylval.string == NULL)
+       yyerror("unable to allocate memory");
+
+    /* Copy the string and collapse any escaped characters. */
+    for (i = 0, j = 0; i < len; i++, j++) {
+       if (s[i] == '\\' && i != len - 1)
+           yylval.string[j] = s[++i];
+       else
+           yylval.string[j] = s[i];
+    }
+    yylval.string[j] = '\0';
+}
+
+static void
+fill_cmnd(s, len)
+    char *s;
+    int len;
+{
+    arg_len = arg_size = 0;
+
+    yylval.command.cmnd = (char *) malloc(len + 1);
+    if (yylval.command.cmnd == NULL)
+       yyerror("unable to allocate memory");
+
+    /* copy the string and NULL-terminate it (escapes handled by fnmatch) */
+    (void) strncpy(yylval.command.cmnd, s, len);
+    yylval.command.cmnd[len] = '\0';
+
+    yylval.command.args = NULL;
+}
+
+static void
+fill_args(s, len, addspace)
+    char *s;
+    int len;
+    int addspace;
+{
+    int new_len;
+    char *p;
+
+    /*
+     * If first arg, malloc() some room, else if we don't
+     * have enough space realloc() some more.
+     */
+    if (yylval.command.args == NULL) {
+       addspace = 0;
+       new_len = len;
+
+       while (new_len >= (arg_size += COMMANDARGINC))
+           ;
+
+       yylval.command.args = (char *) malloc(arg_size);
+       if (yylval.command.args == NULL)
+           yyerror("unable to allocate memory");
+    } else {
+       new_len = arg_len + len + addspace;
+
+       if (new_len >= arg_size) {
+           /* Allocate more space than we need for subsequent args */
+           while (new_len >= (arg_size += COMMANDARGINC))
+               ;
+
+           if ((p = (char *) realloc(yylval.command.args, arg_size)) == NULL) {
+               free(yylval.command.args);
+               yyerror("unable to allocate memory");
+           } else
+               yylval.command.args = p;
+       }
+    }
+
+    /* Efficiently append the arg (with a leading space if needed). */
+    p = yylval.command.args + arg_len;
+    if (addspace)
+       *p++ = ' ';
+    (void) strcpy(p, s);
+    arg_len = new_len;
+}
+
+int
+yywrap()
+{
+
+    /* Free space used by the aliases unless called by testsudoers. */
+    if (clearaliases)
+       reset_aliases();
+
+    return(TRUE);
+}
diff --git a/logging.c b/logging.c
new file mode 100644 (file)
index 0000000..723d19e
--- /dev/null
+++ b/logging.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 1994-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: logging.c,v 1.153 2002/01/16 21:28:25 millert Exp $";
+#endif /* lint */
+
+static void do_syslog          __P((int, char *));
+static void do_logfile         __P((char *));
+static void send_mail          __P((char *));
+static void mail_auth          __P((int, char *));
+static char *get_timestr       __P((void));
+static void mysyslog           __P((int, const char *, ...));
+
+#define MAXSYSLOGTRIES 16      /* num of retries for broken syslogs */
+
+/*
+ * We do an openlog(3)/closelog(3) for each message because some
+ * authentication methods (notably PAM) use syslog(3) for their
+ * own nefarious purposes and may call openlog(3) and closelog(3).
+ * Note that because we don't want to assume that all systems have
+ * vsyslog(3) (HP-UX doesn't) "%m" will not be expanded.
+ * Sadly this is a maze of #ifdefs.
+ */
+static void
+#ifdef __STDC__
+mysyslog(int pri, const char *fmt, ...)
+#else
+mysyslog(pri, fmt, va_alist)
+    int pri;
+    const char *fmt;
+    va_dcl
+#endif
+{
+#ifdef BROKEN_SYSLOG
+    int i;
+#endif
+    char buf[MAXSYSLOGLEN+1];
+    va_list ap;
+
+#ifdef __STDC__
+    va_start(ap, fmt);
+#else
+    va_start(ap);
+#endif
+#ifdef LOG_NFACILITIES
+    openlog(Argv[0], 0, def_ival(I_LOGFAC));
+#else
+    openlog(Argv[0], 0);
+#endif
+    vsnprintf(buf, sizeof(buf), fmt, ap);
+#ifdef BROKEN_SYSLOG
+    /*
+     * Some versions of syslog(3) don't guarantee success and return
+     * an int (notably HP-UX < 10.0).  So, if at first we don't succeed,
+     * try, try again...
+     */
+    for (i = 0; i < MAXSYSLOGTRIES; i++)
+       if (syslog(pri, "%s", buf) == 0)
+           break;
+#else
+    syslog(pri, "%s", buf);
+#endif /* BROKEN_SYSLOG */
+    va_end(ap);
+    closelog();
+}
+
+/*
+ * Log a message to syslog, pre-pending the username and splitting the
+ * message into parts if it is longer than MAXSYSLOGLEN.
+ */
+static void
+do_syslog(pri, msg)
+    int pri;
+    char *msg;
+{
+    int count;
+    char *p;
+    char *tmp;
+    char save;
+
+    /*
+     * Log the full line, breaking into multiple syslog(3) calls if necessary
+     */
+    for (p = msg, count = 0; *p && count < strlen(msg) / MAXSYSLOGLEN + 1;
+       count++) {
+       if (strlen(p) > MAXSYSLOGLEN) {
+           /*
+            * Break up the line into what will fit on one syslog(3) line
+            * Try to break on a word boundary if possible.
+            */
+           for (tmp = p + MAXSYSLOGLEN; tmp > p && *tmp != ' '; tmp--)
+               ;
+           if (tmp <= p)
+               tmp = p + MAXSYSLOGLEN;
+
+           /* NULL terminate line, but save the char to restore later */
+           save = *tmp;
+           *tmp = '\0';
+
+           if (count == 0)
+               mysyslog(pri, "%8.8s : %s", user_name, p);
+           else
+               mysyslog(pri, "%8.8s : (command continued) %s", user_name, p);
+
+           *tmp = save;                        /* restore saved character */
+
+           /* Eliminate leading whitespace */
+           for (p = tmp; *p != ' ' && *p !='\0'; p++)
+               ;
+       } else {
+           if (count == 0)
+               mysyslog(pri, "%8.8s : %s", user_name, p);
+           else
+               mysyslog(pri, "%8.8s : (command continued) %s", user_name, p);
+       }
+    }
+}
+
+static void
+do_logfile(msg)
+    char *msg;
+{
+    char *full_line;
+    char *beg, *oldend, *end;
+    FILE *fp;
+    mode_t oldmask;
+    int maxlen = def_ival(I_LOGLINELEN);
+
+    oldmask = umask(077);
+    fp = fopen(def_str(I_LOGFILE), "a");
+    (void) umask(oldmask);
+    if (fp == NULL) {
+       easprintf(&full_line, "Can't open log file: %s: %s",
+           def_str(I_LOGFILE), strerror(errno));
+       send_mail(full_line);
+       free(full_line);
+    } else if (!lock_file(fileno(fp), SUDO_LOCK)) {
+       easprintf(&full_line, "Can't lock log file: %s: %s",
+           def_str(I_LOGFILE), strerror(errno));
+       send_mail(full_line);
+       free(full_line);
+    } else {
+       if (def_ival(I_LOGLINELEN) == 0) {
+           /* Don't pretty-print long log file lines (hard to grep) */
+           if (def_flag(I_LOG_HOST))
+               (void) fprintf(fp, "%s : %s : HOST=%s : %s\n", get_timestr(),
+                   user_name, user_shost, msg);
+           else
+               (void) fprintf(fp, "%s : %s : %s\n", get_timestr(),
+                   user_name, msg);
+       } else {
+           if (def_flag(I_LOG_HOST))
+               easprintf(&full_line, "%s : %s : HOST=%s : %s", get_timestr(),
+                   user_name, user_shost, msg);
+           else
+               easprintf(&full_line, "%s : %s : %s", get_timestr(),
+                   user_name, msg);
+
+           /*
+            * Print out full_line with word wrap
+            */
+           beg = end = full_line;
+           while (beg) {
+               oldend = end;
+               end = strchr(oldend, ' ');
+
+               if (maxlen > 0 && end) {
+                   *end = '\0';
+                   if (strlen(beg) > maxlen) {
+                       /* too far, need to back up & print the line */
+
+                       if (beg == (char *)full_line)
+                           maxlen -= 4;        /* don't indent first line */
+
+                       *end = ' ';
+                       if (oldend != beg) {
+                           /* rewind & print */
+                           end = oldend-1;
+                           while (*end == ' ')
+                               --end;
+                           *(++end) = '\0';
+                           (void) fprintf(fp, "%s\n    ", beg);
+                           *end = ' ';
+                       } else {
+                           (void) fprintf(fp, "%s\n    ", beg);
+                       }
+
+                       /* reset beg to point to the start of the new substr */
+                       beg = end;
+                       while (*beg == ' ')
+                           ++beg;
+                   } else {
+                       /* we still have room */
+                       *end = ' ';
+                   }
+
+                   /* remove leading whitespace */
+                   while (*end == ' ')
+                       ++end;
+               } else {
+                   /* final line */
+                   (void) fprintf(fp, "%s\n", beg);
+                   beg = NULL;                 /* exit condition */
+               }
+           }
+           free(full_line);
+       }
+       (void) fflush(fp);
+       (void) lock_file(fileno(fp), SUDO_UNLOCK);
+       (void) fclose(fp);
+    }
+}
+
+/*
+ * Two main functions, log_error() to log errors and log_auth() to
+ * log allow/deny messages.
+ */
+void
+log_auth(status, inform_user)
+    int status;
+    int inform_user;
+{
+    char *message;
+    char *logline;
+    int pri;
+
+    if (status & VALIDATE_OK)
+       pri = def_ival(I_GOODPRI);
+    else
+       pri = def_ival(I_BADPRI);
+
+    /* Set error message, if any. */
+    if (status & VALIDATE_OK)
+       message = "";
+    else if (status & FLAG_NO_USER)
+       message = "user NOT in sudoers ; ";
+    else if (status & FLAG_NO_HOST)
+       message = "user NOT authorized on host ; ";
+    else if (status & VALIDATE_NOT_OK)
+       message = "command not allowed ; ";
+    else
+       message = "unknown error ; ";
+
+    easprintf(&logline, "%sTTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s%s%s",
+       message, user_tty, user_cwd, *user_runas, user_cmnd,
+       user_args ? " " : "", user_args ? user_args : "");
+
+    mail_auth(status, logline);                /* send mail based on status */
+
+    /* Inform the user if they failed to authenticate.  */
+    if (inform_user && (status & VALIDATE_NOT_OK)) {
+       if (status & FLAG_NO_USER)
+           (void) fprintf(stderr, "%s is not in the sudoers file.  %s",
+               user_name, "This incident will be reported.\n");
+       else if (status & FLAG_NO_HOST)
+           (void) fprintf(stderr, "%s is not allowed to run sudo on %s.  %s",
+               user_name, user_shost, "This incident will be reported.\n");
+       else if (status & FLAG_NO_CHECK)
+           (void) fprintf(stderr, "Sorry, user %s may not run sudo on %s.\n",
+               user_name, user_shost);
+       else
+           (void) fprintf(stderr,
+               "Sorry, user %s is not allowed to execute '%s%s%s' as %s on %s.\n",
+               user_name, user_cmnd, user_args ? " " : "",
+               user_args ? user_args : "", *user_runas, user_host);
+    }
+
+    /*
+     * Log via syslog and/or a file.
+     */
+    if (def_str(I_SYSLOG))
+       do_syslog(pri, logline);
+    if (def_str(I_LOGFILE))
+       do_logfile(logline);
+
+    free(logline);
+}
+
+void
+#ifdef __STDC__
+log_error(int flags, const char *fmt, ...)
+#else
+log_error(va_alist)
+    va_dcl
+#endif
+{
+    int serrno = errno;
+    char *message;
+    char *logline;
+    va_list ap;
+#ifdef __STDC__
+    va_start(ap, fmt);
+#else
+    int flags;
+    const char *fmt;
+
+    va_start(ap);
+    flags = va_arg(ap, int);
+    fmt = va_arg(ap, const char *);
+#endif
+
+    /* Become root if we are not already to avoid user control */
+    if (geteuid() != 0)
+       set_perms(PERM_ROOT, 0);
+
+    /* Expand printf-style format + args. */
+    evasprintf(&message, fmt, ap);
+    va_end(ap);
+
+    if (flags & MSG_ONLY)
+       logline = message;
+    else if (flags & USE_ERRNO) {
+       if (user_args) {
+           easprintf(&logline,
+               "%s: %s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s %s",
+               message, strerror(serrno), user_tty, user_cwd, *user_runas,
+               user_cmnd, user_args);
+       } else {
+           easprintf(&logline,
+               "%s: %s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s", message,
+               strerror(serrno), user_tty, user_cwd, *user_runas, user_cmnd);
+       }
+    } else {
+       if (user_args) {
+           easprintf(&logline,
+               "%s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s %s", message,
+               user_tty, user_cwd, *user_runas, user_cmnd, user_args);
+       } else {
+           easprintf(&logline,
+               "%s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s", message,
+               user_tty, user_cwd, *user_runas, user_cmnd);
+       }
+    }
+
+    /*
+     * Tell the user.
+     */
+    (void) fprintf(stderr, "%s: %s", Argv[0], message);
+    if (flags & USE_ERRNO)
+       (void) fprintf(stderr, ": %s", strerror(serrno));
+    (void) fputc('\n', stderr);
+
+    /*
+     * Send a copy of the error via mail.
+     */
+    if (!(flags & NO_MAIL))
+       send_mail(logline);
+
+    /*
+     * Log to syslog and/or a file.
+     */
+    if (def_str(I_SYSLOG))
+       do_syslog(def_ival(I_BADPRI), logline);
+    if (def_str(I_LOGFILE))
+       do_logfile(logline);
+
+    free(message);
+    if (logline != message)
+       free(logline);
+
+    if (!(flags & NO_EXIT))
+       exit(1);
+}
+
+#define MAX_MAILFLAGS  63
+
+/*
+ * Send a message to MAILTO user
+ */
+static void
+send_mail(line)
+    char *line;
+{
+    FILE *mail;
+    char *p;
+    int pfd[2], pid, status;
+    sigset_t set, oset;
+#ifndef NO_ROOT_MAILER
+    static char *root_envp[] = {
+       "HOME=/",
+       "PATH=/usr/bin:/bin",
+       "LOGNAME=root",
+       "USER=root",
+       NULL
+    };
+#endif
+
+    /* Just return if mailer is disabled. */
+    if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO))
+       return;
+
+    (void) sigemptyset(&set);
+    (void) sigaddset(&set, SIGCHLD);
+    (void) sigprocmask(SIG_BLOCK, &set, &oset);
+
+    if (pipe(pfd) == -1) {
+       (void) fprintf(stderr, "%s: cannot open pipe: %s\n",
+           Argv[0], strerror(errno));
+       exit(1);
+    }
+
+    switch (pid = fork()) {
+       case -1:
+           /* Error. */
+           (void) fprintf(stderr, "%s: cannot fork: %s\n",
+               Argv[0], strerror(errno));
+           exit(1);
+           break;
+       case 0:
+           {
+               char *argv[MAX_MAILFLAGS + 1];
+               char *mpath, *mflags;
+               int i;
+
+               /* Child, set stdin to output side of the pipe */
+               if (pfd[0] != STDIN_FILENO) {
+                   (void) dup2(pfd[0], STDIN_FILENO);
+                   (void) close(pfd[0]);
+               }
+               (void) close(pfd[1]);
+
+               /* Build up an argv based the mailer path and flags */
+               mflags = estrdup(def_str(I_MAILERFLAGS));
+               mpath = estrdup(def_str(I_MAILERPATH));
+               if ((argv[0] = strrchr(mpath, ' ')))
+                   argv[0]++;
+               else
+                   argv[0] = mpath;
+
+               i = 1;
+               if ((p = strtok(mflags, " \t"))) {
+                   do {
+                       argv[i] = p;
+                   } while (++i < MAX_MAILFLAGS && (p = strtok(NULL, " \t")));
+               }
+               argv[i] = NULL;
+
+               /* Close password file so we don't leak the fd. */
+               endpwent();
+
+               /*
+                * Depending on the config, either run the mailer as root
+                * (so user cannot kill it) or as the user (for the paranoid).
+                */
+#ifndef NO_ROOT_MAILER
+               set_perms(PERM_FULL_ROOT, 0);
+               execve(mpath, argv, root_envp);
+#else
+               set_perms(PERM_FULL_USER, 0);
+               execv(mpath, argv);
+#endif /* NO_ROOT_MAILER */
+               _exit(127);
+           }
+           break;
+    }
+
+    (void) close(pfd[0]);
+    mail = fdopen(pfd[1], "w");
+
+    /* Pipes are all setup, send message via sendmail. */
+    (void) fprintf(mail, "To: %s\nFrom: %s\nSubject: ",
+       def_str(I_MAILTO), user_name);
+    for (p = def_str(I_MAILSUB); *p; p++) {
+       /* Expand escapes in the subject */
+       if (*p == '%' && *(p+1) != '%') {
+           switch (*(++p)) {
+               case 'h':
+                   (void) fputs(user_host, mail);
+                   break;
+               case 'u':
+                   (void) fputs(user_name, mail);
+                   break;
+               default:
+                   p--;
+                   break;
+           }
+       } else
+           (void) fputc(*p, mail);
+    }
+    (void) fprintf(mail, "\n\n%s : %s : %s : %s\n\n", user_host,
+       get_timestr(), user_name, line);
+    fclose(mail);
+
+    /* If mailer is done, wait for it now.  If not reapchild will get it.  */
+#ifdef sudo_waitpid
+    (void) sudo_waitpid(pid, &status, WNOHANG);
+#endif
+    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+}
+
+/*
+ * Send mail based on the value of "status" and compile-time options.
+ */
+static void
+mail_auth(status, line)
+    int status;
+    char *line;
+{
+    int mail_mask;
+
+    /* If any of these bits are set in status, we send mail. */
+    if (def_flag(I_MAIL_ALWAYS))
+       mail_mask =
+           VALIDATE_ERROR|VALIDATE_OK|FLAG_NO_USER|FLAG_NO_HOST|VALIDATE_NOT_OK;
+    else {
+       mail_mask = VALIDATE_ERROR;
+       if (def_flag(I_MAIL_NO_USER))
+           mail_mask |= FLAG_NO_USER;
+       if (def_flag(I_MAIL_NO_HOST))
+           mail_mask |= FLAG_NO_HOST;
+       if (def_flag(I_MAIL_NO_PERMS))
+           mail_mask |= VALIDATE_NOT_OK;
+    }
+
+    if ((status & mail_mask) != 0)
+       send_mail(line);
+}
+
+/*
+ * SIGCHLD sig handler--wait for children as they die.
+ */
+RETSIGTYPE
+reapchild(sig)
+    int sig;
+{
+    int status, serrno = errno;
+
+#ifdef sudo_waitpid
+    while (sudo_waitpid(-1, &status, WNOHANG) != -1 && errno == EINTR)
+       ;
+#else
+    (void) wait(&status);
+#endif
+    errno = serrno;
+}
+
+/*
+ * Return an ascii string with the current date + time
+ * Uses strftime() if available, else falls back to ctime().
+ */
+static char *
+get_timestr()
+{
+    char *s;
+    time_t now = time((time_t) 0);
+#ifdef HAVE_STRFTIME
+    static char buf[128];
+    struct tm *timeptr;
+
+    timeptr = localtime(&now);
+    if (def_flag(I_LOG_YEAR))
+       s = "%h %e %T %Y";
+    else
+       s = "%h %e %T";
+
+    /* strftime() does not guarantee to NUL-terminate so we must check. */
+    buf[sizeof(buf) - 1] = '\0';
+    if (strftime(buf, sizeof(buf), s, timeptr) && buf[sizeof(buf) - 1] == '\0')
+       return(buf);
+
+#endif /* HAVE_STRFTIME */
+
+    s = ctime(&now) + 4;               /* skip day of the week */
+    if (def_flag(I_LOG_YEAR))
+       s[20] = '\0';                   /* avoid the newline */
+    else
+       s[15] = '\0';                   /* don't care about year */
+
+    return(s);
+}
diff --git a/logging.h b/logging.h
new file mode 100644 (file)
index 0000000..da4b02a
--- /dev/null
+++ b/logging.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LOGGING_H
+#define _LOGGING_H
+
+#include <syslog.h>
+#ifdef __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+/* Logging types */
+#define SLOG_SYSLOG            0x01
+#define SLOG_FILE              0x02
+#define SLOG_BOTH              0x03
+
+/* Flags for log_error() */
+#define MSG_ONLY               0x01
+#define USE_ERRNO              0x02
+#define NO_MAIL                        0x04
+#define NO_EXIT                        0x08
+
+/*
+ * Maximum number of characters to log per entry.  The syslogger
+ * will log this much, after that, it truncates the log line.
+ * We need this here to make sure that we continue with another   
+ * syslog(3) call if the internal buffer is more than 1023 characters.
+ */
+#ifndef MAXSYSLOGLEN
+# define MAXSYSLOGLEN          960
+#endif
+      
+void log_auth                  __P((int, int));
+void log_error                 __P((int flags, const char *fmt, ...));
+RETSIGTYPE reapchild           __P((int));
+
+#endif /* _LOGGING_H */
diff --git a/lsearch.c b/lsearch.c
new file mode 100644 (file)
index 0000000..dc90f63
--- /dev/null
+++ b/lsearch.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Roger L. Snyder.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "compat.h"
+#include "emul/search.h"
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)lsearch.c    8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#ifndef lint
+static const char rcsid[] = "$Sudo: lsearch.c,v 1.18 2001/12/14 19:52:48 millert Exp $";
+#endif /* lint */
+
+typedef int (*cmp_fn_t) __P((const VOID *, const VOID *));
+static VOID *linear_base __P((const VOID *, const VOID *, size_t *, size_t,
+                            cmp_fn_t, int));
+
+VOID *
+lsearch(key, base, nelp, width, compar)
+       const VOID *key, *base;
+       size_t *nelp, width;
+       cmp_fn_t compar;
+{
+       return(linear_base(key, base, nelp, width, compar, 1));
+}
+
+VOID *
+lfind(key, base, nelp, width, compar)
+       const VOID *key, *base;
+       size_t *nelp, width;
+       cmp_fn_t compar;
+{
+       return(linear_base(key, base, nelp, width, compar, 0));
+}
+
+static VOID *
+linear_base(key, base, nelp, width, compar, add_flag)
+       const VOID *key, *base;
+       size_t *nelp, width;
+       cmp_fn_t compar;
+       int add_flag;
+{
+       /* Strict ANSI does not allow pointer arithmetic on void *'s */
+       const char *element, *end;
+
+       end = (const char *) base + *nelp * width;
+       for (element = (const char *) base; element < end; element += width)
+               if (!compar(key, (VOID *) element))     /* key found */
+                       return((VOID *) element);
+       if (!add_flag)                                  /* key not found */
+               return(NULL);
+
+       /*
+        * The UNIX System User's Manual, 1986 edition claims that
+        * a NULL pointer is returned by lsearch with errno set
+        * appropriately, if there is not enough room in the table
+        * to add a new item.  This can't be done as none of these
+        * routines have any method of determining the size of the
+        * table.  This comment was isn't in the 1986-87 System V
+        * manual.
+        */
+       ++*nelp;
+       (void) memcpy((VOID *)end, key, width);
+       return((VOID *) end);
+}
diff --git a/mkdefaults b/mkdefaults
new file mode 100755 (executable)
index 0000000..82ef6bd
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -w
+#
+# Generate sudo_defs_table and associated defines
+#
+# Input should be formatted thusly:
+#
+# var_name
+#      TYPE
+#      description (or NULL)
+
+# Deal with optional -o (output) argument
+if ($#ARGV > 0 && $ARGV[0] eq "-o") {
+    shift;
+    $header = $cfile = shift;
+    $header .= '.h';
+    $cfile .= '.c';
+}
+die "usage: $0 input_file" unless $#ARGV == 0;
+
+$infile = $ARGV[0];
+if (!defined($header)) {
+    $header = $infile;
+    $header =~ s/(\.in)?$/.h/;
+}
+if (!defined($cfile)) {
+    $cfile = $infile;
+    $cfile =~ s/(\.in)?$/.c/;
+}
+
+open(IN, "<$infile") || die "$0: can't open $infile: $!\n";
+open(HEADER, ">$header") || die "$0: can't open $header: $!\n";
+open(CFILE, ">$cfile") || die "$0: can't open $cfile: $!\n";
+
+print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n    {\n";
+
+$count = -1;
+while(<IN>) {
+    chomp;
+    next if /^\s*$/;
+    next if /^\s*#/;
+
+    if (/^\S/) {
+       # Print last record
+       &print_record() if defined($var);
+
+       $var = $_;
+       ($type, $desc) = (undef, undef);
+       $count++;
+    } else {
+       s/^\s+//;
+       s/\s+$//;
+       die "$0: syntax error near line $.\n" if
+           defined($type) && defined($desc);
+       next if /^NULL$/;
+       if (defined($type)) {
+           # Strip leading and trailing double quote and escape the rest
+           s/^"//;
+           s/"$//;
+           s/"/\\"/g;
+           $desc = "\"$_\"";
+       } else {
+           $type = $_;
+       }
+    }
+}
+&print_record();
+print CFILE "\tNULL, 0, NULL\n    }\n};\n";
+
+close(IN);
+close(HEADER);
+close(CFILE);
+
+sub print_record {
+    $defname = "I_" . uc($var);
+    printf HEADER "#define %-24s%d", $defname, $count;
+    #print HEADER "\t/* $desc */" if defined($desc);
+    print HEADER "\n";
+
+    $desc = "NULL" unless defined($desc);
+    print CFILE "\t\"$var\", $type,\n\t$desc\n    }, {\n";
+}
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755 (executable)
index 0000000..935edea
--- /dev/null
@@ -0,0 +1,75 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.3 2001/12/31 22:05:23 millert Exp $
+
+umask 022
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+   case "${1}" in
+     -h | --help | --h* )                      # -h for help
+        echo "${usage}" 1>&2; exit 0 ;;
+     -m )                                      # -m PERM arg
+        shift
+        test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
+        dirmode="${1}"
+        shift ;;
+     -- ) shift; break ;;                      # stop option processing
+     -* ) echo "${usage}" 1>&2; exit 1 ;;      # unknown option
+     * )  break ;;                             # first non-opt arg
+   esac
+done
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp"
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+         errstatus=$lasterr
+       else
+         if test ! -z "$dirmode"; then
+            echo "chmod $dirmode $pathcomp"
+
+            lasterr=""
+            chmod $dirmode "$pathcomp" || lasterr=$?
+
+            if test ! -z "$lasterr"; then
+              errstatus=$lasterr
+            fi
+         fi
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:3
+# End:
diff --git a/parse.c b/parse.c
new file mode 100644 (file)
index 0000000..97c0306
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 1996, 1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_FNMATCH
+# include <fnmatch.h>
+#endif /* HAVE_FNMATCH_H */
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#endif /* HAVE_NETGROUP_H */
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#include "sudo.h"
+#include "parse.h"
+#include "interfaces.h"
+
+#ifndef HAVE_FNMATCH
+# include "emul/fnmatch.h"
+#endif /* HAVE_FNMATCH */
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: parse.c,v 1.137 2002/03/16 00:44:47 millert Exp $";
+#endif /* lint */
+
+/*
+ * Globals
+ */
+int parse_error = FALSE;
+extern int keepall;
+extern FILE *yyin, *yyout;
+
+/*
+ * Prototypes
+ */
+static int has_meta    __P((char *));
+       void init_parser        __P((void));
+
+/*
+ * Look up the user in the sudoers file and check to see if they are
+ * allowed to run the specified command on this host as the target user.
+ */
+int
+sudoers_lookup(pwflag)
+    int pwflag;
+{
+    int error;
+    int pwcheck;
+    int nopass;
+
+    /* Become sudoers file owner */
+    set_perms(PERM_SUDOERS, 0);
+
+    /* We opened _PATH_SUDOERS in check_sudoers() so just rewind it. */
+    rewind(sudoers_fp);
+    yyin = sudoers_fp;
+    yyout = stdout;
+
+    /* Allocate space for data structures in the parser. */
+    init_parser();
+
+    /* If pwcheck *could* be PWCHECK_ALL or PWCHECK_ANY, keep more state. */
+    if (pwflag > 0)
+       keepall = TRUE;
+
+    /* Need to be root while stat'ing things in the parser. */
+    set_perms(PERM_ROOT, 0);
+    error = yyparse();
+
+    /* Close the sudoers file now that we are done with it. */
+    (void) fclose(sudoers_fp);
+    sudoers_fp = NULL;
+
+    if (error || parse_error)
+       return(VALIDATE_ERROR);
+
+    /*
+     * The pw options may have changed during sudoers parse so we
+     * wait until now to set this.
+     */
+    if (pwflag)
+       pwcheck = (pwflag == -1) ? PWCHECK_NEVER : def_ival(pwflag);
+    else
+       pwcheck = 0;
+
+    /*
+     * Assume the worst.  If the stack is empty the user was
+     * not mentioned at all.
+     */
+    if (def_flag(I_AUTHENTICATE))
+       error = VALIDATE_NOT_OK;
+    else
+       error = VALIDATE_NOT_OK | FLAG_NOPASS;
+    if (pwcheck) {
+       error |= FLAG_NO_CHECK;
+    } else {
+       error |= FLAG_NO_HOST;
+       if (!top)
+           error |= FLAG_NO_USER;
+    }
+
+    /*
+     * Only check the actual command if pwcheck flag is not set.
+     * It is set for the "validate", "list" and "kill" pseudo-commands.
+     * Always check the host and user.
+     */
+    nopass = -1;
+    if (pwcheck) {
+       int found;
+
+       if (pwcheck == PWCHECK_NEVER || !def_flag(I_AUTHENTICATE))
+           nopass = FLAG_NOPASS;
+       found = 0;
+       while (top) {
+           if (host_matches == TRUE) {
+               found = 1;
+               if (pwcheck == PWCHECK_ANY && no_passwd == TRUE)
+                   nopass = FLAG_NOPASS;
+               else if (pwcheck == PWCHECK_ALL && nopass != 0)
+                   nopass = (no_passwd == TRUE) ? FLAG_NOPASS : 0;
+           }
+           top--;
+       }
+       if (found) {
+           if (nopass == -1)
+               nopass = 0;
+           return(VALIDATE_OK | nopass);
+       }
+    } else {
+       while (top) {
+           if (host_matches == TRUE) {
+               error &= ~FLAG_NO_HOST;
+               if (runas_matches == TRUE) {
+                   if (cmnd_matches == TRUE) {
+                       /*
+                        * User was granted access to cmnd on host.
+                        * If no passwd required return as such.
+                        */
+                       if (no_passwd == TRUE)
+                           return(VALIDATE_OK | FLAG_NOPASS);
+                       else
+                           return(VALIDATE_OK);
+                   } else if (cmnd_matches == FALSE) {
+                       /*
+                        * User was explicitly denied access to cmnd on host.
+                        */
+                       if (no_passwd == TRUE)
+                           return(VALIDATE_NOT_OK | FLAG_NOPASS);
+                       else
+                           return(VALIDATE_NOT_OK);
+                   }
+               }
+           }
+           top--;
+       }
+    }
+
+    /*
+     * The user was not explicitly granted nor denied access.
+     */
+    if (nopass == -1)
+       nopass = 0;
+    return(error | nopass);
+}
+
+/*
+ * If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
+ * otherwise, return TRUE if cmnd names one of the inodes in path.
+ */
+int
+command_matches(cmnd, cmnd_args, path, sudoers_args)
+    char *cmnd;
+    char *cmnd_args;
+    char *path;
+    char *sudoers_args;
+{
+    int plen;
+    static struct stat cst;
+    struct stat pst;
+    DIR *dirp;
+    struct dirent *dent;
+    char buf[MAXPATHLEN];
+    static char *cmnd_base;
+
+    /* Don't bother with pseudo commands like "validate" */
+    if (strchr(cmnd, '/') == NULL)
+       return(FALSE);
+
+    plen = strlen(path);
+
+    /* Only need to stat cmnd once since it never changes */
+    if (cst.st_dev == 0) {
+       if (stat(cmnd, &cst) == -1)
+           return(FALSE);
+       if ((cmnd_base = strrchr(cmnd, '/')) == NULL)
+           cmnd_base = cmnd;
+       else
+           cmnd_base++;
+    }
+
+    /*
+     * If the pathname has meta characters in it use fnmatch(3)
+     * to do the matching
+     */
+    if (has_meta(path)) {
+       /*
+        * Return true if fnmatch(3) succeeds AND
+        *  a) there are no args in sudoers OR
+        *  b) there are no args on command line and none required by sudoers OR
+        *  c) there are args in sudoers and on command line and they match
+        * else return false.
+        */
+       if (fnmatch(path, cmnd, FNM_PATHNAME) != 0)
+           return(FALSE);
+       if (!sudoers_args ||
+           (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
+           (sudoers_args && fnmatch(sudoers_args, cmnd_args ? cmnd_args : "",
+           0) == 0)) {
+           if (safe_cmnd)
+               free(safe_cmnd);
+           safe_cmnd = estrdup(user_cmnd);
+           return(TRUE);
+       } else
+           return(FALSE);
+    } else {
+       /*
+        * No meta characters
+        * Check to make sure this is not a directory spec (doesn't end in '/')
+        */
+       if (path[plen - 1] != '/') {
+           char *p;
+
+           /* Only proceed if the basenames of cmnd and path are the same */
+           if ((p = strrchr(path, '/')) == NULL)
+               p = path;
+           else
+               p++;
+           if (strcmp(cmnd_base, p) != 0 || stat(path, &pst) == -1)
+               return(FALSE);
+
+           /*
+            * Return true if inode/device matches AND
+            *  a) there are no args in sudoers OR
+            *  b) there are no args on command line and none req by sudoers OR
+            *  c) there are args in sudoers and on command line and they match
+            */
+           if (cst.st_dev != pst.st_dev || cst.st_ino != pst.st_ino)
+               return(FALSE);
+           if (!sudoers_args ||
+               (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
+               (sudoers_args &&
+                fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0)) {
+               if (safe_cmnd)
+                   free(safe_cmnd);
+               safe_cmnd = estrdup(path);
+               return(TRUE);
+           } else
+               return(FALSE);
+       }
+
+       /*
+        * Grot through path's directory entries, looking for cmnd.
+        */
+       dirp = opendir(path);
+       if (dirp == NULL)
+           return(FALSE);
+
+       while ((dent = readdir(dirp)) != NULL) {
+           /* ignore paths > MAXPATHLEN (XXX - log) */
+           if (plen + NAMLEN(dent) >= sizeof(buf))
+               continue;
+           strcpy(buf, path);
+           strcat(buf, dent->d_name);
+
+           /* only stat if basenames are the same */
+           if (strcmp(cmnd_base, dent->d_name) != 0 || stat(buf, &pst) == -1)
+               continue;
+           if (cst.st_dev == pst.st_dev && cst.st_ino == pst.st_ino) {
+               if (safe_cmnd)
+                   free(safe_cmnd);
+               safe_cmnd = estrdup(buf);
+               break;
+           }
+       }
+
+       closedir(dirp);
+       return(dent != NULL);
+    }
+}
+
+/*
+ * Returns TRUE if "n" is one of our ip addresses or if
+ * "n" is a network that we are on, else returns FALSE.
+ */
+int
+addr_matches(n)
+    char *n;
+{
+    int i;
+    char *m;
+    struct in_addr addr, mask;
+
+    /* If there's an explicit netmask, use it. */
+    if ((m = strchr(n, '/'))) {
+       *m++ = '\0';
+       addr.s_addr = inet_addr(n);
+       if (strchr(m, '.'))
+           mask.s_addr = inet_addr(m);
+       else {
+           i = 32 - atoi(m);
+           mask.s_addr = 0xffffffff;
+           mask.s_addr >>= i;
+           mask.s_addr <<= i;
+           mask.s_addr = htonl(mask.s_addr);
+       }
+       *(m - 1) = '/';
+
+       for (i = 0; i < num_interfaces; i++)
+           if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr)
+               return(TRUE);
+    } else {
+       addr.s_addr = inet_addr(n);
+
+       for (i = 0; i < num_interfaces; i++)
+           if (interfaces[i].addr.s_addr == addr.s_addr ||
+               (interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr)
+               == addr.s_addr)
+               return(TRUE);
+    }
+
+    return(FALSE);
+}
+
+/*
+ * Returns 0 if the hostname matches the pattern and non-zero otherwise.
+ */
+int
+hostname_matches(shost, lhost, pattern)
+    char *shost;
+    char *lhost;
+    char *pattern;
+{
+    if (has_meta(pattern)) {
+       if (strchr(pattern, '.'))
+           return(fnmatch(pattern, lhost, FNM_CASEFOLD));
+       else
+           return(fnmatch(pattern, shost, FNM_CASEFOLD));
+    } else {
+       if (strchr(pattern, '.'))
+           return(strcasecmp(lhost, pattern));
+       else
+           return(strcasecmp(shost, pattern));
+    }
+}
+
+/*
+ *  Returns TRUE if the given user belongs to the named group,
+ *  else returns FALSE.
+ */
+int
+usergr_matches(group, user)
+    char *group;
+    char *user;
+{
+    struct group *grp;
+    struct passwd *pw;
+    char **cur;
+
+    /* make sure we have a valid usergroup, sudo style */
+    if (*group++ != '%')
+       return(FALSE);
+
+    if ((grp = getgrnam(group)) == NULL) 
+       return(FALSE);
+
+    /*
+     * Check against user's real gid as well as group's user list
+     */
+    if ((pw = getpwnam(user)) == NULL)
+       return(FALSE);
+
+    if (grp->gr_gid == pw->pw_gid)
+       return(TRUE);
+
+    for (cur=grp->gr_mem; *cur; cur++) {
+       if (strcmp(*cur, user) == 0)
+           return(TRUE);
+    }
+
+    return(FALSE);
+}
+
+/*
+ * Returns TRUE if "host" and "user" belong to the netgroup "netgr",
+ * else return FALSE.  Either of "host", "shost" or "user" may be NULL
+ * in which case that argument is not checked...
+ */
+int
+netgr_matches(netgr, host, shost, user)
+    char *netgr;
+    char *host;
+    char *shost;
+    char *user;
+{
+#ifdef HAVE_GETDOMAINNAME
+    static char *domain = (char *) -1;
+#else
+    static char *domain = NULL;
+#endif /* HAVE_GETDOMAINNAME */
+
+    /* make sure we have a valid netgroup, sudo style */
+    if (*netgr++ != '+')
+       return(FALSE);
+
+#ifdef HAVE_GETDOMAINNAME
+    /* get the domain name (if any) */
+    if (domain == (char *) -1) {
+       domain = (char *) emalloc(MAXHOSTNAMELEN);
+       if (getdomainname(domain, MAXHOSTNAMELEN) == -1 || *domain == '\0') {
+           free(domain);
+           domain = NULL;
+       }
+    }
+#endif /* HAVE_GETDOMAINNAME */
+
+#ifdef HAVE_INNETGR
+    if (innetgr(netgr, host, user, domain))
+       return(TRUE);
+    else if (host != shost && innetgr(netgr, shost, user, domain))
+       return(TRUE);
+#endif /* HAVE_INNETGR */
+
+    return(FALSE);
+}
+
+/*
+ * Returns TRUE if "s" has shell meta characters in it,
+ * else returns FALSE.
+ */
+static int
+has_meta(s)
+    char *s;
+{
+    char *t;
+    
+    for (t = s; *t; t++) {
+       if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']')
+           return(TRUE);
+    }
+    return(FALSE);
+}
diff --git a/parse.h b/parse.h
new file mode 100644 (file)
index 0000000..939f403
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1996, 1998-2000 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: parse.h,v 1.9 2000/03/23 04:38:20 millert Exp $
+ */
+
+#ifndef _SUDO_PARSE_H
+#define _SUDO_PARSE_H
+
+/*
+ * Data structure used in parsing sudoers;
+ * top of stack values are the ones that
+ * apply when parsing is done & can be
+ * accessed by *_matches macros
+ */
+#define STACKINCREMENT (32)
+struct matchstack {
+       int user;
+       int cmnd;
+       int host;
+       int runas;
+       int nopass;
+};
+
+/*
+ * Data structure describing a command in the
+ * sudoers file.
+ */
+struct sudo_command {
+    char *cmnd;
+    char *args;
+};
+
+#define user_matches   (match[top-1].user)
+#define cmnd_matches   (match[top-1].cmnd)
+#define host_matches   (match[top-1].host)
+#define runas_matches  (match[top-1].runas)
+#define no_passwd      (match[top-1].nopass)
+
+/*
+ * Structure containing command matches if "sudo -l" is used.
+ */
+struct command_match {
+    char *runas;
+    size_t runas_len;
+    size_t runas_size;
+    char *cmnd;
+    size_t cmnd_len;
+    size_t cmnd_size;
+    int nopasswd;
+};
+
+/*
+ * Structure describing an alias match in parser.
+ */
+typedef struct {
+    int type;
+    char *name;
+    int val;
+} aliasinfo;
+
+/*
+ * Structure containing Cmnd_Alias's if "sudo -l" is used.
+ */
+struct generic_alias {
+    int type;
+    char *alias;
+    char *entries;
+    size_t entries_size;
+    size_t entries_len;
+};
+
+/* The matching stack and number of entries on it. */
+extern struct matchstack *match;
+extern int top;
+
+/*
+ * Prototypes
+ */
+int addr_matches       __P((char *));
+int command_matches    __P((char *, char *, char *, char *));
+int hostname_matches   __P((char *, char *, char *));
+int netgr_matches      __P((char *, char *, char *, char *));
+int usergr_matches     __P((char *, char *));
+
+#endif /* _SUDO_PARSE_H */
diff --git a/parse.lex b/parse.lex
new file mode 100644 (file)
index 0000000..773be1b
--- /dev/null
+++ b/parse.lex
@@ -0,0 +1,443 @@
+%{
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * This code is derived from software contributed by Chris Jepeway
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <ctype.h>
+#include "sudo.h"
+#include "parse.h"
+#include <sudo.tab.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: parse.lex,v 1.119 2002/03/16 00:44:47 millert Exp $";
+#endif /* lint */
+
+#undef yywrap          /* guard against a yywrap macro */
+
+extern YYSTYPE yylval;
+extern int clearaliases;
+int sudolineno = 1;
+static int sawspace = 0;
+static int arg_len = 0;
+static int arg_size = 0;
+
+static void fill               __P((char *, int));
+static void fill_cmnd          __P((char *, int));
+static void fill_args          __P((char *, int, int));
+extern void reset_aliases      __P((void));
+extern void yyerror            __P((char *));
+
+/* realloc() to size + COMMANDARGINC to make room for command args */
+#define COMMANDARGINC  64
+
+#ifdef TRACELEXER
+#define LEXTRACE(msg)  fputs(msg, stderr)
+#else
+#define LEXTRACE(msg)
+#endif
+%}
+
+OCTET                  (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5])
+DOTTEDQUAD             {OCTET}(\.{OCTET}){3}
+HOSTNAME               [[:alnum:]_-]+
+WORD                   ([^#@!=:,\(\) \t\n\\]|\\[^\n])+
+ENVAR                  ([^#!=, \t\n\\]|\\[^\n])([^#=, \t\n\\]|\\[^\n])*
+DEFVAR                 [a-z_]+
+
+/* XXX - convert GOTRUNAS to exclusive state (GOTDEFS cannot be) */
+%s     GOTRUNAS
+%s     GOTDEFS
+%x     GOTCMND
+%x     STARTDEFS
+%x     INDEFS
+
+%%
+<GOTDEFS>[[:blank:]]+  BEGIN STARTDEFS;
+
+<STARTDEFS>{DEFVAR}    {
+                           BEGIN INDEFS;
+                           LEXTRACE("DEFVAR ");
+                           fill(yytext, yyleng);
+                           return(DEFVAR);
+                       }
+
+<INDEFS>{
+    ,                  {
+                           BEGIN STARTDEFS;
+                           LEXTRACE(", ");
+                           return(',');
+                       }                       /* return ',' */
+
+    =                  {
+                           LEXTRACE("= ");
+                           return('=');
+                       }                       /* return '=' */
+
+    \+=                        {
+                           LEXTRACE("+= ");
+                           return('+');
+                       }                       /* return '+' */
+
+    -=                 {
+                           LEXTRACE("-= ");
+                           return('-');
+                       }                       /* return '-' */
+
+    \"([^\"]|\\\")+\"  {
+                           LEXTRACE("WORD(1) ");
+                           fill(yytext + 1, yyleng - 2);
+                           return(WORD);
+                       }
+
+    {ENVAR}            {
+                           LEXTRACE("WORD(2) ");
+                           fill(yytext, yyleng);
+                           return(WORD);
+                       }
+}
+
+<GOTCMND>{
+    \\[:\\,= \t#]      {
+                           LEXTRACE("QUOTEDCHAR ");
+                           fill_args(yytext + 1, 1, sawspace);
+                           sawspace = FALSE;
+                       }
+
+    [#:\,=\n]          {
+                           BEGIN INITIAL;
+                           unput(*yytext);
+                           return(COMMAND);
+                       }                       /* end of command line args */
+
+    [^\\:, \t\n]+      {
+                           LEXTRACE("ARG ");
+                           fill_args(yytext, yyleng, sawspace);
+                           sawspace = FALSE;
+                       }                       /* a command line arg */
+}
+
+<INITIAL>^Defaults[:@]?        {
+                           BEGIN GOTDEFS;
+                           switch (yytext[8]) {
+                               case ':':
+                                   LEXTRACE("DEFAULTS_USER ");
+                                   return(DEFAULTS_USER);
+                               case '@':
+                                   LEXTRACE("DEFAULTS_HOST ");
+                                   return(DEFAULTS_HOST);
+                               default:
+                                   LEXTRACE("DEFAULTS ");
+                                   return(DEFAULTS);
+                           }
+                       }
+
+<INITIAL>^(Host|Cmnd|User|Runas)_Alias {
+                           fill(yytext, yyleng);
+                           switch (*yytext) {
+                               case 'H':
+                                   LEXTRACE("HOSTALIAS ");
+                                   return(HOSTALIAS);
+                               case 'C':
+                                   LEXTRACE("CMNDALIAS ");
+                                   return(CMNDALIAS);
+                               case 'U':
+                                   LEXTRACE("USERALIAS ");
+                                   return(USERALIAS);
+                               case 'R':
+                                   LEXTRACE("RUNASALIAS ");
+                                   BEGIN GOTRUNAS;
+                                   return(RUNASALIAS);
+                           }
+                       }
+
+NOPASSWD[[:blank:]]*:  {
+                               /* cmnd does not require passwd for this user */
+                               LEXTRACE("NOPASSWD ");
+                               return(NOPASSWD);
+                       }
+
+PASSWD[[:blank:]]*:    {
+                               /* cmnd requires passwd for this user */
+                               LEXTRACE("PASSWD ");
+                               return(PASSWD);
+                       }
+
+\+{WORD}               {
+                           /* netgroup */
+                           fill(yytext, yyleng);
+                           LEXTRACE("NETGROUP ");
+                           return(NETGROUP);
+                       }
+
+\%{WORD}               {
+                           /* UN*X group */
+                           fill(yytext, yyleng);
+                           LEXTRACE("GROUP ");
+                           return(USERGROUP);
+                       }
+
+{DOTTEDQUAD}(\/{DOTTEDQUAD})? {
+                           fill(yytext, yyleng);
+                           LEXTRACE("NTWKADDR ");
+                           return(NTWKADDR);
+                       }
+
+{DOTTEDQUAD}\/([12][0-9]*|3[0-2]*) {
+                           fill(yytext, yyleng);
+                           LEXTRACE("NTWKADDR ");
+                           return(NTWKADDR);
+                       }
+
+<INITIAL>\(            {
+                               BEGIN GOTRUNAS;
+                               LEXTRACE("RUNAS ");
+                               return (RUNAS);
+                       }
+
+[[:upper:]][[:upper:][:digit:]_]* {
+                           if (strcmp(yytext, "ALL") == 0) {
+                               LEXTRACE("ALL ");
+                               return(ALL);
+                           } else {
+                               fill(yytext, yyleng);
+                               LEXTRACE("ALIAS ");
+                               return(ALIAS);
+                           }
+                       }
+
+<GOTRUNAS>(#[0-9-]+|{WORD}) {
+                           /* username/uid that user can run command as */
+                           fill(yytext, yyleng);
+                           LEXTRACE("WORD(3) ");
+                           return(WORD);
+                       }
+
+<GOTRUNAS>\)           {
+                           BEGIN INITIAL;
+                       }
+
+\/(\\[\,:= \t#]|[^\,:=\\ \t\n#])+      {
+                           /* directories can't have args... */
+                           if (yytext[yyleng - 1] == '/') {
+                               LEXTRACE("COMMAND ");
+                               fill_cmnd(yytext, yyleng);
+                               return(COMMAND);
+                           } else {
+                               BEGIN GOTCMND;
+                               LEXTRACE("COMMAND ");
+                               fill_cmnd(yytext, yyleng);
+                           }
+                       }                       /* a pathname */
+
+<INITIAL,GOTDEFS>{WORD} {
+                           /* a word */
+                           fill(yytext, yyleng);
+                           LEXTRACE("WORD(4) ");
+                           return(WORD);
+                       }
+
+,                      {
+                           LEXTRACE(", ");
+                           return(',');
+                       }                       /* return ',' */
+
+=                      {
+                           LEXTRACE("= ");
+                           return('=');
+                       }                       /* return '=' */
+
+:                      {
+                           LEXTRACE(": ");
+                           return(':');
+                       }                       /* return ':' */
+
+<*>!+                  {
+                           if (yyleng % 2 == 1)
+                               return('!');    /* return '!' */
+                       }
+
+<*>\n                  {
+                           BEGIN INITIAL;
+                           ++sudolineno;
+                           LEXTRACE("\n");
+                           return(COMMENT);
+                       }                       /* return newline */
+
+<*>[[:blank:]]+                {                       /* throw away space/tabs */
+                           sawspace = TRUE;    /* but remember for fill_args */
+                       }
+
+<*>\\[[:blank:]]*\n    {
+                           sawspace = TRUE;    /* remember for fill_args */
+                           ++sudolineno;
+                           LEXTRACE("\n\t");
+                       }                       /* throw away EOL after \ */
+
+<INITIAL,STARTDEFS,INDEFS>#.*\n        {
+                           BEGIN INITIAL;
+                           ++sudolineno;
+                           LEXTRACE("\n");
+                           return(COMMENT);
+                       }                       /* return comments */
+
+<*>.                   {
+                           LEXTRACE("ERROR ");
+                           return(ERROR);
+                       }       /* parse error */
+
+%%
+static void
+fill(s, len)
+    char *s;
+    int len;
+{
+    int i, j;
+
+    yylval.string = (char *) malloc(len + 1);
+    if (yylval.string == NULL)
+       yyerror("unable to allocate memory");
+
+    /* Copy the string and collapse any escaped characters. */
+    for (i = 0, j = 0; i < len; i++, j++) {
+       if (s[i] == '\\' && i != len - 1)
+           yylval.string[j] = s[++i];
+       else
+           yylval.string[j] = s[i];
+    }
+    yylval.string[j] = '\0';
+}
+
+static void
+fill_cmnd(s, len)
+    char *s;
+    int len;
+{
+    arg_len = arg_size = 0;
+
+    yylval.command.cmnd = (char *) malloc(len + 1);
+    if (yylval.command.cmnd == NULL)
+       yyerror("unable to allocate memory");
+
+    /* copy the string and NULL-terminate it (escapes handled by fnmatch) */
+    (void) strncpy(yylval.command.cmnd, s, len);
+    yylval.command.cmnd[len] = '\0';
+
+    yylval.command.args = NULL;
+}
+
+static void
+fill_args(s, len, addspace)
+    char *s;
+    int len;
+    int addspace;
+{
+    int new_len;
+    char *p;
+
+    /*
+     * If first arg, malloc() some room, else if we don't
+     * have enough space realloc() some more.
+     */
+    if (yylval.command.args == NULL) {
+       addspace = 0;
+       new_len = len;
+
+       while (new_len >= (arg_size += COMMANDARGINC))
+           ;
+
+       yylval.command.args = (char *) malloc(arg_size);
+       if (yylval.command.args == NULL)
+           yyerror("unable to allocate memory");
+    } else {
+       new_len = arg_len + len + addspace;
+
+       if (new_len >= arg_size) {
+           /* Allocate more space than we need for subsequent args */
+           while (new_len >= (arg_size += COMMANDARGINC))
+               ;
+
+           if ((p = (char *) realloc(yylval.command.args, arg_size)) == NULL) {
+               free(yylval.command.args);
+               yyerror("unable to allocate memory");
+           } else
+               yylval.command.args = p;
+       }
+    }
+
+    /* Efficiently append the arg (with a leading space if needed). */
+    p = yylval.command.args + arg_len;
+    if (addspace)
+       *p++ = ' ';
+    (void) strcpy(p, s);
+    arg_len = new_len;
+}
+
+int
+yywrap()
+{
+
+    /* Free space used by the aliases unless called by testsudoers. */
+    if (clearaliases)
+       reset_aliases();
+
+    return(TRUE);
+}
diff --git a/parse.yacc b/parse.yacc
new file mode 100644 (file)
index 0000000..7a6fb4e
--- /dev/null
@@ -0,0 +1,1193 @@
+%{
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * XXX - the whole opFOO naming thing is somewhat bogus.
+ *
+ * XXX - the way things are stored for printmatches is stupid,
+ *       they should be stored as elements in an array and then
+ *       list_matches() can format things the way it wants.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+# include <alloca.h>
+#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
+#ifdef HAVE_LSEARCH
+# include <search.h>
+#endif /* HAVE_LSEARCH */
+
+#include "sudo.h"
+#include "parse.h"
+
+#ifndef HAVE_LSEARCH
+#include "emul/search.h"
+#endif /* HAVE_LSEARCH */
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: parse.yacc,v 1.180 2002/03/16 00:44:47 millert Exp $";
+#endif /* lint */
+
+/*
+ * Globals
+ */
+extern int sudolineno, parse_error;
+int errorlineno = -1;
+int clearaliases = TRUE;
+int printmatches = FALSE;
+int pedantic = FALSE;
+int keepall = FALSE;
+int quiet = FALSE;
+
+/*
+ * Alias types
+ */
+#define HOST_ALIAS              1
+#define CMND_ALIAS              2
+#define USER_ALIAS              3
+#define RUNAS_ALIAS             4
+
+/*
+ * The matching stack, initial space allocated in init_parser().
+ */
+struct matchstack *match;
+int top = 0, stacksize = 0;
+
+#define push \
+    do { \
+       if (top >= stacksize) { \
+           while ((stacksize += STACKINCREMENT) < top); \
+           match = (struct matchstack *) erealloc(match, sizeof(struct matchstack) * stacksize); \
+       } \
+       match[top].user   = -1; \
+       match[top].cmnd   = -1; \
+       match[top].host   = -1; \
+       match[top].runas  = -1; \
+       match[top].nopass = def_flag(I_AUTHENTICATE) ? -1 : TRUE; \
+       top++; \
+    } while (0)
+
+#define pushcp \
+    do { \
+       if (top >= stacksize) { \
+           while ((stacksize += STACKINCREMENT) < top); \
+           match = (struct matchstack *) erealloc(match, sizeof(struct matchstack) * stacksize); \
+       } \
+       match[top].user   = match[top-1].user; \
+       match[top].cmnd   = match[top-1].cmnd; \
+       match[top].host   = match[top-1].host; \
+       match[top].runas  = match[top-1].runas; \
+       match[top].nopass = match[top-1].nopass; \
+       top++; \
+    } while (0)
+
+#define pop \
+    { \
+       if (top == 0) \
+           yyerror("matching stack underflow"); \
+       else \
+           top--; \
+    }
+
+/*
+ * Shortcuts for append()
+ */
+#define append_cmnd(s, p) append(s, &cm_list[cm_list_len].cmnd, \
+       &cm_list[cm_list_len].cmnd_len, &cm_list[cm_list_len].cmnd_size, p)
+
+#define append_runas(s, p) append(s, &cm_list[cm_list_len].runas, \
+       &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, p)
+
+#define append_entries(s, p) append(s, &ga_list[ga_list_len-1].entries, \
+       &ga_list[ga_list_len-1].entries_len, \
+       &ga_list[ga_list_len-1].entries_size, p)
+
+/*
+ * The stack for printmatches.  A list of allowed commands for the user.
+ */
+static struct command_match *cm_list = NULL;
+static size_t cm_list_len = 0, cm_list_size = 0;
+
+/*
+ * List of Cmnd_Aliases and expansions for `sudo -l'
+ */
+static int in_alias = FALSE;
+static size_t ga_list_len = 0, ga_list_size = 0;
+static struct generic_alias *ga_list = NULL;
+
+/*
+ * Does this Defaults list pertain to this user?
+ */
+static int defaults_matches = 0;
+
+/*
+ * Local protoypes
+ */
+static int  add_alias          __P((char *, int, int));
+static void append             __P((char *, char **, size_t *, size_t *, char *));
+static void expand_ga_list     __P((void));
+static void expand_match_list  __P((void));
+static aliasinfo *find_alias   __P((char *, int));
+static int  more_aliases       __P((void));
+       void init_parser                __P((void));
+       void yyerror            __P((char *));
+
+void
+yyerror(s)
+    char *s;
+{
+    /* Save the line the first error occurred on. */
+    if (errorlineno == -1)
+       errorlineno = sudolineno ? sudolineno - 1 : 0;
+    if (s && !quiet) {
+#ifndef TRACELEXER
+       (void) fprintf(stderr, ">>> sudoers file: %s, line %d <<<\n", s,
+           sudolineno ? sudolineno - 1 : 0);
+#else
+       (void) fprintf(stderr, "<*> ");
+#endif
+    }
+    parse_error = TRUE;
+}
+%}
+
+%union {
+    char *string;
+    int BOOLEAN;
+    struct sudo_command command;
+    int tok;
+}
+
+%start file                            /* special start symbol */
+%token <command> COMMAND               /* absolute pathname w/ optional args */
+%token <string>  ALIAS                 /* an UPPERCASE alias name */
+%token <string>         DEFVAR                 /* a Defaults variable name */
+%token <string>  NTWKADDR              /* w.x.y.z */
+%token <string>  NETGROUP              /* a netgroup (+NAME) */
+%token <string>  USERGROUP             /* a usergroup (%NAME) */
+%token <string>  WORD                  /* a word */
+%token <tok>    DEFAULTS               /* Defaults entry */
+%token <tok>    DEFAULTS_HOST          /* Host-specific defaults entry */
+%token <tok>    DEFAULTS_USER          /* User-specific defaults entry */
+%token <tok>    RUNAS                  /* ( runas_list ) */
+%token <tok>    NOPASSWD               /* no passwd req for command */
+%token <tok>    PASSWD                 /* passwd req for command (default) */
+%token <tok>    ALL                    /* ALL keyword */
+%token <tok>    COMMENT                /* comment and/or carriage return */
+%token <tok>    HOSTALIAS              /* Host_Alias keyword */
+%token <tok>    CMNDALIAS              /* Cmnd_Alias keyword */
+%token <tok>    USERALIAS              /* User_Alias keyword */
+%token <tok>    RUNASALIAS             /* Runas_Alias keyword */
+%token <tok>    ':' '=' ',' '!' '+' '-' /* union member tokens */
+%token <tok>    ERROR
+
+/*
+ * NOTE: these are not true booleans as there are actually 3 possible values: 
+ *        1) TRUE (positive match)
+ *        0) FALSE (negative match due to a '!' somewhere)
+ *       -1) No match (don't change the value of *_matches)
+ */
+%type <BOOLEAN>         cmnd
+%type <BOOLEAN>         host
+%type <BOOLEAN>         runasuser
+%type <BOOLEAN>         oprunasuser
+%type <BOOLEAN>         runaslist
+%type <BOOLEAN>         user
+
+%%
+
+file           :       entry
+               |       file entry
+               ;
+
+entry          :       COMMENT
+                           { ; }
+                |       error COMMENT
+                           { yyerrok; }
+               |       { push; } userlist privileges {
+                           while (top && user_matches != TRUE)
+                               pop;
+                       }
+               |       USERALIAS useraliases
+                           { ; }
+               |       HOSTALIAS hostaliases
+                           { ; }
+               |       CMNDALIAS cmndaliases
+                           { ; }
+               |       RUNASALIAS runasaliases
+                           { ; }
+               |       defaults_line
+                           { ; }
+               ;
+
+defaults_line  :       defaults_type defaults_list
+
+defaults_type  :       DEFAULTS {
+                           defaults_matches = TRUE;
+                       }
+               |       DEFAULTS_USER { push; } userlist {
+                           defaults_matches = user_matches;
+                           pop;
+                       }
+               |       DEFAULTS_HOST { push; } hostlist {
+                           defaults_matches = host_matches;
+                           pop;
+                       }
+               ;
+
+defaults_list  :       defaults_entry
+               |       defaults_entry ',' defaults_list
+
+defaults_entry :       DEFVAR {
+                           if (defaults_matches == TRUE &&
+                               !set_default($1, NULL, TRUE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free($1);
+                       }
+               |       '!' DEFVAR {
+                           if (defaults_matches == TRUE &&
+                               !set_default($2, NULL, FALSE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free($2);
+                       }
+               |       DEFVAR '=' WORD {
+                           if (defaults_matches == TRUE &&
+                               !set_default($1, $3, TRUE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free($1);
+                           free($3);
+                       }
+               |       DEFVAR '+' WORD {
+                           if (defaults_matches == TRUE &&
+                               !set_default($1, $3, '+')) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free($1);
+                           free($3);
+                       }
+               |       DEFVAR '-' WORD {
+                           if (defaults_matches == TRUE &&
+                               !set_default($1, $3, '-')) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free($1);
+                           free($3);
+                       }
+
+privileges     :       privilege
+               |       privileges ':' privilege
+               ;
+
+privilege      :       hostlist '=' cmndspeclist {
+                           /*
+                            * We already did a push if necessary in
+                            * cmndspec so just reset some values so
+                            * the next 'privilege' gets a clean slate.
+                            */
+                           host_matches = -1;
+                           runas_matches = -1;
+                           if (def_flag(I_AUTHENTICATE))
+                               no_passwd = -1;
+                           else
+                               no_passwd = TRUE;
+                       }
+               ;
+
+ophost         :       host {
+                           if ($1 != -1)
+                               host_matches = $1;
+                       }
+               |       '!' host {
+                           if ($2 != -1)
+                               host_matches = ! $2;
+                       }
+
+host           :       ALL {
+                           $$ = TRUE;
+                       }
+               |       NTWKADDR {
+                           if (addr_matches($1))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       NETGROUP {
+                           if (netgr_matches($1, user_host, user_shost, NULL))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       WORD {
+                           if (hostname_matches(user_shost, user_host, $1) == 0)
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       ALIAS {
+                           aliasinfo *aip = find_alias($1, HOST_ALIAS);
+
+                           /* could be an all-caps hostname */
+                           if (aip)
+                               $$ = aip->val;
+                           else if (strcasecmp(user_shost, $1) == 0)
+                               $$ = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Host_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", $1, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               $$ = -1;
+                           }
+                           free($1);
+                       }
+               ;
+
+cmndspeclist   :       cmndspec
+               |       cmndspeclist ',' cmndspec
+               ;
+
+cmndspec       :       runasspec nopasswd opcmnd {
+                           /*
+                            * Push the entry onto the stack if it is worth
+                            * saving and clear cmnd_matches for next cmnd.
+                            *
+                            * We need to save at least one entry on
+                            * the stack so sudoers_lookup() can tell that
+                            * the user was listed in sudoers.  Also, we
+                            * need to be able to tell whether or not a
+                            * user was listed for this specific host.
+                            *
+                            * If keepall is set and the user matches then
+                            * we need to keep entries around too...
+                            */
+                           if (user_matches != -1 && host_matches != -1 &&
+                               cmnd_matches != -1 && runas_matches != -1)
+                               pushcp;
+                           else if (user_matches != -1 && (top == 1 ||
+                               (top == 2 && host_matches != -1 &&
+                               match[0].host == -1)))
+                               pushcp;
+                           else if (user_matches == TRUE && keepall)
+                               pushcp;
+                           cmnd_matches = -1;
+                       }
+               ;
+
+opcmnd         :       cmnd {
+                           if ($1 != -1)
+                               cmnd_matches = $1;
+                       }
+               |       '!' {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("!", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_cmnd("!", NULL);
+                           }
+                       } cmnd {
+                           if ($3 != -1)
+                               cmnd_matches = ! $3;
+                       }
+               ;
+
+runasspec      :       /* empty */ {
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE) {
+                               if (runas_matches == -1) {
+                                   cm_list[cm_list_len].runas_len = 0;
+                               } else {
+                                   /* Inherit runas data. */
+                                   cm_list[cm_list_len].runas =
+                                       estrdup(cm_list[cm_list_len-1].runas);
+                                   cm_list[cm_list_len].runas_len =
+                                       cm_list[cm_list_len-1].runas_len;
+                                   cm_list[cm_list_len].runas_size =
+                                       cm_list[cm_list_len-1].runas_size;
+                               }
+                           }
+                           /*
+                            * If this is the first entry in a command list
+                            * then check against default runas user.
+                            */
+                           if (runas_matches == -1)
+                               runas_matches = (strcmp(*user_runas,
+                                   def_str(I_RUNAS_DEFAULT)) == 0);
+                       }
+               |       RUNAS runaslist {
+                           runas_matches = ($2 == TRUE ? TRUE : FALSE);
+                       }
+               ;
+
+runaslist      :       oprunasuser { ; }
+               |       runaslist ',' oprunasuser {
+                           /* Later entries override earlier ones. */
+                           if ($3 != -1)
+                               $$ = $3;
+                           else
+                               $$ = $1;
+                       }
+               ;
+
+oprunasuser    :       runasuser { ; }
+               |       '!' {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("!", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas("!", ", ");
+                           }
+                       } runasuser {
+                           /* Set $$ to the negation of runasuser */
+                           $$ = ($3 == -1 ? -1 : ! $3);
+                       }
+
+runasuser      :       WORD {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries($1, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas($1, ", ");
+                           }
+                           if (strcmp($1, *user_runas) == 0)
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       USERGROUP {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries($1, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas($1, ", ");
+                           }
+                           if (usergr_matches($1, *user_runas))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       NETGROUP {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries($1, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas($1, ", ");
+                           }
+                           if (netgr_matches($1, NULL, NULL, *user_runas))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       ALIAS {
+                           aliasinfo *aip = find_alias($1, RUNAS_ALIAS);
+
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries($1, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas($1, ", ");
+                           }
+                           /* could be an all-caps username */
+                           if (aip)
+                               $$ = aip->val;
+                           else if (strcmp($1, *user_runas) == 0)
+                               $$ = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Runas_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", $1, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               $$ = -1;
+                           }
+                           free($1);
+                       }
+               |       ALL {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("ALL", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas("ALL", ", ");
+                           }
+                           $$ = TRUE;
+                       }
+               ;
+
+nopasswd       :       /* empty */ {
+                           /* Inherit NOPASSWD/PASSWD status. */
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE) {
+                               if (no_passwd == TRUE)
+                                   cm_list[cm_list_len].nopasswd = TRUE;
+                               else
+                                   cm_list[cm_list_len].nopasswd = FALSE;
+                           }
+                       }
+               |       NOPASSWD {
+                           no_passwd = TRUE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].nopasswd = TRUE;
+                       }
+               |       PASSWD {
+                           no_passwd = FALSE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].nopasswd = FALSE;
+                       }
+               ;
+
+cmnd           :       ALL {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("ALL", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE) {
+                                   append_cmnd("ALL", NULL);
+                                   expand_match_list();
+                               }
+                           }
+
+                           $$ = TRUE;
+
+                           if (safe_cmnd)
+                               free(safe_cmnd);
+                           safe_cmnd = estrdup(user_cmnd);
+                       }
+               |       ALIAS {
+                           aliasinfo *aip;
+
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries($1, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE) {
+                                   append_cmnd($1, NULL);
+                                   expand_match_list();
+                               }
+                           }
+
+                           if ((aip = find_alias($1, CMND_ALIAS)))
+                               $$ = aip->val;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Cmnd_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", $1, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               $$ = -1;
+                           }
+                           free($1);
+                       }
+               |        COMMAND {
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE) {
+                                   append_entries($1.cmnd, ", ");
+                                   if ($1.args)
+                                       append_entries($1.args, " ");
+                               }
+                               if (host_matches == TRUE &&
+                                   user_matches == TRUE)  {
+                                   append_cmnd($1.cmnd, NULL);
+                                   if ($1.args)
+                                       append_cmnd($1.args, " ");
+                                   expand_match_list();
+                               }
+                           }
+
+                           if (command_matches(user_cmnd, user_args,
+                               $1.cmnd, $1.args))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+
+                           free($1.cmnd);
+                           if ($1.args)
+                               free($1.args);
+                       }
+               ;
+
+hostaliases    :       hostalias
+               |       hostaliases ':' hostalias
+               ;
+
+hostalias      :       ALIAS { push; } '=' hostlist {
+                           if ((host_matches != -1 || pedantic) &&
+                               !add_alias($1, HOST_ALIAS, host_matches))
+                               YYERROR;
+                           pop;
+                       }
+               ;
+
+hostlist       :       ophost
+               |       hostlist ',' ophost
+               ;
+
+cmndaliases    :       cmndalias
+               |       cmndaliases ':' cmndalias
+               ;
+
+cmndalias      :       ALIAS {
+                           push;
+                           if (printmatches == TRUE) {
+                               in_alias = TRUE;
+                               /* Allocate space for ga_list if necessary. */
+                               expand_ga_list();
+                               ga_list[ga_list_len-1].type = CMND_ALIAS;
+                               ga_list[ga_list_len-1].alias = estrdup($1);
+                            }
+                       } '=' cmndlist {
+                           if ((cmnd_matches != -1 || pedantic) &&
+                               !add_alias($1, CMND_ALIAS, cmnd_matches))
+                               YYERROR;
+                           pop;
+                           free($1);
+
+                           if (printmatches == TRUE)
+                               in_alias = FALSE;
+                       }
+               ;
+
+cmndlist       :       opcmnd { ; }
+               |       cmndlist ',' opcmnd
+               ;
+
+runasaliases   :       runasalias
+               |       runasaliases ':' runasalias
+               ;
+
+runasalias     :       ALIAS {
+                           if (printmatches == TRUE) {
+                               in_alias = TRUE;
+                               /* Allocate space for ga_list if necessary. */
+                               expand_ga_list();
+                               ga_list[ga_list_len-1].type = RUNAS_ALIAS;
+                               ga_list[ga_list_len-1].alias = estrdup($1);
+                           }
+                       } '=' runaslist {
+                           if (($4 != -1 || pedantic) &&
+                               !add_alias($1, RUNAS_ALIAS, $4))
+                               YYERROR;
+                           free($1);
+
+                           if (printmatches == TRUE)
+                               in_alias = FALSE;
+                       }
+               ;
+
+useraliases    :       useralias
+               |       useraliases ':' useralias
+               ;
+
+useralias      :       ALIAS { push; } '=' userlist {
+                           if ((user_matches != -1 || pedantic) &&
+                               !add_alias($1, USER_ALIAS, user_matches))
+                               YYERROR;
+                           pop;
+                           free($1);
+                       }
+               ;
+
+userlist       :       opuser
+               |       userlist ',' opuser
+               ;
+
+opuser         :       user {
+                           if ($1 != -1)
+                               user_matches = $1;
+                       }
+               |       '!' user {
+                           if ($2 != -1)
+                               user_matches = ! $2;
+                       }
+
+user           :       WORD {
+                           if (strcmp($1, user_name) == 0)
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       USERGROUP {
+                           if (usergr_matches($1, user_name))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       NETGROUP {
+                           if (netgr_matches($1, NULL, NULL, user_name))
+                               $$ = TRUE;
+                           else
+                               $$ = -1;
+                           free($1);
+                       }
+               |       ALIAS {
+                           aliasinfo *aip = find_alias($1, USER_ALIAS);
+
+                           /* could be an all-caps username */
+                           if (aip)
+                               $$ = aip->val;
+                           else if (strcmp($1, user_name) == 0)
+                               $$ = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared User_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", $1, sudolineno);
+                                   if (pedantic > 1)
+                                       YYERROR;
+                               }
+                               $$ = -1;
+                           }
+                           free($1);
+                       }
+               |       ALL {
+                           $$ = TRUE;
+                       }
+               ;
+
+%%
+
+#define MOREALIASES (32)
+aliasinfo *aliases = NULL;
+size_t naliases = 0;
+size_t nslots = 0;
+
+
+/*
+ * Compare two aliasinfo structures, strcmp() style.
+ * Note that we do *not* compare their values.
+ */
+static int
+aliascmp(a1, a2)
+    const VOID *a1, *a2;
+{
+    int r;
+    aliasinfo *ai1, *ai2;
+
+    ai1 = (aliasinfo *) a1;
+    ai2 = (aliasinfo *) a2;
+    if ((r = strcmp(ai1->name, ai2->name)) == 0)
+       r = ai1->type - ai2->type;
+
+    return(r);
+}
+
+/*
+ * Compare two generic_alias structures, strcmp() style.
+ */
+static int
+genaliascmp(entry, key)
+    const VOID *entry, *key;
+{
+    int r;
+    struct generic_alias *ga1, *ga2;
+
+    ga1 = (struct generic_alias *) key;
+    ga2 = (struct generic_alias *) entry;
+    if ((r = strcmp(ga1->alias, ga2->alias)) == 0)
+       r = ga1->type - ga2->type;
+
+    return(r);
+}
+
+
+/*
+ * Adds the named alias of the specified type to the aliases list.
+ */
+static int
+add_alias(alias, type, val)
+    char *alias;
+    int type;
+    int val;
+{
+    aliasinfo ai, *aip;
+    size_t onaliases;
+    char s[512];
+
+    if (naliases >= nslots && !more_aliases()) {
+       (void) snprintf(s, sizeof(s), "Out of memory defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
+
+    ai.type = type;
+    ai.val = val;
+    ai.name = estrdup(alias);
+    onaliases = naliases;
+
+    aip = (aliasinfo *) lsearch((VOID *)&ai, (VOID *)aliases, &naliases,
+                               sizeof(ai), aliascmp);
+    if (aip == NULL) {
+       (void) snprintf(s, sizeof(s), "Aliases corrupted defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
+    if (onaliases == naliases) {
+       (void) snprintf(s, sizeof(s), "Alias `%s' already defined", alias);
+       yyerror(s);
+       return(FALSE);
+    }
+
+    return(TRUE);
+}
+
+/*
+ * Searches for the named alias of the specified type.
+ */
+static aliasinfo *
+find_alias(alias, type)
+    char *alias;
+    int type;
+{
+    aliasinfo ai;
+
+    ai.name = alias;
+    ai.type = type;
+
+    return((aliasinfo *) lfind((VOID *)&ai, (VOID *)aliases, &naliases,
+                sizeof(ai), aliascmp));
+}
+
+/*
+ * Allocates more space for the aliases list.
+ */
+static int
+more_aliases()
+{
+
+    nslots += MOREALIASES;
+    if (nslots == MOREALIASES)
+       aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
+    else
+       aliases = (aliasinfo *) realloc(aliases, nslots * sizeof(aliasinfo));
+
+    return(aliases != NULL);
+}
+
+/*
+ * Lists the contents of the aliases list.
+ */
+void
+dumpaliases()
+{
+    size_t n;
+
+    for (n = 0; n < naliases; n++) {
+       if (aliases[n].val == -1)
+           continue;
+
+       switch (aliases[n].type) {
+       case HOST_ALIAS:
+           (void) puts("HOST_ALIAS");
+           break;
+
+       case CMND_ALIAS:
+           (void) puts("CMND_ALIAS");
+           break;
+
+       case USER_ALIAS:
+           (void) puts("USER_ALIAS");
+           break;
+
+       case RUNAS_ALIAS:
+           (void) puts("RUNAS_ALIAS");
+           break;
+       }
+       (void) printf("\t%s: %d\n", aliases[n].name, aliases[n].val);
+    }
+}
+
+/*
+ * Lists the contents of cm_list and ga_list for `sudo -l'.
+ */
+void
+list_matches()
+{
+    int i; 
+    char *p;
+    struct generic_alias *ga, key;
+
+    (void) printf("User %s may run the following commands on this host:\n",
+       user_name);
+    for (i = 0; i < cm_list_len; i++) {
+
+       /* Print the runas list. */
+       (void) fputs("    ", stdout);
+       if (cm_list[i].runas) {
+           (void) putchar('(');
+           p = strtok(cm_list[i].runas, ", ");
+           do {
+               if (p != cm_list[i].runas)
+                   (void) fputs(", ", stdout);
+
+               key.alias = p;
+               key.type = RUNAS_ALIAS;
+               if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+                   (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+                   (void) fputs(ga->entries, stdout);
+               else
+                   (void) fputs(p, stdout);
+           } while ((p = strtok(NULL, ", ")));
+           (void) fputs(") ", stdout);
+       } else {
+           (void) printf("(%s) ", def_str(I_RUNAS_DEFAULT));
+       }
+
+       /* Is a password required? */
+       if (cm_list[i].nopasswd == TRUE && def_flag(I_AUTHENTICATE))
+           (void) fputs("NOPASSWD: ", stdout);
+       else if (cm_list[i].nopasswd == FALSE && !def_flag(I_AUTHENTICATE))
+           (void) fputs("PASSWD: ", stdout);
+
+       /* Print the actual command or expanded Cmnd_Alias. */
+       key.alias = cm_list[i].cmnd;
+       key.type = CMND_ALIAS;
+       if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+           (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+           (void) puts(ga->entries);
+       else
+           (void) puts(cm_list[i].cmnd);
+    }
+
+    /* Be nice and free up space now that we are done. */
+    for (i = 0; i < ga_list_len; i++) {
+       free(ga_list[i].alias);
+       free(ga_list[i].entries);
+    }
+    free(ga_list);
+    ga_list = NULL;
+
+    for (i = 0; i < cm_list_len; i++) {
+       free(cm_list[i].runas);
+       free(cm_list[i].cmnd);
+    }
+    free(cm_list);
+    cm_list = NULL;
+    cm_list_len = 0;
+    cm_list_size = 0;
+}
+
+/*
+ * Appends a source string to the destination, optionally prefixing a separator.
+ */
+static void
+append(src, dstp, dst_len, dst_size, separator)
+    char *src, **dstp;
+    size_t *dst_len, *dst_size;
+    char *separator;
+{
+    size_t src_len = strlen(src);
+    char *dst = *dstp;
+
+    /*
+     * Only add the separator if there is something to separate from.
+     * If the last char is a '!', don't apply the separator (XXX).
+     */
+    if (separator && dst && dst[*dst_len - 1] != '!')
+       src_len += strlen(separator);
+    else
+       separator = NULL;
+
+    /* Assumes dst will be NULL if not set. */
+    if (dst == NULL) {
+       dst = (char *) emalloc(BUFSIZ);
+       *dst_size = BUFSIZ;
+       *dst_len = 0;
+       *dstp = dst;
+    }
+
+    /* Allocate more space if necessary. */
+    if (*dst_size <= *dst_len + src_len) {
+       while (*dst_size <= *dst_len + src_len)
+           *dst_size += BUFSIZ;
+
+       dst = (char *) erealloc(dst, *dst_size);
+       *dstp = dst;
+    }
+
+    /* Copy src -> dst adding a separator if appropriate and adjust len. */
+    dst += *dst_len;
+    *dst_len += src_len;
+    *dst = '\0';
+    if (separator)
+       (void) strcat(dst, separator);
+    (void) strcat(dst, src);
+}
+
+/*
+ * Frees up space used by the aliases list and resets the associated counters.
+ */
+void
+reset_aliases()
+{
+    size_t n;
+
+    if (aliases) {
+       for (n = 0; n < naliases; n++)
+           free(aliases[n].name);
+       free(aliases);
+       aliases = NULL;
+    }
+    naliases = nslots = 0;
+}
+
+/*
+ * Increments ga_list_len, allocating more space as necessary.
+ */
+static void
+expand_ga_list()
+{
+
+    if (++ga_list_len >= ga_list_size) {
+       while ((ga_list_size += STACKINCREMENT) < ga_list_len)
+           ;
+       ga_list = (struct generic_alias *)
+           erealloc(ga_list, sizeof(struct generic_alias) * ga_list_size);
+    }
+
+    ga_list[ga_list_len - 1].entries = NULL;
+}
+
+/*
+ * Increments cm_list_len, allocating more space as necessary.
+ */
+static void
+expand_match_list()
+{
+
+    if (++cm_list_len >= cm_list_size) {
+       while ((cm_list_size += STACKINCREMENT) < cm_list_len)
+           ;
+       if (cm_list == NULL)
+           cm_list_len = 0;            /* start at 0 since it is a subscript */
+       cm_list = (struct command_match *)
+           erealloc(cm_list, sizeof(struct command_match) * cm_list_size);
+    }
+
+    cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
+    cm_list[cm_list_len].nopasswd = FALSE;
+}
+
+/*
+ * Frees up spaced used by a previous parser run and allocates new space
+ * for various data structures.
+ */
+void
+init_parser()
+{
+
+    /* Free up old data structures if we run the parser more than once. */
+    if (match) {
+       free(match);
+       match = NULL;
+       top = 0;
+       parse_error = FALSE;
+       errorlineno = -1;   
+       sudolineno = 1;     
+    }
+
+    /* Allocate space for the matching stack. */
+    stacksize = STACKINCREMENT;
+    match = (struct matchstack *) emalloc(sizeof(struct matchstack) * stacksize);
+
+    /* Allocate space for the match list (for `sudo -l'). */
+    if (printmatches == TRUE)
+       expand_match_list();
+}
diff --git a/pathnames.h.in b/pathnames.h.in
new file mode 100644 (file)
index 0000000..984a835
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2001
+ *     Todd C. Miller <Todd.Miller@courtesan.com>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: pathnames.h.in,v 1.45 2001/12/14 19:54:56 millert Exp $
+ */
+
+/*
+ *  Pathnames to programs and files used by sudo.
+ */
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif /* HAVE_PATHS_H */
+
+#ifndef _PATH_DEV
+#define _PATH_DEV              "/dev/"
+#endif /* _PATH_DEV */
+
+#ifndef _PATH_TTY
+#define _PATH_TTY              "/dev/tty"
+#endif /* _PATH_TTY */
+
+#ifndef _PATH_DEFPATH
+#define _PATH_DEFPATH          "/usr/bin:/bin"
+#endif /* _PATH_DEFPATH */
+
+/*
+ * NOTE: _PATH_SUDOERS is usually overriden by the Makefile.
+ */
+#ifndef _PATH_SUDOERS
+#define _PATH_SUDOERS          "/etc/sudoers"
+#endif /* _PATH_SUDOERS */
+
+/*
+ * NOTE:  _PATH_SUDOERS_TMP is usually overriden by the Makefile.
+ *        _PATH_SUDOERS_TMP *MUST* be on the same partition
+ *        as _PATH_SUDOERS!
+ */
+#ifndef _PATH_SUDOERS_TMP
+#define _PATH_SUDOERS_TMP      "/etc/sudoers.tmp"
+#endif /* _PATH_SUDOERS_TMP */
+
+/*
+ * The following paths are controlled via the configure script.
+ */
+
+/*
+ * Where to put the timestamp files.  Defaults to /var/run/sudo if
+ * /var/run exists, else /tmp/.odus.
+ */
+#ifndef _PATH_SUDO_TIMEDIR
+#undef _PATH_SUDO_TIMEDIR
+#endif /* _PATH_SUDO_TIMEDIR */
+
+/*
+ * Where to put the sudo log file when logging to a file.  Defaults to
+ * /var/log/sudo.log if /var/log exists, else /var/adm/sudo.log.
+ */
+#ifndef _PATH_SUDO_LOGFILE
+#undef _PATH_SUDO_LOGFILE
+#endif /* _PATH_SUDO_LOGFILE */
+
+#ifndef _PATH_SUDO_SENDMAIL
+#undef _PATH_SUDO_SENDMAIL
+#endif /* _PATH_SUDO_SENDMAIL */
+
+#ifndef _PATH_VI
+#undef _PATH_VI
+#endif /* _PATH_VI */
+
+#ifndef _PATH_MV
+#undef _PATH_MV
+#endif /* _PATH_MV */
+
+#ifndef _PATH_BSHELL
+#undef _PATH_BSHELL
+#endif /* _PATH_BSHELL */
diff --git a/sample.pam b/sample.pam
new file mode 100644 (file)
index 0000000..b2efeab
--- /dev/null
@@ -0,0 +1,8 @@
+#%PAM-1.0
+# Sample /etc/pam.d/sudo file for RedHat Linux 5.0 and above.
+# This is where you configure your authorization method. The uncommented
+# line below does 'normal' (/etc/passwd) authentication. The commented line
+# just above is what I use on my system, which allows my users to validate
+# against our Windows NT domain. - GJC
+#auth      required    /lib/security/pam_smb_auth.so
+auth       required    /lib/security/pam_pwdb.so shadow nullok
diff --git a/sample.sudoers b/sample.sudoers
new file mode 100644 (file)
index 0000000..f4b471a
--- /dev/null
@@ -0,0 +1,129 @@
+#
+# Sample /etc/sudoers file.
+#
+# This file MUST be edited with the 'visudo' command as root.
+#
+# See the sudoers man page for the details on how to write a sudoers file.
+#
+
+##
+# User alias specification
+##
+User_Alias     FULLTIMERS = millert, mikef, dowdy
+User_Alias     PARTTIMERS = bostley, jwfox, crawl
+User_Alias     WEBMASTERS = will, wendy, wim
+
+##
+# Runas alias specification
+##
+Runas_Alias    OP = root, operator
+Runas_Alias    DB = oracle, sybase
+
+##
+# Host alias specification
+##
+Host_Alias     SPARC = bigtime, eclipse, moet, anchor:\
+               SGI = grolsch, dandelion, black:\
+               ALPHA = widget, thalamus, foobar:\
+               HPPA = boa, nag, python
+Host_Alias     CUNETS = 128.138.0.0/255.255.0.0
+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
+
+##
+# 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
+Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+Cmnd_Alias     SHUTDOWN = /usr/sbin/shutdown
+Cmnd_Alias     HALT = /usr/sbin/halt, /usr/sbin/fasthalt
+Cmnd_Alias     REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
+Cmnd_Alias     SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
+                        /usr/local/bin/tcsh, /usr/bin/rsh, \
+                        /usr/local/bin/zsh
+Cmnd_Alias     SU = /usr/bin/su
+Cmnd_Alias     VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, \
+                      /usr/bin/chfn
+
+##
+# Override builtin defaults
+##
+Defaults               syslog=auth
+Defaults:FULLTIMERS    !lecture
+Defaults:millert       !authenticate
+Defaults@SERVERS       log_year, logfile=/var/log/sudo.log
+
+##
+# User specification
+##
+
+# root and users in group wheel can run anything on any machine as any user
+root           ALL = (ALL) ALL
+%wheel         ALL = (ALL) ALL
+
+# full time sysadmins can run anything on any machine without a password
+FULLTIMERS     ALL = NOPASSWD: ALL
+
+# part time sysadmins may run anything but need a password
+PARTTIMERS     ALL = ALL
+
+# jack may run anything on machines in CSNETS
+jack           CSNETS = ALL
+
+# lisa may run any command on any host in CUNETS (a class B network)
+lisa           CUNETS = ALL
+
+# operator may run maintenance commands and anything in /usr/oper/bin/
+operator       ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
+               /usr/oper/bin/
+
+# joe may su only to operator
+joe            ALL = /usr/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
+
+# bob may run anything on the sparc and sgi machines as any user
+# listed in the Runas_Alias "OP" (ie: root and operator)
+bob            SPARC = (OP) ALL : SGI = (OP) ALL
+
+# jim may run anything on machines in the biglab netgroup
+jim            +biglab = ALL
+
+# 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
+
+# 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*
+
+# jen can run anything on all machines except the ones
+# in the "SERVERS" Host_Alias
+jen            ALL, !SERVERS = ALL
+
+# jill can run any commands in the directory /usr/bin/, except for
+# those in the SU and SHELLS aliases.
+jill           SERVERS = /usr/bin/, !SU, !SHELLS
+
+# steve can run any command in the directory /usr/local/op_commands/
+# as user operator.
+steve          CSNETS = (operator) /usr/local/op_commands/
+
+# matt needs to be able to kill things on his workstation when
+# they get hung.
+matt           valkyrie = KILL
+
+# users in the WEBMASTERS User_Alias (will, wendy, and wim)
+# may run any command as user www (which owns the web pages)
+# or simply su to www.
+WEBMASTERS     www = (www) ALL, (root) /usr/bin/su www
+
+# anyone can mount/unmount a cd-rom on the machines in the CDROM alias
+ALL            CDROM = NOPASSWD: /sbin/umount /CDROM,\
+               /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
diff --git a/sample.syslog.conf b/sample.syslog.conf
new file mode 100644 (file)
index 0000000..2effbab
--- /dev/null
@@ -0,0 +1,25 @@
+# This is a sample syslog.conf fragment for use with Sudo.
+#
+# Sudo logs to local2 by default, but this is changable via the
+# --with-logfac configure option.  To see what syslog facility
+# a sudo binary uses, run `sudo -V' as *root*.  You may have
+# to check /usr/include/syslog.h to map the facility number to
+# a name.
+#
+# NOTES:
+#      The whitespace in the following line is made up of <TAB>
+#       characters, *not* spaces.  You cannot just cut and paste!
+#
+#      If you edit syslog.conf you need to send syslogd a HUP signal.
+#      Ie: kill -HUP process_id
+#
+#      Syslogd will not create new log files for you, you must first
+#      create the file before syslogd will log to it.  Eg.
+#      'touch /var/log/sudo'
+
+# This logs successful and failed sudo attempts to the file /var/log/sudo
+local2.debug                                   /var/log/sudo
+
+# To log to a remote machine, use something like the following,
+# where "loghost" is the name of the remote machine.
+local2.debug                                   @loghost
diff --git a/set_perms.c b/set_perms.c
new file mode 100644 (file)
index 0000000..300f5b3
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 1994-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <errno.h>
+#include <grp.h>
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+#endif
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: set_perms.c,v 1.12 2002/01/22 02:00:25 millert Exp $";
+#endif /* lint */
+
+/*
+ * Prototypes
+ */
+static void runas_setup                __P((void));
+static void fatal              __P((char *, int));
+
+#if !defined(NO_SAVED_IDS) && defined(_SC_SAVED_IDS) && defined(_SC_VERSION)
+/*
+ * Set real and effective uids and gids based on perm.
+ * Since we have POSIX saved IDs we can get away with just
+ * toggling the effective uid/gid unless we are headed for an exec().
+ */
+void
+set_perms_posix(perm, sudo_mode)
+    int perm;
+    int sudo_mode;
+{
+    int error;
+
+    switch (perm) {
+       case PERM_ROOT:
+                               if (seteuid(0))
+                                   fatal("seteuid(0) failed, your operating system may have broken POSIX saved ID support\nTry running configure with --disable-saved-ids", 0);
+                               break;
+
+       case PERM_FULL_ROOT:
+                               /* headed for exec() */
+                               (void) seteuid(0);
+                               if (setuid(0))
+                                   fatal("setuid(0)", 1);
+                               break;
+
+       case PERM_USER:
+                               (void) setegid(user_gid);
+                               if (seteuid(user_uid))
+                                   fatal("seteuid(user_uid)", 1);
+                               break;
+
+       case PERM_FULL_USER:
+                               /* headed for exec() */
+                               (void) setgid(user_gid);
+                               if (setuid(user_uid))
+                                   fatal("setuid(user_uid)", 1);
+                               break;
+                               
+       case PERM_RUNAS:
+                               /* headed for exec(), assume euid == 0 */
+                               runas_setup();
+                               if (def_flag(I_STAY_SETUID))
+                                   error = seteuid(runas_pw->pw_uid);
+                               else
+                                   error = setuid(runas_pw->pw_uid);
+                               if (error)
+                                   fatal("unable to change to runas uid", 1);
+                               break;
+
+       case PERM_SUDOERS:
+                               /* assume euid == 0, ruid == user */
+                               if (setegid(SUDOERS_GID))
+                                   fatal("unable to change to sudoers gid", 1);
+
+                               /*
+                                * If SUDOERS_UID == 0 and SUDOERS_MODE
+                                * is group readable we use a non-zero
+                                * uid in order to avoid NFS lossage.
+                                * Using uid 1 is a bit bogus but should
+                                * work on all OS's.
+                                */
+                               if (SUDOERS_UID == 0) {
+                                   if ((SUDOERS_MODE & 040) && seteuid(1))
+                                       fatal("seteuid(1)", 1);
+                               } else {
+                                   if (seteuid(SUDOERS_UID))
+                                       fatal("seteuid(SUDOERS_UID)", 1);
+                               }
+                               break;
+    }
+}
+#endif /* !NO_SAVED_IDS && _SC_SAVED_IDS && _SC_VERSION */
+
+#ifdef HAVE_SETREUID
+/*
+ * Set real and effective uids and gids based on perm.
+ * We always retain a real or effective uid of 0 unless
+ * we are headed for an exec().
+ */
+void
+set_perms_fallback(perm, sudo_mode)
+    int perm;
+    int sudo_mode;
+{
+    int error;
+
+    switch (perm) {
+       case PERM_FULL_ROOT:
+       case PERM_ROOT:
+                               if (setuid(0))
+                                   fatal("setuid(0) failed, your operating system may have broken POSIX saved ID support\nTry running configure with --disable-setreuid", 0);
+                               break;
+
+       case PERM_USER:
+                               (void) setegid(user_gid);
+                               if (setreuid(0, user_uid))
+                                   fatal("setreuid(0, user_uid)", 1);
+                               break;
+                               
+       case PERM_FULL_USER:
+                               /* headed for exec() */
+                               (void) setgid(user_gid);
+                               if (setuid(user_uid))
+                                   fatal("setuid(user_uid)", 1);
+                               break;
+                               
+       case PERM_RUNAS:
+                               /* headed for exec(), assume euid == 0 */
+                               runas_setup();
+                               if (def_flag(I_STAY_SETUID))
+                                   error = setreuid(user_uid, runas_pw->pw_uid);
+                               else
+                                   error = setuid(runas_pw->pw_uid);
+                               if (error)
+                                   fatal("unable to change to runas uid", 1);
+                               break;
+
+       case PERM_SUDOERS:
+                               /* assume euid == 0, ruid == user */
+                               if (setegid(SUDOERS_GID))
+                                   fatal("unable to change to sudoers gid", 1);
+
+                               /*
+                                * If SUDOERS_UID == 0 and SUDOERS_MODE
+                                * is group readable we use a non-zero
+                                * uid in order to avoid NFS lossage.
+                                * Using uid 1 is a bit bogus but should
+                                * work on all OS's.
+                                */
+                               if (SUDOERS_UID == 0) {
+                                   if ((SUDOERS_MODE & 040) && setreuid(0, 1))
+                                       fatal("setreuid(0, 1)", 1);
+                               } else {
+                                   if (setreuid(0, SUDOERS_UID))
+                                       fatal("setreuid(0, SUDOERS_UID)", 1);
+                               }
+                               break;
+    }
+}
+
+#else
+
+/*
+ * Set real and effective uids and gids based on perm.
+ * NOTE: does not support the "stay_setuid" option.
+ */
+void
+set_perms_fallback(perm, sudo_mode)
+    int perm;
+    int sudo_mode;
+{
+
+    /*
+     * Since we only have setuid() and seteuid() we have to set
+     * real and effective uidss to 0 initially.
+     */
+    if (setuid(0))
+       fatal("setuid(0)", 1);
+
+    switch (perm) {
+       case PERM_USER:
+                               (void) setegid(user_gid);
+                               if (seteuid(user_uid))
+                                   fatal("seteuid(user_uid)", 1);
+                               break;
+                               
+       case PERM_FULL_USER:
+                               /* headed for exec() */
+                               (void) setgid(user_gid);
+                               if (setuid(user_uid))
+                                   fatal("setuid(user_uid)", 1);
+                               break;
+                               
+       case PERM_RUNAS:
+                               /* headed for exec(), assume euid == 0 */
+                               runas_setup();
+                               if (setuid(runas_pw->pw_uid))
+                                   fatal("unable to change to runas uid", 1);
+                               break;
+
+       case PERM_SUDOERS:
+                               /* assume euid == 0, ruid == user */
+                               if (setegid(SUDOERS_GID))
+                                   fatal("unable to change to sudoers gid", 1);
+
+                               /*
+                                * If SUDOERS_UID == 0 and SUDOERS_MODE
+                                * is group readable we use a non-zero
+                                * uid in order to avoid NFS lossage.
+                                * Using uid 1 is a bit bogus but should
+                                * work on all OS's.
+                                */
+                               if (SUDOERS_UID == 0) {
+                                   if ((SUDOERS_MODE & 040) && seteuid(1))
+                                       fatal("seteuid(1)", 1);
+                               } else {
+                                   if (seteuid(SUDOERS_UID))
+                                       fatal("seteuid(SUDOERS_UID)", 1);
+                               }
+                               break;
+    }
+}
+#endif /* HAVE_SETREUID */
+
+static void
+runas_setup()
+{
+#ifdef HAVE_LOGIN_CAP_H
+    int error, flags;
+    extern login_cap_t *lc;
+#endif
+
+    if (runas_pw->pw_name != NULL) {
+#ifdef HAVE_PAM
+       pam_prep_user(runas_pw);
+#endif /* HAVE_PAM */
+
+#ifdef HAVE_LOGIN_CAP_H
+       if (def_flag(I_USE_LOGINCLASS)) {
+           /*
+             * We don't have setusercontext() set the user since we
+             * may only want to set the effective uid.  Depending on
+             * sudoers and/or command line arguments we may not want
+             * setusercontext() to call initgroups().
+            */
+           flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
+           if (!def_flag(I_PRESERVE_GROUPS))
+               flags |= LOGIN_SETGROUP;
+           else if (setgid(runas_pw->pw_gid))
+               perror("cannot set gid to runas gid");
+           error = setusercontext(lc, runas_pw,
+               runas_pw->pw_uid, flags);
+           if (error)
+               perror("unable to set user context");
+       } else
+#endif /* HAVE_LOGIN_CAP_H */
+       {
+           if (setgid(runas_pw->pw_gid))
+               perror("cannot set gid to runas gid");
+#ifdef HAVE_INITGROUPS
+           /*
+            * Initialize group vector unless asked not to.
+            */
+           if (!def_flag(I_PRESERVE_GROUPS) &&
+               initgroups(*user_runas, runas_pw->pw_gid) < 0)
+               perror("cannot set group vector");
+#endif /* HAVE_INITGROUPS */
+       }
+    }
+}
+
+static void
+fatal(str, printerr)
+    char *str;
+{
+
+    if (str) {
+       if (printerr)
+           perror(str);
+       else {
+           fputs(str, stderr);
+           fputc('\n', stderr);
+       }
+    }
+    exit(1);
+}
diff --git a/sigaction.c b/sigaction.c
new file mode 100644 (file)
index 0000000..41d1476
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <signal.h>
+#include <errno.h>
+
+#include <compat.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: sigaction.c,v 1.2 2001/12/08 19:36:48 millert Exp $";
+#endif /* lint */
+
+int
+sigaction(signo, sa, osa)
+    int signo;
+    const sigaction_t *sa;
+    sigaction_t *osa;
+{
+    sigaction_t nsa;
+    int error;
+
+    /* We must reverse SV_INTERRUPT since it is the opposite of SA_RESTART */
+    if (sa) {
+       nsa = *sa;
+       nsa.sa_flags ^= SV_INTERRUPT;
+       sa = &nsa;
+    }
+
+    error = sigvec(signo, sa, osa);
+    if (!error && osa)
+       osa->sa_flags ^= SV_INTERRUPT;          /* flip SV_INTERRUPT as above */
+
+    return(error);
+}
+
+int
+sigemptyset(set)
+    sigset_t *set;
+{
+
+    *set = 0;
+    return(0);
+}
+
+int
+sigfillset(set)
+    sigset_t *set;
+{
+
+    *set = ~0;;
+    return(0);
+}
+
+int
+sigaddset(set, signo)
+    sigset_t *set;
+    int signo;
+{
+
+    if (signo <= 0 || signo >= NSIG) {
+       errno = EINVAL;
+       return(-1);
+    }
+
+    *set |= sigmask(signo);
+    return(0);
+}
+
+int
+sigdelset(set, signo)
+    sigset_t *set;
+    int signo;
+{
+
+    if (signo <= 0 || signo >= NSIG) {
+       errno = EINVAL;
+       return(-1);
+    }
+
+    *set &= ~(sigmask(signo));
+    return(0);
+}
+
+int
+sigismember(set, signo)
+    sigset_t *set;
+    int signo;
+{
+
+    return(*set & sigmask(signo));
+}
+
+int
+sigprocmask(how, set, oset)
+    int how;
+    const sigset_t *set;
+    sigset_t *oset;
+{
+    int mask;
+
+    /* If 'set' is NULL the user just wants the current signal mask. */
+    if (set == 0)
+       mask = sigblock(0);
+    else
+       switch (how) {
+           case SIG_BLOCK:
+               mask = sigblock(*set);
+               break;
+           case SIG_UNBLOCK:
+               mask = sigsetmask(~*set);
+               break;
+           case SIG_SETMASK:
+               mask = sigsetmask(*set);
+               break;
+           default:
+               return(-1);
+       }
+
+    if (mask == -1)
+       return(-1);
+    if (oset)
+       *oset = mask;
+    return(0);
+}
diff --git a/snprintf.c b/snprintf.c
new file mode 100644 (file)
index 0000000..9acc488
--- /dev/null
@@ -0,0 +1,775 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From: @(#)vfprintf.c        8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * v?snprintf/v?asprintf based on 4.4BSD stdio.
+ * NOTE: does not support floating point.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <limits.h>
+
+#ifdef __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "compat.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: snprintf.c,v 1.14 2001/12/14 22:15:56 millert Exp $";
+#endif /* lint */
+
+static int xxxprintf    __P((char **, size_t, int, const char *, va_list));
+
+/*
+ * Some systems may not have these defined in <limits.h>
+ */
+#ifndef ULONG_MAX
+# define ULONG_MAX     ((unsigned long)-1)
+#endif
+#ifndef LONG_MAX
+# define LONG_MAX      (ULONG_MAX / 2)
+#endif
+#ifdef HAVE_LONG_LONG
+# ifndef UQUAD_MAX
+#  ifdef ULONG_LONG_MAX
+#   define UQUAD_MAX   ULONG_LONG_MAX
+#  else
+#   define UQUAD_MAX   ((unsigned long long)-1)
+#  endif
+# endif
+# ifndef QUAD_MAX
+#  ifdef LONG_LONG_MAX
+#   define QUAD_MAX    LONG_LONG_MAX
+#  else
+#   define QUAD_MAX    (UQUAD_MAX / 2)
+#  endif
+# endif
+#endif /* HAVE_LONG_LONG */
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define        to_digit(c)     ((c) - '0')
+#define is_digit(c)    ((unsigned int)to_digit(c) <= 9)
+#define        to_char(n)      ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define        ALT             0x001           /* alternate form */
+#define        HEXPREFIX       0x002           /* add 0x or 0X prefix */
+#define        LADJUST         0x004           /* left adjustment */
+#define        LONGDBL         0x008           /* long double; unimplemented */
+#define        LONGINT         0x010           /* long integer */
+#define        QUADINT         0x020           /* quad integer */
+#define        SHORTINT        0x040           /* short integer */
+#define        ZEROPAD         0x080           /* zero (as opposed to blank) pad */
+
+#define BUF            68
+
+#ifndef HAVE_MEMCHR
+VOID *
+memchr(s, c, n)
+       const VOID *s;
+       unsigned char c;
+       size_t n;
+{
+       if (n != 0) {
+               const unsigned char *p = s;
+
+               do {
+                       if (*p++ == c)
+                               return ((VOID *)(p - 1));
+               } while (--n != 0);
+       }
+       return (NULL);
+}
+#endif /* !HAVE_MEMCHR */
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static char *
+__ultoa(val, endp, base, octzero, xdigs)
+       unsigned long val;
+       char *endp;
+       int base, octzero;
+       char *xdigs;
+{
+       char *cp = endp;
+       long sval;
+
+       /*
+        * Handle the three cases separately, in the hope of getting
+        * better/faster code.
+        */
+       switch (base) {
+       case 10:
+               if (val < 10) { /* many numbers are 1 digit */
+                       *--cp = to_char(val);
+                       return (cp);
+               }
+               /*
+                * On many machines, unsigned arithmetic is harder than
+                * signed arithmetic, so we do at most one unsigned mod and
+                * divide; this is sufficient to reduce the range of
+                * the incoming value to where signed arithmetic works.
+                */
+               if (val > LONG_MAX) {
+                       *--cp = to_char(val % 10);
+                       sval = val / 10;
+               } else
+                       sval = val;
+               do {
+                       *--cp = to_char(sval % 10);
+                       sval /= 10;
+               } while (sval != 0);
+               break;
+
+       case 8:
+               do {
+                       *--cp = to_char(val & 7);
+                       val >>= 3;
+               } while (val);
+               if (octzero && *cp != '0')
+                       *--cp = '0';
+               break;
+
+       case 16:
+               do {
+                       *--cp = xdigs[val & 15];
+                       val >>= 4;
+               } while (val);
+               break;
+
+       default:                        /* oops */
+               abort();
+       }
+       return (cp);
+}
+
+/* Identical to __ultoa, but for quads. */
+#ifdef HAVE_LONG_LONG
+# ifdef LONG_IS_QUAD
+#  define __uqtoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x))
+# else
+static char *
+__uqtoa(val, endp, base, octzero, xdigs)
+       unsigned long long val;
+       char *endp;
+       int base, octzero;
+       char *xdigs;
+{
+       char *cp = endp;
+       long long sval;
+
+       /* quick test for small values; __ultoa is typically much faster */
+       /* (perhaps instead we should run until small, then call __ultoa?) */
+       if (val <= (unsigned long long)ULONG_MAX)
+               return (__ultoa((unsigned long)val, endp, base, octzero, xdigs));
+       switch (base) {
+       case 10:
+               if (val < 10) {
+                       *--cp = to_char(val % 10);
+                       return (cp);
+               }
+               if (val > QUAD_MAX) {
+                       *--cp = to_char(val % 10);
+                       sval = val / 10;
+               } else
+                       sval = val;
+               do {
+                       *--cp = to_char(sval % 10);
+                       sval /= 10;
+               } while (sval != 0);
+               break;
+
+       case 8:
+               do {
+                       *--cp = to_char(val & 7);
+                       val >>= 3;
+               } while (val);
+               if (octzero && *cp != '0')
+                       *--cp = '0';
+               break;
+
+       case 16:
+               do {
+                       *--cp = xdigs[val & 15];
+                       val >>= 4;
+               } while (val);
+               break;
+
+       default:                        /* oops */
+               abort();
+       }
+       return (cp);
+}
+# endif /* !LONG_IS_QUAD */
+#endif /* HAVE_LONG_LONG */
+
+/*
+ * Actual printf innards.
+ */
+static int
+xxxprintf(strp, strsize, alloc, fmt0, ap)
+       char **strp;
+       size_t strsize;
+       int alloc;
+       const char *fmt0;
+       va_list ap;
+{
+       char *fmt;              /* format string */
+       int ch;                 /* character from fmt */
+       int n;                  /* handy integer (short term usage) */
+       char *cp;               /* handy char pointer (short term usage) */
+       int flags;              /* flags as above */
+       int ret;                /* return value accumulator */
+       int width;              /* width from format (%8d), or 0 */
+       int prec;               /* precision from format (%.3d), or -1 */
+       char sign;              /* sign prefix (' ', '+', '-', or \0) */
+       unsigned long ulval;    /* integer arguments %[diouxX] */
+#ifdef HAVE_LONG_LONG
+       unsigned long long uqval; /* %q (quad) integers */
+#endif
+       int base;               /* base for [diouxX] conversion */
+       int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
+       int fieldsz;            /* field size expanded by sign, etc */
+       int realsz;             /* field size expanded by dprec */
+       int size;               /* size of converted field or string */
+       char *xdigs;            /* digits for [xX] conversion */
+       char buf[BUF];          /* space for %c, %[diouxX], %[eEfgG] */
+       char ox[2];             /* space for 0x hex-prefix */
+       char *str;              /* pointer to string to fill */
+       char *estr;             /* pointer to last char in str */
+
+       /*
+        * Choose PADSIZE to trade efficiency vs. size.  If larger printf
+        * fields occur frequently, increase PADSIZE and make the initialisers
+        * below longer.
+        */
+#define        PADSIZE 16              /* pad chunk size */
+       static char blanks[PADSIZE] =
+        {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+       static char zeroes[PADSIZE] =
+        {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+       /* Print chars to "str", (allocate as needed if alloc is set). */
+#define        PRINT(ptr, len) do { \
+       const char *p = ptr; \
+       const char *endp = ptr + len; \
+       while (p < endp && (str < estr || alloc)) { \
+               if (alloc && str >= estr) { \
+                       char *t; \
+                       strsize = (strsize << 1) + 1; \
+                       if (!(t = (char *)realloc(*strp, strsize))) { \
+                               free(str); \
+                               *strp = NULL; \
+                               ret = -1; \
+                               goto done; \
+                       } \
+                       str = t + (str - *strp); \
+                       estr = t + strsize - 1; \
+                       *strp = t; \
+               } \
+               *str++ = *p++; \
+       } \
+} while (0)
+
+       /* BEWARE, PAD uses `n'. */
+#define        PAD(howmany, with) do { \
+       if ((n = (howmany)) > 0) { \
+               while (n > PADSIZE) { \
+                       PRINT(with, PADSIZE); \
+                       n -= PADSIZE; \
+               } \
+               PRINT(with, n); \
+       } \
+} while (0)
+
+       /*
+        * To extend shorts properly, we need both signed and unsigned
+        * argument extraction methods.
+        */
+#define        SARG() \
+       (flags&LONGINT ? va_arg(ap, long) : \
+           flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+           (long)va_arg(ap, int))
+#define        UARG() \
+       (flags&LONGINT ? va_arg(ap, unsigned long) : \
+           flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
+           (unsigned long)va_arg(ap, unsigned int))
+
+       fmt = (char *)fmt0;
+       ret = 0;
+
+       if (alloc) {
+               strsize = 128;
+               *strp = str = (char *)malloc(strsize);
+               if (str == NULL) {
+                       ret = -1;
+                       goto done;
+               }
+               estr = str + 127;
+       } else {
+               str = *strp;
+               if (strsize)
+                       estr = str + strsize - 1;
+               else
+                       estr = NULL;
+       }
+
+       /*
+        * Scan the format for conversions (`%' character).
+        */
+       for (;;) {
+               for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+                       /* void */;
+               if ((n = fmt - cp) != 0) {
+                       PRINT(cp, n);
+                       ret += n;
+               }
+               if (ch == '\0')
+                       goto done;
+               fmt++;          /* skip over '%' */
+
+               flags = 0;
+               dprec = 0;
+               width = 0;
+               prec = -1;
+               sign = '\0';
+
+rflag:         ch = *fmt++;
+reswitch:      switch (ch) {
+               case ' ':
+                       /*
+                        * ``If the space and + flags both appear, the space
+                        * flag will be ignored.''
+                        *      -- ANSI X3J11
+                        */
+                       if (!sign)
+                               sign = ' ';
+                       goto rflag;
+               case '#':
+                       flags |= ALT;
+                       goto rflag;
+               case '*':
+                       /*
+                        * ``A negative field width argument is taken as a
+                        * - flag followed by a positive field width.''
+                        *      -- ANSI X3J11
+                        * They don't exclude field widths read from args.
+                        */
+                       if ((width = va_arg(ap, int)) >= 0)
+                               goto rflag;
+                       width = -width;
+                       /* FALLTHROUGH */
+               case '-':
+                       flags |= LADJUST;
+                       goto rflag;
+               case '+':
+                       sign = '+';
+                       goto rflag;
+               case '.':
+                       if ((ch = *fmt++) == '*') {
+                               n = va_arg(ap, int);
+                               prec = n < 0 ? -1 : n;
+                               goto rflag;
+                       }
+                       n = 0;
+                       while (is_digit(ch)) {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       }
+                       prec = n < 0 ? -1 : n;
+                       goto reswitch;
+               case '0':
+                       /*
+                        * ``Note that 0 is taken as a flag, not as the
+                        * beginning of a field width.''
+                        *      -- ANSI X3J11
+                        */
+                       flags |= ZEROPAD;
+                       goto rflag;
+               case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       n = 0;
+                       do {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       } while (is_digit(ch));
+                       width = n;
+                       goto reswitch;
+               case 'h':
+                       flags |= SHORTINT;
+                       goto rflag;
+               case 'l':
+                       flags |= LONGINT;
+                       goto rflag;
+#ifdef HAVE_LONG_LONG
+               case 'q':
+                       flags |= QUADINT;
+                       goto rflag;
+#endif /* HAVE_LONG_LONG */
+               case 'c':
+                       *(cp = buf) = va_arg(ap, int);
+                       size = 1;
+                       sign = '\0';
+                       break;
+               case 'D':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'd':
+               case 'i':
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT) {
+                               uqval = va_arg(ap, long long);
+                               if ((long long)uqval < 0) {
+                                       uqval = -uqval;
+                                       sign = '-';
+                               }
+                       }
+                       else
+#endif /* HAVE_LONG_LONG */
+                       {
+                               ulval = SARG();
+                               if ((long)ulval < 0) {
+                                       ulval = -ulval;
+                                       sign = '-';
+                               }
+                       }
+                       base = 10;
+                       goto number;
+               case 'n':
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT)
+                               *va_arg(ap, long long *) = ret;
+                       else
+#endif /* HAVE_LONG_LONG */
+                       if (flags & LONGINT)
+                               *va_arg(ap, long *) = ret;
+                       else if (flags & SHORTINT)
+                               *va_arg(ap, short *) = ret;
+                       else
+                               *va_arg(ap, int *) = ret;
+                       continue;       /* no output */
+               case 'O':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'o':
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT)
+                               uqval = va_arg(ap, unsigned long long);
+                       else
+#endif /* HAVE_LONG_LONG */
+                               ulval = UARG();
+                       base = 8;
+                       goto nosign;
+               case 'p':
+                       /*
+                        * ``The argument shall be a pointer to void.  The
+                        * value of the pointer is converted to a sequence
+                        * of printable characters, in an implementation-
+                        * defined manner.''
+                        *      -- ANSI X3J11
+                        */
+                       ulval = (unsigned long)va_arg(ap, VOID *);
+                       base = 16;
+                       xdigs = "0123456789abcdef";
+                       flags = (flags & ~QUADINT) | HEXPREFIX;
+                       ch = 'x';
+                       goto nosign;
+               case 's':
+                       if ((cp = va_arg(ap, char *)) == NULL)
+                               cp = "(null)";
+                       if (prec >= 0) {
+                               /*
+                                * can't use strlen; can only look for the
+                                * NUL in the first `prec' characters, and
+                                * strlen() will go further.
+                                */
+                               char *p = memchr(cp, 0, prec);
+
+                               if (p != NULL) {
+                                       size = p - cp;
+                                       if (size > prec)
+                                               size = prec;
+                               } else
+                                       size = prec;
+                       } else
+                               size = strlen(cp);
+                       sign = '\0';
+                       break;
+               case 'U':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'u':
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT)
+                               uqval = va_arg(ap, unsigned long long);
+                       else
+#endif /* HAVE_LONG_LONG */
+                               ulval = UARG();
+                       base = 10;
+                       goto nosign;
+               case 'X':
+                       xdigs = "0123456789ABCDEF";
+                       goto hex;
+               case 'x':
+                       xdigs = "0123456789abcdef";
+hex:
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT)
+                               uqval = va_arg(ap, unsigned long long);
+                       else
+#endif /* HAVE_LONG_LONG */
+                               ulval = UARG();
+                       base = 16;
+                       /* leading 0x/X only if non-zero */
+                       if (flags & ALT &&
+#ifdef HAVE_LONG_LONG
+                           (flags & QUADINT ? uqval != 0 : ulval != 0))
+#else
+                           ulval != 0)
+#endif /* HAVE_LONG_LONG */
+                               flags |= HEXPREFIX;
+
+                       /* unsigned conversions */
+nosign:                        sign = '\0';
+                       /*
+                        * ``... diouXx conversions ... if a precision is
+                        * specified, the 0 flag will be ignored.''
+                        *      -- ANSI X3J11
+                        */
+number:                        if ((dprec = prec) >= 0)
+                               flags &= ~ZEROPAD;
+
+                       /*
+                        * ``The result of converting a zero value with an
+                        * explicit precision of zero is no characters.''
+                        *      -- ANSI X3J11
+                        */
+                       cp = buf + BUF;
+#ifdef HAVE_LONG_LONG
+                       if (flags & QUADINT) {
+                               if (uqval != 0 || prec != 0)
+                                       cp = __uqtoa(uqval, cp, base,
+                                           flags & ALT, xdigs);
+                       }
+                       else
+#endif /* HAVE_LONG_LONG */
+                       {
+                               if (ulval != 0 || prec != 0)
+                                       cp = __ultoa(ulval, cp, base,
+                                           flags & ALT, xdigs);
+                       }
+                       size = buf + BUF - cp;
+                       break;
+               default:        /* "%?" prints ?, unless ? is NUL */
+                       if (ch == '\0')
+                               goto done;
+                       /* pretend it was %c with argument ch */
+                       cp = buf;
+                       *cp = ch;
+                       size = 1;
+                       sign = '\0';
+                       break;
+               }
+
+               /*
+                * All reasonable formats wind up here.  At this point, `cp'
+                * points to a string which (if not flags&LADJUST) should be
+                * padded out to `width' places.  If flags&ZEROPAD, it should
+                * first be prefixed by any sign or other prefix; otherwise,
+                * it should be blank padded before the prefix is emitted.
+                * After any left-hand padding and prefixing, emit zeroes
+                * required by a decimal [diouxX] precision, then print the
+                * string proper, then emit zeroes required by any leftover
+                * floating precision; finally, if LADJUST, pad with blanks.
+                *
+                * Compute actual size, so we know how much to pad.
+                * fieldsz excludes decimal prec; realsz includes it.
+                */
+               fieldsz = size;
+               if (sign)
+                       fieldsz++;
+               else if (flags & HEXPREFIX)
+                       fieldsz += 2;
+               realsz = dprec > fieldsz ? dprec : fieldsz;
+
+               /* right-adjusting blank padding */
+               if ((flags & (LADJUST|ZEROPAD)) == 0)
+                       PAD(width - realsz, blanks);
+
+               /* prefix */
+               if (sign) {
+                       PRINT(&sign, 1);
+               } else if (flags & HEXPREFIX) {
+                       ox[0] = '0';
+                       ox[1] = ch;
+                       PRINT(ox, 2);
+               }
+
+               /* right-adjusting zero padding */
+               if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+                       PAD(width - realsz, zeroes);
+
+               /* leading zeroes from decimal precision */
+               PAD(dprec - fieldsz, zeroes);
+
+               /* the string or number proper */
+               PRINT(cp, size);
+
+               /* left-adjusting padding (always blank) */
+               if (flags & LADJUST)
+                       PAD(width - realsz, blanks);
+
+               /* finally, adjust ret */
+               ret += width > realsz ? width : realsz;
+       }
+done:
+       if (strsize)
+               *str = '\0';
+       return (ret);
+       /* NOTREACHED */
+}
+
+#ifndef HAVE_VSNPRINTF
+int
+vsnprintf(str, n, fmt, ap)
+       char *str;
+       size_t n;
+       const char *fmt;
+       va_list ap;
+{
+
+       return (xxxprintf(&str, n, 0, fmt, ap));
+}
+#endif /* HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+int
+#ifdef __STDC__
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+       char *str;
+       size_t n;
+       char const *fmt;
+       va_dcl
+#endif
+{
+       int ret;
+       va_list ap;
+
+#ifdef __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       ret = xxxprintf(&str, n, 0, fmt, ap);
+       va_end(ap);
+       return (ret);
+}
+#endif /* HAVE_SNPRINTF */
+
+#ifndef HAVE_VASPRINTF
+int
+vasprintf(str, fmt, ap)
+       char **str;
+       const char *fmt;
+       va_list ap;
+{
+
+       return (xxxprintf(str, 0, 1, fmt, ap));
+}
+#endif /* HAVE_VASPRINTF */
+
+#ifndef HAVE_ASPRINTF
+int
+#ifdef __STDC__
+asprintf(char **str, char const *fmt, ...)
+#else
+asprintf(str, fmt, va_alist)
+       char **str;
+       char const *fmt;
+       va_dcl
+#endif
+{
+       int ret;
+       va_list ap;
+
+#ifdef __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       ret = xxxprintf(str, 0, 1, fmt, ap);
+       va_end(ap);
+       return (ret);
+}
+#endif /* HAVE_ASPRINTF */
diff --git a/strcasecmp.c b/strcasecmp.c
new file mode 100644 (file)
index 0000000..f0a4b3c
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1987, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)strcasecmp.c    8.1 (Berkeley) 6/4/93
+ */
+
+#include "config.h"
+#include <sys/types.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: strcasecmp.c,v 1.3 1999/11/05 17:00:00 millert Exp $";
+#endif /* lint */
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison.  The mappings are
+ * based upon ascii character sequences.
+ */
+static const unsigned char charmap[] = {
+       '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+       '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+       '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+       '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+       '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+       '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+       '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+       '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+       '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+       '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+       '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+       '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+       '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+       '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+       '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+       '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+       '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+       '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+       '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+       '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+       '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+       '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+       '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+       '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+       '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+       '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+       '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+       '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strcasecmp(s1, s2)
+       const char *s1, *s2;
+{
+       const unsigned char *cm = charmap,
+                           *us1 = (const unsigned char *)s1,
+                           *us2 = (const unsigned char *)s2;
+
+       while (cm[*us1] == cm[*us2++])
+               if (*us1++ == '\0')
+                       return (0);
+       return (cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+       const char *s1, *s2;
+       size_t n;
+{
+
+       if (n != 0) {
+               const unsigned char *cm = charmap,
+                                   *us1 = (const unsigned char *)s1,
+                                   *us2 = (const unsigned char *)s2;
+
+               do {
+                       if (cm[*us1] != cm[*us2++])
+                               return (cm[*us1] - cm[*--us2]);
+                       if (*us1++ == '\0')
+                               break;
+               } while (--n != 0);
+       }
+       return (0);
+}
diff --git a/strerror.c b/strerror.c
new file mode 100644 (file)
index 0000000..0a06e33
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: strerror.c,v 1.5 2001/12/14 19:56:48 millert Exp $";
+#endif /* lint */
+
+/*
+ * Map errno -> error string.
+ */
+char *
+strerror(n)
+    int n;
+{
+    extern int sys_nerr;
+    extern char *sys_errlist[];
+
+    if (n > 0 && n < sys_nerr)
+       return(sys_errlist[n]);
+    errno = EINVAL;
+    return("Unknown error");
+}
diff --git a/sudo.c b/sudo.c
new file mode 100644 (file)
index 0000000..7c6f532
--- /dev/null
+++ b/sudo.c
@@ -0,0 +1,1035 @@
+/*
+ * Copyright (c) 1993-1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * For a brief history of sudo, please see the HISTORY file included
+ * with this distribution.
+ */
+
+#define _SUDO_SUDO_C
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifdef HAVE_SETRLIMIT
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <grp.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS)
+# ifdef __hpux
+#  undef MAXINT
+#  include <hpsecurity.h>
+# else
+#  include <sys/security.h>
+# endif /* __hpux */
+# include <prot.h>
+#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+# ifndef LOGIN_DEFROOTCLASS
+#  define LOGIN_DEFROOTCLASS   "daemon"
+# endif
+#endif
+
+#include "sudo.h"
+#include "interfaces.h"
+#include "version.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: sudo.c,v 1.318 2002/01/15 23:43:59 millert Exp $";
+#endif /* lint */
+
+/*
+ * Prototypes
+ */
+static int init_vars                   __P((int));
+static int parse_args                  __P((void));
+static void check_sudoers              __P((void));
+static void initial_setup              __P((void));
+static void set_loginclass             __P((struct passwd *));
+static void usage                      __P((int));
+static void usage_excl                 __P((int));
+static struct passwd *get_authpw       __P((void));
+extern void list_matches               __P((void));
+extern char **rebuild_env              __P((int, char **));
+extern char **zero_env                 __P((char **));
+extern struct passwd *sudo_getpwnam    __P((const char *));
+extern struct passwd *sudo_getpwuid    __P((uid_t));
+
+/*
+ * Globals
+ */
+int Argc;
+char **Argv;
+int NewArgc = 0;
+char **NewArgv = NULL;
+struct sudo_user sudo_user;
+struct passwd *auth_pw;
+FILE *sudoers_fp = NULL;
+struct interface *interfaces;
+int num_interfaces;
+int tgetpass_flags;
+extern int errorlineno;
+#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+static struct rlimit corelimit;
+#endif /* RLIMIT_CORE */
+#ifdef HAVE_LOGIN_CAP_H
+login_cap_t *lc;
+#endif /* HAVE_LOGIN_CAP_H */
+#ifdef HAVE_BSD_AUTH_H
+char *login_style;
+#endif /* HAVE_BSD_AUTH_H */
+void (*set_perms) __P((int, int));
+
+
+int
+main(argc, argv, envp)
+    int argc;
+    char **argv;
+    char **envp;
+{
+    int validated;
+    int fd;
+    int cmnd_status;
+    int sudo_mode;
+    int pwflag;
+    char **new_environ;
+    sigaction_t sa;
+    extern int printmatches;
+    extern char **environ;
+
+    /* Must be done as the first thing... */
+#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS)
+    (void) set_auth_parameters(argc, argv);
+# ifdef HAVE_INITPRIVS
+    initprivs();
+# endif
+#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
+
+    /* Zero out the environment. */
+    environ = zero_env(envp);
+
+    Argv = argv;
+    Argc = argc;
+
+    if (geteuid() != 0) {
+       (void) fprintf(stderr, "Sorry, %s must be setuid root.\n", Argv[0]);
+       exit(1);
+    }
+
+    /*
+     * Ignore keyboard-generated signals so the user cannot interrupt
+     * us at some point and avoid the logging.
+     */
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = SIG_IGN;
+    (void) sigaction(SIGINT, &sa, NULL);
+    (void) sigaction(SIGQUIT, &sa, NULL);
+    (void) sigaction(SIGTSTP, &sa, NULL);
+
+    /*
+     * Setup signal handlers, turn off core dumps, and close open files.
+     */
+    initial_setup();
+    setpwent();
+
+    /* Parse our arguments. */
+    sudo_mode = parse_args();
+
+    /* Setup defaults data structures. */
+    init_defaults();
+
+    /* Load the list of local ip addresses and netmasks.  */
+    load_interfaces();
+
+    pwflag = 0;
+    if (sudo_mode & MODE_SHELL)
+       user_cmnd = "shell";
+    else
+       switch (sudo_mode) {
+           case MODE_VERSION:
+               (void) printf("Sudo version %s\n", version);
+               if (getuid() == 0) {
+                   putchar('\n');
+                   dump_auth_methods();
+                   dump_defaults();
+                   dump_interfaces();
+                   dump_badenv();
+               }
+               exit(0);
+               break;
+           case MODE_HELP:
+               usage(0);
+               break;
+           case MODE_VALIDATE:
+               user_cmnd = "validate";
+               pwflag = I_VERIFYPW_I;
+               break;
+           case MODE_KILL:
+           case MODE_INVALIDATE:
+               user_cmnd = "kill";
+               pwflag = -1;
+               break;
+           case MODE_LISTDEFS:
+               list_options();
+               exit(0);
+               break;
+           case MODE_LIST:
+               user_cmnd = "list";
+               pwflag = I_LISTPW_I;
+               printmatches = 1;
+               break;
+       }
+
+    /* Must have a command to run... */
+    if (user_cmnd == NULL && NewArgc == 0)
+       usage(1);
+
+    cmnd_status = init_vars(sudo_mode);
+
+    check_sudoers();   /* check mode/owner on _PATH_SUDOERS */
+
+    /* Validate the user but don't search for pseudo-commands. */
+    validated = sudoers_lookup(pwflag);
+
+    /*
+     * If we have POSIX saved uids and the stay_setuid flag was not set,
+     * set the real, effective and saved uids to 0 and use set_perms_fallback()
+     * instead of set_perms_posix().
+     */
+#if !defined(NO_SAVED_IDS) && defined(_SC_SAVED_IDS) && defined(_SC_VERSION)
+    if (!def_flag(I_STAY_SETUID) && set_perms == set_perms_posix) {
+       if (setuid(0)) {
+           perror("setuid(0)");
+           exit(1);
+       }
+       set_perms = set_perms_fallback;
+    }
+#endif
+
+    /*
+     * Look up runas user passwd struct.  If we are given a uid then
+     * there may be no corresponding passwd(5) entry (which is OK).
+     */
+    if (**user_runas == '#') {
+       runas_pw = sudo_getpwuid(atoi(*user_runas + 1));
+       if (runas_pw == NULL) {
+           runas_pw = emalloc(sizeof(struct passwd));
+           (void) memset((VOID *)runas_pw, 0, sizeof(struct passwd));
+           runas_pw->pw_uid = atoi(*user_runas + 1);
+       }
+    } else {
+       runas_pw = sudo_getpwnam(*user_runas);
+       if (runas_pw == NULL)
+           log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
+    }
+
+    /* 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 (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_flag(I_ROOT_SUDO)) {
+       (void) fputs("You are already root, you don't need to use sudo.\n",
+           stderr);
+       exit(1);
+    }
+
+    /* If given the -P option, set the "preserve_groups" flag. */
+    if (sudo_mode & MODE_PRESERVE_GROUPS)
+       def_flag(I_PRESERVE_GROUPS) = TRUE;
+
+    /* If no command line args and "set_home" is not set, error out. */
+    if ((sudo_mode & MODE_IMPLIED_SHELL) && !def_flag(I_SHELL_NOARGS))
+       usage(1);
+
+    /* May need to set $HOME to target user if we are running a command. */
+    if ((sudo_mode & MODE_RUN) && (def_flag(I_ALWAYS_SET_HOME) ||
+       ((sudo_mode & MODE_SHELL) && def_flag(I_SET_HOME))))
+       sudo_mode |= MODE_RESET_HOME;
+
+    /* Bail if a tty is required and we don't have one.  */
+    if (def_flag(I_REQUIRETTY)) {
+       if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1)
+           log_error(NO_MAIL, "sorry, you must have a tty to run sudo");
+       else
+           (void) close(fd);
+    }
+
+    /* Fill in passwd struct based on user we are authenticating as.  */
+    auth_pw = get_authpw();
+
+    /* Require a password unless the NOPASS tag was set.  */
+    if (!(validated & FLAG_NOPASS))
+       check_user();
+
+    /* Build up custom environment that avoids any nasty bits. */
+    new_environ = rebuild_env(sudo_mode, envp);
+
+    if (validated & VALIDATE_OK) {
+       /* Finally tell the user if the command did not exist. */
+       if (cmnd_status == NOT_FOUND_DOT) {
+           (void) fprintf(stderr, "%s: ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.\n", Argv[0], user_cmnd, user_cmnd, user_cmnd);
+           exit(1);
+       } else if (cmnd_status == NOT_FOUND) {
+           (void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
+               user_cmnd);
+           exit(1);
+       }
+
+       log_auth(validated, 1);
+       if (sudo_mode == MODE_VALIDATE)
+           exit(0);
+       else if (sudo_mode == MODE_LIST) {
+           list_matches();
+           exit(0);
+       }
+
+       /* This *must* have been set if we got a match but... */
+       if (safe_cmnd == NULL) {
+           log_error(MSG_ONLY,
+               "internal error, safe_cmnd never got set for %s; %s",
+               user_cmnd,
+               "please report this error at http://courtesan.com/sudo/bugs/");
+       }
+
+       /* Reset signal handlers before we exec. */
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_RESTART;
+       sa.sa_handler = SIG_DFL;
+       (void) sigaction(SIGINT, &sa, NULL);
+       (void) sigaction(SIGQUIT, &sa, NULL);
+       (void) sigaction(SIGTSTP, &sa, NULL);
+
+       /* Override user's umask if configured to do so. */
+       if (def_ival(I_UMASK) != 0777)
+           (void) umask(def_mode(I_UMASK));
+
+       /* Restore coredumpsize resource limit. */
+#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+       (void) setrlimit(RLIMIT_CORE, &corelimit);
+#endif /* RLIMIT_CORE */
+
+       /* Become specified user or root. */
+       set_perms(PERM_RUNAS, sudo_mode);
+
+       /* Close the password and group files */
+       endpwent();
+       endgrent();
+
+       /* Install the new environment. */
+       environ = new_environ;
+
+#ifndef PROFILING
+       if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
+           exit(0);
+       else
+           EXEC(safe_cmnd, NewArgv);   /* run the command */
+#else
+       exit(0);
+#endif /* PROFILING */
+       /*
+        * If we got here then the exec() failed...
+        */
+       (void) fprintf(stderr, "%s: unable to exec %s: %s\n",
+           Argv[0], safe_cmnd, strerror(errno));
+       exit(127);
+    } else if ((validated & FLAG_NO_USER) || (validated & FLAG_NO_HOST)) {
+       log_auth(validated, 1);
+       exit(1);
+    } else if (validated & VALIDATE_NOT_OK) {
+       if (def_flag(I_PATH_INFO)) {
+           /*
+            * We'd like to not leak path info at all here, but that can
+            * *really* confuse the users.  To really close the leak we'd
+            * have to say "not allowed to run foo" even when the problem
+            * is just "no foo in path" since the user can trivially set
+            * their path to just contain a single dir.
+            */
+           log_auth(validated,
+               !(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND));
+           if (cmnd_status == NOT_FOUND)
+               (void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
+                   user_cmnd);
+           else if (cmnd_status == NOT_FOUND_DOT)
+               (void) fprintf(stderr, "%s: ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.\n", Argv[0], user_cmnd, user_cmnd, user_cmnd);
+       } else {
+           /* Just tell the user they are not allowed to run foo. */
+           log_auth(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
+init_vars(sudo_mode)
+    int sudo_mode;
+{
+    char *p, thost[MAXHOSTNAMELEN];
+    int nohostname, rval;
+
+    /* Sanity check command from user. */
+    if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) {
+       (void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0],
+           NewArgv[0]);
+       exit(1);
+    }
+
+#ifdef HAVE_TZSET
+    (void) tzset();            /* set the timezone if applicable */
+#endif /* HAVE_TZSET */
+
+    /* Default value for cmnd and cwd, overridden later. */
+    if (user_cmnd == NULL)
+       user_cmnd = NewArgv[0];
+    (void) strcpy(user_cwd, "unknown");
+
+    /*
+     * We avoid gethostbyname() if possible since we don't want
+     * sudo to block if DNS or NIS is hosed.
+     * "host" is the (possibly fully-qualified) hostname and
+     * "shost" is the unqualified form of the hostname.
+     */
+    nohostname = gethostname(thost, sizeof(thost));
+    if (nohostname)
+       user_host = user_shost = "localhost";
+    else {
+       user_host = estrdup(thost);
+       if (def_flag(I_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;
+           }
+       }
+    }
+
+    if ((p = ttyname(STDIN_FILENO)) || (p = ttyname(STDOUT_FILENO))) {
+       if (strncmp(p, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+           p += sizeof(_PATH_DEV) - 1;
+       user_tty = estrdup(p);
+    } else
+       user_tty = "unknown";
+
+    /*
+     * Get a local copy of the user's struct passwd with the shadow password
+     * if necessary.  It is assumed that euid is 0 at this point so we
+     * can read the shadow passwd file if necessary.
+     */
+    if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL) {
+       /* Need to make a fake struct passwd for logging to work. */
+       struct passwd pw;
+       char pw_name[MAX_UID_T_LEN + 1];
+
+       pw.pw_uid = getuid();
+       (void) sprintf(pw_name, "%ld", (long) pw.pw_uid);
+       pw.pw_name = pw_name;
+       sudo_user.pw = &pw;
+
+       log_error(0, "uid %ld does not exist in the passwd file!",
+           (long) pw.pw_uid);
+    }
+    if (user_shell == NULL || *user_shell == '\0')
+       user_shell = sudo_user.pw->pw_shell;
+
+    /* It is now safe to use log_error() and set_perms() */
+
+    /*
+     * Must defer set_fqdn() until it is safe to call log_error()
+     */
+    if (def_flag(I_FQDN))
+       set_fqdn();
+
+    if (nohostname)
+       log_error(USE_ERRNO|MSG_ONLY, "can't get hostname");
+
+    /*
+     * Get current working directory.  Try as user, fall back to root.
+     */
+    set_perms(PERM_USER, sudo_mode);
+    if (!getcwd(user_cwd, sizeof(user_cwd))) {
+       set_perms(PERM_ROOT, sudo_mode);
+       if (!getcwd(user_cwd, sizeof(user_cwd))) {
+           (void) fprintf(stderr, "%s: Can't get working directory!\n",
+                          Argv[0]);
+           (void) strcpy(user_cwd, "unknown");
+       }
+    } else
+       set_perms(PERM_ROOT, sudo_mode);
+
+    /*
+     * If we were given the '-s' option (run shell) we need to redo
+     * NewArgv and NewArgc.
+     */
+    if ((sudo_mode & MODE_SHELL)) {
+       char **dst, **src = NewArgv;
+
+       NewArgv = (char **) emalloc (sizeof(char *) * (++NewArgc + 1));
+       if (user_shell && *user_shell) {
+           NewArgv[0] = user_shell;
+       } else {
+           (void) fprintf(stderr, "%s: Unable to determine shell.", Argv[0]);
+           exit(1);
+       }
+
+       /* copy the args from Argv */
+       for (dst = NewArgv + 1; (*dst = *src) != NULL; ++src, ++dst)
+           ;
+    }
+
+    /* Set login class if applicable. */
+    set_loginclass(sudo_user.pw);
+
+    /* Resolve the path and return. */
+    if ((sudo_mode & MODE_RUN)) {
+       /* XXX - should call this as runas user, not root. */
+       rval = find_path(NewArgv[0], &user_cmnd, user_path);
+       if (rval != FOUND) {
+           /* Failed as root, try as invoking user. */
+           set_perms(PERM_USER, sudo_mode);
+           rval = find_path(NewArgv[0], &user_cmnd, user_path);
+           set_perms(PERM_ROOT, sudo_mode);
+       }
+
+       /* set user_args */
+       if (NewArgc > 1) {
+           char *to, **from;
+           size_t size;
+
+           /* If MODE_SHELL not set then NewArgv is contiguous so just count */
+           if (!(sudo_mode & MODE_SHELL)) {
+               size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
+                       strlen(NewArgv[NewArgc-1]) + 1;
+           } else {
+               for (size = 0, from = NewArgv + 1; *from; from++)
+                   size += strlen(*from) + 1;
+           }
+
+           /* alloc and copy. */
+           to = user_args = (char *) emalloc(size);
+           for (from = NewArgv + 1; *from; from++) {
+               (void) strcpy(to, *from);
+               to += strlen(*from);
+               *to++ = ' ';
+           }
+           *--to = '\0';
+       }
+    } else
+       rval = FOUND;
+
+    return(rval);
+}
+
+/*
+ * Command line argument parsing, can't use getopt(3).
+ */
+static int
+parse_args()
+{
+    int rval = MODE_RUN;               /* what mode is suod to be run in? */
+    int excl = 0;                      /* exclusive arg, no others allowed */
+
+    NewArgv = Argv + 1;
+    NewArgc = Argc - 1;
+
+    if (NewArgc == 0) {                        /* no options and no command */
+       rval |= (MODE_IMPLIED_SHELL | MODE_SHELL);
+       return(rval);
+    }
+
+    while (NewArgc > 0 && NewArgv[0][0] == '-') {
+       if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') {
+           (void) fprintf(stderr, "%s: Please use single character options\n",
+               Argv[0]);
+           usage(1);
+       }
+
+       switch (NewArgv[0][1]) {
+           case 'p':
+               /* Must have an associated prompt. */
+               if (NewArgv[1] == NULL)
+                   usage(1);
+
+               user_prompt = NewArgv[1];
+
+               /* Shift Argv over and adjust Argc. */
+               NewArgc--;
+               NewArgv++;
+               break;
+           case 'u':
+               /* Must have an associated runas user. */
+               if (NewArgv[1] == NULL)
+                   usage(1);
+
+               user_runas = &NewArgv[1];
+
+               /* Shift Argv over and adjust Argc. */
+               NewArgc--;
+               NewArgv++;
+               break;
+#ifdef HAVE_BSD_AUTH_H
+           case 'a':
+               /* Must have an associated authentication style. */
+               if (NewArgv[1] == NULL)
+                   usage(1);
+
+               login_style = NewArgv[1];
+
+               /* Shift Argv over and adjust Argc. */
+               NewArgc--;
+               NewArgv++;
+               break;
+#endif
+#ifdef HAVE_LOGIN_CAP_H
+           case 'c':
+               /* Must have an associated login class. */
+               if (NewArgv[1] == NULL)
+                   usage(1);
+
+               login_class = NewArgv[1];
+               def_flag(I_USE_LOGINCLASS) = TRUE;
+
+               /* Shift Argv over and adjust Argc. */
+               NewArgc--;
+               NewArgv++;
+               break;
+#endif
+           case 'b':
+               rval |= MODE_BACKGROUND;
+               break;
+           case 'v':
+               rval = MODE_VALIDATE;
+               if (excl && excl != 'v')
+                   usage_excl(1);
+               excl = 'v';
+               break;
+           case 'k':
+               rval = MODE_INVALIDATE;
+               if (excl && excl != 'k')
+                   usage_excl(1);
+               excl = 'k';
+               break;
+           case 'K':
+               rval = MODE_KILL;
+               if (excl && excl != 'K')
+                   usage_excl(1);
+               excl = 'K';
+               break;
+           case 'L':
+               rval = MODE_LISTDEFS;
+               if (excl && excl != 'L')
+                   usage_excl(1);
+               excl = 'L';
+               break;
+           case 'l':
+               rval = MODE_LIST;
+               if (excl && excl != 'l')
+                   usage_excl(1);
+               excl = 'l';
+               break;
+           case 'V':
+               rval = MODE_VERSION;
+               if (excl && excl != 'V')
+                   usage_excl(1);
+               excl = 'V';
+               break;
+           case 'h':
+               rval = MODE_HELP;
+               if (excl && excl != 'h')
+                   usage_excl(1);
+               excl = 'h';
+               break;
+           case 's':
+               rval |= MODE_SHELL;
+               if (excl && excl != 's')
+                   usage_excl(1);
+               excl = 's';
+               break;
+           case 'H':
+               rval |= MODE_RESET_HOME;
+               break;
+           case 'P':
+               rval |= MODE_PRESERVE_GROUPS;
+               break;
+           case 'S':
+               tgetpass_flags |= TGP_STDIN;
+               break;
+           case '-':
+               NewArgc--;
+               NewArgv++;
+               if (rval == MODE_RUN)
+                   rval |= (MODE_IMPLIED_SHELL | MODE_SHELL);
+               return(rval);
+           case '\0':
+               (void) fprintf(stderr, "%s: '-' requires an argument\n",
+                   Argv[0]);
+               usage(1);
+           default:
+               (void) fprintf(stderr, "%s: Illegal option %s\n", Argv[0],
+                   NewArgv[0]);
+               usage(1);
+       }
+       NewArgc--;
+       NewArgv++;
+    }
+
+    if (NewArgc > 0 && !(rval & MODE_RUN))
+       usage(1);
+
+    return(rval);
+}
+
+/*
+ * Sanity check sudoers mode/owner/type.
+ * Leaves a file pointer to the sudoers file open in ``fp''.
+ */
+static void
+check_sudoers()
+{
+    struct stat statbuf;
+    int rootstat, i;
+    char c;
+
+    /*
+     * Fix the mode and group on sudoers file from old default.
+     * Only works if filesystem is readable/writable by root.
+     */
+    if ((rootstat = lstat(_PATH_SUDOERS, &statbuf)) == 0 &&
+       SUDOERS_UID == statbuf.st_uid && SUDOERS_MODE != 0400 &&
+       (statbuf.st_mode & 0007777) == 0400) {
+
+       if (chmod(_PATH_SUDOERS, SUDOERS_MODE) == 0) {
+           (void) fprintf(stderr, "%s: fixed mode on %s\n",
+               Argv[0], _PATH_SUDOERS);
+           statbuf.st_mode |= SUDOERS_MODE;
+           if (statbuf.st_gid != SUDOERS_GID) {
+               if (!chown(_PATH_SUDOERS,(uid_t) -1,SUDOERS_GID)) {
+                   (void) fprintf(stderr, "%s: set group on %s\n",
+                       Argv[0], _PATH_SUDOERS);
+                   statbuf.st_gid = SUDOERS_GID;
+               } else {
+                   (void) fprintf(stderr,"%s: Unable to set group on %s: %s\n",
+                       Argv[0], _PATH_SUDOERS, strerror(errno));
+               }
+           }
+       } else {
+           (void) fprintf(stderr, "%s: Unable to fix mode on %s: %s\n",
+               Argv[0], _PATH_SUDOERS, strerror(errno));
+       }
+    }
+
+    /*
+     * Sanity checks on sudoers file.  Must be done as sudoers
+     * file owner.  We already did a stat as root, so use that
+     * data if we can't stat as sudoers file owner.
+     */
+    set_perms(PERM_SUDOERS, 0);
+
+    if (rootstat != 0 && lstat(_PATH_SUDOERS, &statbuf) != 0)
+       log_error(USE_ERRNO, "can't stat %s", _PATH_SUDOERS);
+    else if (!S_ISREG(statbuf.st_mode))
+       log_error(0, "%s is not a regular file", _PATH_SUDOERS);
+    else if (statbuf.st_size == 0)
+       log_error(0, "%s is zero length", _PATH_SUDOERS);
+    else if ((statbuf.st_mode & 07777) != SUDOERS_MODE)
+       log_error(0, "%s is mode 0%o, should be 0%o", _PATH_SUDOERS,
+           (statbuf.st_mode & 07777), SUDOERS_MODE);
+    else if (statbuf.st_uid != SUDOERS_UID)
+       log_error(0, "%s is owned by uid %ld, should be %d", _PATH_SUDOERS,
+           (long) statbuf.st_uid, SUDOERS_UID);
+    else if (statbuf.st_gid != SUDOERS_GID)
+       log_error(0, "%s is owned by gid %ld, should be %d", _PATH_SUDOERS,
+           (long) statbuf.st_gid, 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 ||
+               fread(&c, sizeof(c), 1, sudoers_fp) != 1) {
+               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);
+    }
+
+    set_perms(PERM_ROOT, 0);           /* change back to root */
+}
+
+/*
+ * 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()
+{
+    int fd, maxfd;
+#ifdef HAVE_SETRLIMIT
+    struct rlimit rl;
+#endif
+    sigaction_t sa;
+
+#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+    /*
+     * Turn off core dumps.
+     */
+    (void) getrlimit(RLIMIT_CORE, &corelimit);
+    rl.rlim_cur = rl.rlim_max = 0;
+    (void) setrlimit(RLIMIT_CORE, &rl);
+#endif /* RLIMIT_CORE */
+
+    /*
+     * Close any open fd's other than stdin, stdout and stderr.
+     */
+#ifdef HAVE_SYSCONF
+    maxfd = sysconf(_SC_OPEN_MAX) - 1;
+#else
+    maxfd = getdtablesize() - 1;
+#endif /* HAVE_SYSCONF */
+#ifdef RLIMIT_NOFILE
+    if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
+       if (rl.rlim_max != RLIM_INFINITY && rl.rlim_max <= maxfd)
+           maxfd = rl.rlim_max - 1;
+    }
+#endif /* RLIMIT_NOFILE */
+
+    for (fd = maxfd; fd > STDERR_FILENO; fd--)
+       (void) close(fd);
+
+    /* Catch children as they die... */
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = reapchild;
+    (void) sigaction(SIGCHLD, &sa, NULL);
+
+    /* Set set_perms pointer to the correct function */
+#if !defined(NO_SAVED_IDS) && defined(_SC_SAVED_IDS) && defined(_SC_VERSION)
+    if (sysconf(_SC_SAVED_IDS) == 1 && sysconf(_SC_VERSION) >= 199009)
+       set_perms = set_perms_posix;
+    else
+#endif
+       set_perms = set_perms_fallback;
+}
+
+#ifdef HAVE_LOGIN_CAP_H
+static void
+set_loginclass(pw)
+    struct passwd *pw;
+{
+    int errflags;
+
+    /*
+     * Don't make it a fatal error if the user didn't specify the login
+     * class themselves.  We do this because if login.conf gets
+     * corrupted we want the admin to be able to use sudo to fix it.
+     */
+    if (login_class)
+       errflags = NO_MAIL|MSG_ONLY;
+    else
+       errflags = NO_MAIL|MSG_ONLY|NO_EXIT;
+
+    if (login_class && strcmp(login_class, "-") != 0) {
+       if (strcmp(*user_runas, "root") != 0 && user_uid != 0) {
+           (void) fprintf(stderr, "%s: only root can use -c %s\n",
+               Argv[0], login_class);
+           exit(1);
+       }
+    } else {
+       login_class = pw->pw_class;
+       if (!login_class || !*login_class)
+           login_class =
+               (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
+    }
+
+    lc = login_getclass(login_class);
+    if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
+       log_error(errflags, "unknown login class: %s", login_class);
+       if (!lc)
+           lc = login_getclass(NULL);  /* needed for login_getstyle() later */
+    }
+}
+#else
+static void
+set_loginclass(pw)
+    struct passwd *pw;
+{
+}
+#endif /* HAVE_LOGIN_CAP_H */
+
+/*
+ * Look up the fully qualified domain name and set user_host and user_shost.
+ */
+void
+set_fqdn()
+{
+    struct hostent *hp;
+    char *p;
+
+    if (!(hp = gethostbyname(user_host))) {
+       log_error(MSG_ONLY|NO_EXIT,
+           "unable to lookup %s via gethostbyname()", user_host);
+    } else {
+       if (user_shost != user_host)
+           free(user_shost);
+       free(user_host);
+       user_host = estrdup(hp->h_name);
+    }
+    if ((p = strchr(user_host, '.'))) {
+       *p = '\0';
+       user_shost = estrdup(user_host);
+       *p = '.';
+    } else {
+       user_shost = user_host;
+    }
+}
+
+/*
+ * Get passwd entry for the user we are going to authenticate as.
+ * By default, this is the user invoking sudo...
+ */
+static struct passwd *
+get_authpw()
+{
+    struct passwd *pw;
+
+    if (def_ival(I_ROOTPW)) {
+       if ((pw = sudo_getpwuid(0)) == NULL)
+           log_error(0, "uid 0 does not exist in the passwd file!");
+    } else if (def_ival(I_RUNASPW)) {
+       if ((pw = sudo_getpwnam(def_str(I_RUNAS_DEFAULT))) == NULL)
+           log_error(0, "user %s does not exist in the passwd file!",
+               def_str(I_RUNAS_DEFAULT));
+    } else if (def_ival(I_TARGETPW)) {
+       if (**user_runas == '#') {
+           if ((pw = sudo_getpwuid(atoi(*user_runas + 1))) == NULL)
+               log_error(0, "uid %s does not exist in the passwd file!",
+                   user_runas);
+       } else {
+           if ((pw = sudo_getpwnam(*user_runas)) == NULL)
+               log_error(0, "user %s does not exist in the passwd file!",
+                   user_runas);
+       }
+    } else
+       pw = sudo_user.pw;
+
+    return(pw);
+}
+
+/*
+ * Tell which options are mutually exclusive and exit.
+ */
+static void
+usage_excl(exit_val)
+    int exit_val;
+{
+    (void) fprintf(stderr,
+       "Only one of the -h, -k, -K, -l, -s, -v or -V options may be used\n");
+    usage(exit_val);
+}
+
+/*
+ * Give usage message and exit.
+ */
+static void
+usage(exit_val)
+    int exit_val;
+{
+
+    (void) fprintf(stderr, "usage: sudo -V | -h | -L | -l | -v | -k | -K | %s",
+       "[-H] [-P] [-S] [-b] [-p prompt]\n            [-u username/#uid] ");
+#ifdef HAVE_LOGIN_CAP_H
+    (void) fprintf(stderr, "[-c class] ");
+#endif
+#ifdef HAVE_BSD_AUTH_H
+    (void) fprintf(stderr, "[-a auth_type] ");
+#endif
+    (void) fprintf(stderr, "-s | <command>\n");
+    exit(exit_val);
+}
diff --git a/sudo.cat b/sudo.cat
new file mode 100644 (file)
index 0000000..062410d
--- /dev/null
+++ b/sudo.cat
@@ -0,0 +1,462 @@
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+N\bN\bN\bNA\bA\bA\bAM\bM\bM\bME\bE\bE\bE
+       sudo - execute a command as another user
+
+S\bS\bS\bSY\bY\bY\bYN\bN\bN\bNO\bO\bO\bOP\bP\bP\bPS\bS\bS\bSI\bI\bI\bIS\bS\bS\bS
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo -\b-\b-\b-V\bV\bV\bV | -\b-\b-\b-h\bh\bh\bh | -\b-\b-\b-l\bl\bl\bl | -\b-\b-\b-L\bL\bL\bL | -\b-\b-\b-v\bv\bv\bv | -\b-\b-\b-k\bk\bk\bk | -\b-\b-\b-K\bK\bK\bK | -\b-\b-\b-s\bs\bs\bs | [ -\b-\b-\b-H\bH\bH\bH ] [-\b-\b-\b-P\bP\bP\bP ]
+       [-\b-\b-\b-S\bS\bS\bS ] [ -\b-\b-\b-b\bb\bb\bb ] | [ -\b-\b-\b-p\bp\bp\bp _\bp_\br_\bo_\bm_\bp_\bt ] [ -\b-\b-\b-c\bc\bc\bc _\bc_\bl_\ba_\bs_\bs|_\b- ] [ -\b-\b-\b-a\ba\ba\ba _\ba_\bu_\bt_\bh_\b__\bt_\by_\bp_\be
+       ] [ -\b-\b-\b-u\bu\bu\bu _\bu_\bs_\be_\br_\bn_\ba_\bm_\be|_\b#_\bu_\bi_\bd ] _\bc_\bo_\bm_\bm_\ba_\bn_\bd
+
+D\bD\bD\bDE\bE\bE\bES\bS\bS\bSC\bC\bC\bCR\bR\bR\bRI\bI\bI\bIP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bN
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo allows a permitted user to execute a _\bc_\bo_\bm_\bm_\ba_\bn_\bd as the
+       superuser or another user, as specified in the _\bs_\bu_\bd_\bo_\be_\br_\bs
+       file.  The real and effective uid and gid are set to match
+       those of the target user as specified in the passwd file
+       (the group vector is also initialized when the target user
+       is not root).  By default, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo requires that users
+       authenticate themselves with a password (NOTE: by default
+       this is the user's password, not the root password).  Once
+       a user has been authenticated, a timestamp is updated and
+       the user may then use sudo without a password for a short
+       period of time (5 minutes unless overridden in _\bs_\bu_\bd_\bo_\be_\br_\bs).
+
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo determines who is an authorized user by consulting
+       the file _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  By giving s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo the -\b-\b-\b-v\bv\bv\bv flag a user
+       can update the time stamp without running a _\bc_\bo_\bm_\bm_\ba_\bn_\bd_\b. The
+       password prompt itself will also time out if the user's
+       password is not entered within 5 minutes (unless overrid­
+       den via _\bs_\bu_\bd_\bo_\be_\br_\bs).
+
+       If a user who is not listed in the _\bs_\bu_\bd_\bo_\be_\br_\bs file tries to
+       run a command via s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo, mail is sent to the proper author­
+       ities, as defined at configure time or the _\bs_\bu_\bd_\bo_\be_\br_\bs file
+       (defaults to root).  Note that the mail will not be sent
+       if an unauthorized user tries to run sudo with the -\b-\b-\b-l\bl\bl\bl or
+       -\b-\b-\b-v\bv\bv\bv flags.  This allows users to determine for themselves
+       whether or not they are allowed to use s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo.
+
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo can log both successful and unsuccessful attempts (as
+       well as errors) to _\bs_\by_\bs_\bl_\bo_\bg(3), a log file, or both.  By
+       default s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will log via _\bs_\by_\bs_\bl_\bo_\bg(3) but this is changeable
+       at configure time or via the _\bs_\bu_\bd_\bo_\be_\br_\bs file.
+
+O\bO\bO\bOP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bNS\bS\bS\bS
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo accepts the following command line options:
+
+       -V  The -\b-\b-\b-V\bV\bV\bV (_\bv_\be_\br_\bs_\bi_\bo_\bn) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to print the ver­
+           sion number and exit.  If the invoking user is already
+           root the -\b-\b-\b-V\bV\bV\bV option will print out a list of the
+           defaults s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo was compiled with as well as the
+           machine's local network addresses.
+
+       -l  The -\b-\b-\b-l\bl\bl\bl (_\bl_\bi_\bs_\bt) option will list out the allowed (and
+           forbidden) commands for the user on the current host.
+
+
+
+
+
+April 25, 2002                1.6.6                             1
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+       -L  The -\b-\b-\b-L\bL\bL\bL (_\bl_\bi_\bs_\bt defaults) option will list out the param­
+           eters that may be set in a _\bD_\be_\bf_\ba_\bu_\bl_\bt_\bs line along with a
+           short description for each.  This option is useful in
+           conjunction with _\bg_\br_\be_\bp(1).
+
+       -h  The -\b-\b-\b-h\bh\bh\bh (_\bh_\be_\bl_\bp) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to print a usage mes­
+           sage and exit.
+
+       -v  If given the -\b-\b-\b-v\bv\bv\bv (_\bv_\ba_\bl_\bi_\bd_\ba_\bt_\be) option, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will update
+           the user's timestamp, prompting for the user's pass­
+           word if necessary.  This extends the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo timeout for
+           another 5 minutes (or whatever the timeout is set to
+           in _\bs_\bu_\bd_\bo_\be_\br_\bs) but does not run a command.
+
+       -k  The -\b-\b-\b-k\bk\bk\bk (_\bk_\bi_\bl_\bl) option to s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo invalidates the user's
+           timestamp by setting the time on it to the epoch.  The
+           next time s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is run a password will be required.
+           This option does not require a password and was added
+           to allow a user to revoke s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo permissions from a
+           .logout file.
+
+       -K  The -\b-\b-\b-K\bK\bK\bK (sure _\bk_\bi_\bl_\bl) option to s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo removes the user's
+           timestamp entirely.  Likewise, this option does not
+           require a password.
+
+       -b  The -\b-\b-\b-b\bb\bb\bb (_\bb_\ba_\bc_\bk_\bg_\br_\bo_\bu_\bn_\bd) option tells s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to run the given
+           command in the background.  Note that if you use the
+           -\b-\b-\b-b\bb\bb\bb option you cannot use shell job control to manipu­
+           late the process.
+
+       -p  The -\b-\b-\b-p\bp\bp\bp (_\bp_\br_\bo_\bm_\bp_\bt) option allows you to override the
+           default password prompt and use a custom one.  If the
+           password prompt contains the %u escape, %u will be
+           replaced with the user's login name.  Similarly, %h
+           will be replaced with the local hostname.
+
+       -c  The -\b-\b-\b-c\bc\bc\bc (_\bc_\bl_\ba_\bs_\bs) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to run the specified
+           command with resources limited by the specified login
+           class.  The _\bc_\bl_\ba_\bs_\bs argument can be either a class name
+           as defined in /etc/login.conf, or a single '-' charac­
+           ter.  Specifying a _\bc_\bl_\ba_\bs_\bs of - indicates that the com­
+           mand should be run restricted by the default login
+           capabilities for the user the command is run as.  If
+           the _\bc_\bl_\ba_\bs_\bs argument specifies an existing user class,
+           the command must be run as root, or the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo command
+           must be run from a shell that is already root.  This
+           option is only available on systems with BSD login
+           classes where s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo has been configured with the
+           --with-logincap option.
+
+       -a  The -\b-\b-\b-a\ba\ba\ba (_\ba_\bu_\bt_\bh_\be_\bn_\bt_\bi_\bc_\ba_\bt_\bi_\bo_\bn _\bt_\by_\bp_\be) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to use
+           the specified authentication type when validating the
+           user, as allowed by /etc/login.conf.  The system
+           administrator may specify a list of sudo-specific
+
+
+
+April 25, 2002                1.6.6                             2
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+           authentication methods by adding an "auth-sudo" entry
+           in /etc/login.conf.  This option is only available on
+           systems that support BSD authentication where s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo has
+           been configured with the --with-bsdauth option.
+
+       -u  The -\b-\b-\b-u\bu\bu\bu (_\bu_\bs_\be_\br) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to run the specified
+           command as a user other than _\br_\bo_\bo_\bt.  To specify a _\bu_\bi_\bd
+           instead of a _\bu_\bs_\be_\br_\bn_\ba_\bm_\be, use _\b#_\bu_\bi_\bd.
+
+       -s  The -\b-\b-\b-s\bs\bs\bs (_\bs_\bh_\be_\bl_\bl) option runs the shell specified by the
+           _\bS_\bH_\bE_\bL_\bL environment variable if it is set or the shell
+           as specified in _\bp_\ba_\bs_\bs_\bw_\bd(4).
+
+       -H  The -\b-\b-\b-H\bH\bH\bH (_\bH_\bO_\bM_\bE) option sets the HOME environment vari­
+           able to the homedir of the target user (root by
+           default) as specified in _\bp_\ba_\bs_\bs_\bw_\bd(4).  By default, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo
+           does not modify HOME.
+
+       -P  The -\b-\b-\b-P\bP\bP\bP (_\bp_\br_\be_\bs_\be_\br_\bv_\be _\bg_\br_\bo_\bu_\bp _\bv_\be_\bc_\bt_\bo_\br) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to
+           preserve the user's group vector unaltered.  By
+           default, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo 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.
+
+       -S  The -\b-\b-\b-S\bS\bS\bS (_\bs_\bt_\bd_\bi_\bn) option causes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to read the password
+           from standard input instead of the terminal device.
+
+       --  The -\b-\b-\b--\b-\b-\b- flag indicates that s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo should stop processing
+           command line arguments.  It is most useful in conjunc­
+           tion with the -\b-\b-\b-s\bs\bs\bs flag.
+
+R\bR\bR\bRE\bE\bE\bET\bT\bT\bTU\bU\bU\bUR\bR\bR\bRN\bN\bN\bN V\bV\bV\bVA\bA\bA\bAL\bL\bL\bLU\bU\bU\bUE\bE\bE\bES\bS\bS\bS
+       Upon successful execution of a program, the return value
+       from s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will simply be the return value of the program
+       that was executed.
+
+       Otherwise, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo quits with an exit value of 1 if there is
+       a configuration/permission problem or if s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo cannot exe­
+       cute the given command.  In the latter case the error
+       string is printed to stderr.  If s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo cannot _\bs_\bt_\ba_\bt(2) one
+       or more entries in the user's PATH an error is printed on
+       stderr.  (If the directory does not exist or if it is not
+       really a directory, the entry is ignored and no error is
+       printed.)  This should not happen under normal circum­
+       stances.  The most common reason for _\bs_\bt_\ba_\bt(2) to return
+       "permission denied" is if you are running an automounter
+       and one of the directories in your PATH is on a machine
+       that is currently unreachable.
+
+S\bS\bS\bSE\bE\bE\bEC\bC\bC\bCU\bU\bU\bUR\bR\bR\bRI\bI\bI\bIT\bT\bT\bTY\bY\bY\bY N\bN\bN\bNO\bO\bO\bOT\bT\bT\bTE\bE\bE\bES\bS\bS\bS
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo tries to be safe when executing external commands.
+       Variables that control how dynamic loading and binding is
+       done can be used to subvert the program that s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo runs.
+
+
+
+April 25, 2002                1.6.6                             3
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+       To combat this the LD_*, _RLD_*, SHLIB_PATH (HP-UX only),
+       and LIBPATH (AIX only) environment variables are removed
+       from the environment passed on to all commands executed.
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will also remove the IFS, ENV, BASH_ENV, KRB_CONF,
+       KRBCONFDIR, KRBTKFILE, KRB5_CONFIG, LOCALDOMAIN,
+       RES_OPTIONS, HOSTALIASES, NLSPATH, PATH_LOCALE, TERMINFO,
+       TERMINFO_DIRS and TERMPATH variables as they too can pose
+       a threat.  If the TERMCAP variable is set and is a path­
+       name, it too is ignored.  Additionally, if the LC_* or
+       LANGUAGE variables contain the / or % characters, they are
+       ignored.  If s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo has been compiled with SecurID support,
+       the VAR_ACE, USR_ACE and DLC_ACE variables are cleared as
+       well.  The list of environment variables that s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo clears
+       is contained in the output of sudo -V when run as root.
+
+       To prevent command spoofing, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo checks "." and "" (both
+       denoting current directory) last when searching for a com­
+       mand in the user's PATH (if one or both are in the PATH).
+       Note, however, that the actual PATH environment variable
+       is _\bn_\bo_\bt modified and is passed unchanged to the program
+       that s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo executes.
+
+       For security reasons, if your OS supports shared libraries
+       and does not disable user-defined library search paths for
+       setuid programs (most do), you should either use a linker
+       option that disables this behavior or link s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo stati­
+       cally.
+
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will check the ownership of its timestamp directory
+       (_\b/_\bv_\ba_\br_\b/_\br_\bu_\bn_\b/_\bs_\bu_\bd_\bo by default) and ignore the directory's con­
+       tents if it is not owned by root and only writable by
+       root.  On systems that allow non-root users to give away
+       files via _\bc_\bh_\bo_\bw_\bn(2), if the timestamp directory is located
+       in a directory writable by anyone (e.g.: _\b/_\bt_\bm_\bp), it is pos­
+       sible for a user to create the timestamp directory before
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is run.  However, because s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo checks the ownership
+       and mode of the directory and its contents, the only dam­
+       age that can be done is to "hide" files by putting them in
+       the timestamp dir.  This is unlikely to happen since once
+       the timestamp dir is owned by root and inaccessible by any
+       other user the user placing files there would be unable to
+       get them back out.  To get around this issue you can use a
+       directory that is not world-writable for the timestamps
+       (_\b/_\bv_\ba_\br_\b/_\ba_\bd_\bm_\b/_\bs_\bu_\bd_\bo for instance) or create _\b/_\bv_\ba_\br_\b/_\br_\bu_\bn_\b/_\bs_\bu_\bd_\bo with
+       the appropriate owner (root) and permissions (0700) in the
+       system startup files.
+
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will not honor timestamps set far in the future.
+       Timestamps with a date greater than current_time + 2 *
+       TIMEOUT will be ignored and sudo will log and complain.
+       This is done to keep a user from creating his/her own
+       timestamp with a bogus date on systems that allow users to
+       give away files.
+
+
+
+
+April 25, 2002                1.6.6                             4
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+       Please note that s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will only log the command it explic­
+       itly runs.  If a user runs a command such as sudo su or
+       sudo sh, subsequent commands run from that shell will _\bn_\bo_\bt
+       be logged, nor will s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo's access control affect them.
+       The same is true for commands that offer shell escapes
+       (including most editors).  Because of this, care must be
+       taken when giving users access to commands via s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to
+       verify that the command does not inadvertantly give the
+       user an effective root shell.
+
+E\bE\bE\bEX\bX\bX\bXA\bA\bA\bAM\bM\bM\bMP\bP\bP\bPL\bL\bL\bLE\bE\bE\bES\bS\bS\bS
+       Note: the following examples assume suitable _\bs_\bu_\bd_\bo_\be_\br_\bs(4)
+       entries.
+
+       To get a file listing of an unreadable directory:
+
+        % sudo ls /usr/local/protected
+
+       To list the home directory of user yazza on a machine
+       where the filesystem holding ~yazza is not exported as
+       root:
+
+        % sudo -u yazza ls ~yazza
+
+       To edit the _\bi_\bn_\bd_\be_\bx_\b._\bh_\bt_\bm_\bl file as user www:
+
+        % sudo -u www vi ~www/htdocs/index.html
+
+       To shutdown a machine:
+
+        % sudo shutdown -r +15 "quick reboot"
+
+       To make a usage listing of the directories in the /home
+       partition.  Note that this runs the commands in a sub-
+       shell to make the cd and file redirection work.
+
+        % sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+
+
+E\bE\bE\bEN\bN\bN\bNV\bV\bV\bVI\bI\bI\bIR\bR\bR\bRO\bO\bO\bON\bN\bN\bNM\bM\bM\bME\bE\bE\bEN\bN\bN\bNT\bT\bT\bT
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo utilizes the following environment variables:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+April 25, 2002                1.6.6                             5
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+        PATH                   Set to a sane value if SECURE_PATH is set
+        SHELL                  Used to determine shell to run with -s option
+        USER                   Set to the target user (root unless the -u option
+                               is specified)
+        HOME                   In -s or -H mode (or if sudo was configured with
+                               the --enable-shell-sets-home option), set to
+                               homedir of the target user.
+        SUDO_PROMPT            Used as the default password prompt
+        SUDO_COMMAND           Set to the command run by sudo
+        SUDO_USER              Set to the login of the user who invoked sudo
+        SUDO_UID               Set to the uid of the user who invoked sudo
+        SUDO_GID               Set to the gid of the user who invoked sudo
+        SUDO_PS1               If set, PS1 will be set to its value
+
+
+F\bF\bF\bFI\bI\bI\bIL\bL\bL\bLE\bE\bE\bES\bS\bS\bS
+        /etc/sudoers           List of who can run what
+        /var/run/sudo              Directory containing timestamps
+
+
+A\bA\bA\bAU\bU\bU\bUT\bT\bT\bTH\bH\bH\bHO\bO\bO\bOR\bR\bR\bRS\bS\bS\bS
+       Many people have worked on s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo over the years; this ver­
+       sion consists of code written primarily by:
+
+               Todd Miller
+               Chris Jepeway
+
+       See the HISTORY file in the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo distribution or visit
+       http://www.sudo.ws/sudo/history.html for a short history
+       of s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo.
+
+B\bB\bB\bBU\bU\bU\bUG\bG\bG\bGS\bS\bS\bS
+       If you feel you have found a bug in sudo, please submit a
+       bug report at http://www.sudo.ws/sudo/bugs/
+
+D\bD\bD\bDI\bI\bI\bIS\bS\bS\bSC\bC\bC\bCL\bL\bL\bLA\bA\bA\bAI\bI\bI\bIM\bM\bM\bME\bE\bE\bER\bR\bR\bR
+       S\bS\bS\bSu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is provided ``AS IS'' and any express or implied war­
+       ranties, including, but not limited to, the implied war­
+       ranties of merchantability and fitness for a particular
+       purpose are disclaimed.  See the LICENSE file distributed
+       with s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo for complete details.
+
+C\bC\bC\bCA\bA\bA\bAV\bV\bV\bVE\bE\bE\bEA\bA\bA\bAT\bT\bT\bTS\bS\bS\bS
+       There is no easy way to prevent a user from gaining a root
+       shell if that user has access to commands allowing shell
+       escapes.
+
+       If users have sudo ALL there is nothing to prevent them
+       from creating their own program that gives them a root
+       shell regardless of any '!'  elements in the user specifi­
+       cation.
+
+       Running shell scripts via s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo can expose the same kernel
+       bugs that make setuid shell scripts unsafe on some
+
+
+
+April 25, 2002                1.6.6                             6
+
+
+
+
+
+sudo(1m)               MAINTENANCE COMMANDS              sudo(1m)
+
+
+       operating systems (if your OS supports the /dev/fd/ direc­
+       tory, setuid shell scripts are generally safe).
+
+S\bS\bS\bSE\bE\bE\bEE\bE\bE\bE A\bA\bA\bAL\bL\bL\bLS\bS\bS\bSO\bO\bO\bO
+       _\bs_\bt_\ba_\bt(2), _\bl_\bo_\bg_\bi_\bn_\b__\bc_\ba_\bp(3), _\bs_\bu_\bd_\bo_\be_\br_\bs(4), _\bp_\ba_\bs_\bs_\bw_\bd(5), _\bv_\bi_\bs_\bu_\bd_\bo(1m),
+       _\bg_\br_\be_\bp(1), _\bs_\bu(1).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+April 25, 2002                1.6.6                             7
+
+
diff --git a/sudo.h b/sudo.h
new file mode 100644 (file)
index 0000000..44a1ede
--- /dev/null
+++ b/sudo.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1993-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: sudo.h,v 1.184 2002/01/16 21:27:09 millert Exp $
+ */
+
+#ifndef _SUDO_SUDO_H
+#define _SUDO_SUDO_H
+
+#include <pathnames.h>
+#include "compat.h"
+#include "defaults.h"
+#include "logging.h"
+
+/*
+ * Info pertaining to the invoking user.
+ */
+struct sudo_user {
+    struct passwd *pw;
+    struct passwd *_runas_pw;
+    char *path;
+    char *shell;
+    char *tty;
+    char  cwd[MAXPATHLEN];
+    char *host;
+    char *shost;
+    char **runas;
+    char *prompt;
+    char *cmnd_safe;
+    char *cmnd;
+    char *cmnd_args;
+    char *class_name;
+};
+
+/*
+ * Return values for sudoers_lookup(), also used as arguments for log_auth()
+ * Note: cannot use '0' as a value here.
+ */
+/* XXX - VALIDATE_SUCCESS and VALIDATE_FAILURE instead? */
+#define VALIDATE_ERROR          0x01
+#define VALIDATE_OK            0x02
+#define VALIDATE_NOT_OK                0x04
+#define FLAG_NOPASS            0x10
+#define FLAG_NO_USER           0x20
+#define FLAG_NO_HOST           0x40
+#define FLAG_NO_CHECK          0x80
+
+/*
+ * Boolean values
+ */
+#undef TRUE
+#define TRUE                     1
+#undef FALSE
+#define FALSE                    0
+
+/*
+ * find_path()/load_cmnd() return values
+ */
+#define FOUND                    1
+#define NOT_FOUND                0
+#define NOT_FOUND_DOT          -1
+
+/*
+ * Various modes sudo can be in (based on arguments) in octal
+ */
+#define MODE_RUN                 000001
+#define MODE_VALIDATE            000002
+#define MODE_INVALIDATE          000004
+#define MODE_KILL                000010
+#define MODE_VERSION             000020
+#define MODE_HELP                000040
+#define MODE_LIST                000100
+#define MODE_LISTDEFS            000200
+#define MODE_BACKGROUND          000400
+#define MODE_SHELL               001000
+#define MODE_IMPLIED_SHELL       002000
+#define MODE_RESET_HOME          004000
+#define MODE_PRESERVE_GROUPS     010000
+
+/*
+ * Used with set_perms()
+ */
+#define PERM_ROOT                0x00
+#define PERM_FULL_ROOT           0x01
+#define PERM_USER                0x02
+#define PERM_FULL_USER           0x03
+#define PERM_SUDOERS             0x04
+#define PERM_RUNAS               0x05
+
+/*
+ * Shortcuts for sudo_user contents.
+ */
+#define user_name              (sudo_user.pw->pw_name)
+#define user_passwd            (sudo_user.pw->pw_passwd)
+#define user_uid               (sudo_user.pw->pw_uid)
+#define user_gid               (sudo_user.pw->pw_gid)
+#define user_dir               (sudo_user.pw->pw_dir)
+#define user_shell             (sudo_user.shell)
+#define user_tty               (sudo_user.tty)
+#define user_cwd               (sudo_user.cwd)
+#define user_runas             (sudo_user.runas)
+#define user_cmnd              (sudo_user.cmnd)
+#define user_args              (sudo_user.cmnd_args)
+#define user_path              (sudo_user.path)
+#define user_prompt            (sudo_user.prompt)
+#define user_host              (sudo_user.host)
+#define user_shost             (sudo_user.shost)
+#define safe_cmnd              (sudo_user.cmnd_safe)
+#define login_class            (sudo_user.class_name)
+#define runas_pw               (sudo_user._runas_pw)
+
+/*
+ * We used to use the system definition of PASS_MAX or _PASSWD_LEN,
+ * but that caused problems with various alternate authentication
+ * methods.  So, we just define our own and assume that it is >= the
+ * system max.
+ */
+#define SUDO_PASS_MAX  256
+
+/*
+ * Flags for lock_file()
+ */
+#define SUDO_LOCK      1               /* lock a file */
+#define SUDO_TLOCK     2               /* test & lock a file (non-blocking) */
+#define SUDO_UNLOCK    4               /* unlock a file */
+
+/*
+ * Flags for sudoers_lookup:
+ *  PASSWD_NEVER:  user never has to give a passwd
+ *  PASSWD_ALL:    no passwd needed if all entries for host have NOPASSWD flag
+ *  PASSWD_ANY:    no passwd needed if any entry for host has a NOPASSWD flag
+ *  PASSWD_ALWAYS: passwd always needed
+ */
+#define PWCHECK_NEVER  0x01
+#define PWCHECK_ALL    0x02
+#define PWCHECK_ANY    0x04
+#define PWCHECK_ALWAYS 0x08
+
+/*
+ * Flags for tgetpass()
+ */
+#define TGP_ECHO       0x01            /* leave echo on when reading passwd */
+#define TGP_STDIN      0x02            /* read from stdin, not /dev/tty */
+
+/*
+ * Function prototypes
+ */
+#define YY_DECL int yylex __P((void))
+
+#ifndef HAVE_GETCWD
+char *getcwd           __P((char *, size_t size));
+#endif
+#ifndef HAVE_SNPRINTF
+int snprintf           __P((char *, size_t, const char *, ...));
+#endif
+#ifndef HAVE_VSNPRINTF
+int vsnprintf          __P((char *, size_t, const char *, va_list));
+#endif
+#ifndef HAVE_ASPRINTF
+int asprintf           __P((char **, const char *, ...));
+#endif
+#ifndef HAVE_VASPRINTF
+int vasprintf          __P((char **, const char *, va_list));
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp         __P((const char *, const char *));
+#endif
+char *sudo_goodpath    __P((const char *));
+char *tgetpass         __P((const char *, int, int));
+int find_path          __P((char *, char **, char *));
+void check_user                __P((void));
+void verify_user       __P((struct passwd *, char *));
+int sudoers_lookup     __P((int));
+void set_perms_posix   __P((int, int));
+void set_perms_fallback        __P((int, int));
+void remove_timestamp  __P((int));
+int check_secureware   __P((char *));
+void sia_attempt_auth  __P((void));
+void pam_attempt_auth  __P((void));
+int yyparse            __P((void));
+void pass_warn         __P((FILE *));
+VOID *emalloc          __P((size_t));
+VOID *erealloc         __P((VOID *, size_t));
+char *estrdup          __P((const char *));
+int easprintf          __P((char **, const char *, ...));
+int evasprintf         __P((char **, const char *, va_list));
+void dump_badenv       __P((void));
+void dump_defaults     __P((void));
+void dump_auth_methods __P((void));
+void init_envtables    __P((void));
+int lock_file          __P((int, int));
+int touch              __P((char *, time_t));
+int user_is_exempt     __P((void));
+void set_fqdn          __P((void));
+char *sudo_getepw      __P((struct passwd *));
+int pam_prep_user      __P((struct passwd *));
+YY_DECL;
+
+/* Only provide extern declarations outside of sudo.c. */
+#ifndef _SUDO_SUDO_C
+extern struct sudo_user sudo_user;
+extern struct passwd *auth_pw;
+
+extern int Argc;
+extern char **Argv;
+extern FILE *sudoers_fp;
+extern int tgetpass_flags;
+
+extern void (*set_perms) __P((int, int));
+#endif
+extern int errno;
+
+#endif /* _SUDO_SUDO_H */
diff --git a/sudo.man.in b/sudo.man.in
new file mode 100644 (file)
index 0000000..838af38
--- /dev/null
@@ -0,0 +1,456 @@
+.\" Automatically generated by Pod::Man version 1.15
+.\" Thu Apr 25 09:34:52 2002
+.\"
+.\" Standard preamble:
+.\" ======================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+
+.fi
+..
+.\" 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
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` 
+.    ds C' 
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" 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 \{\
+.    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
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.bd B 3
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ======================================================================
+.\"
+.IX Title "sudo @mansectsu@"
+.TH sudo @mansectsu@ "1.6.6" "April 25, 2002" "MAINTENANCE COMMANDS"
+.UC
+.SH "NAME"
+sudo \- execute a command as another user
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBsudo\fR \fB\-V\fR | \fB\-h\fR | \fB\-l\fR | \fB\-L\fR | \fB\-v\fR | \fB\-k\fR | \fB\-K\fR | \fB\-s\fR |
+[ \fB\-H\fR ] [\fB\-P\fR ] [\fB\-S\fR ] [ \fB\-b\fR ] | [ \fB\-p\fR \fIprompt\fR ]
+[ \fB\-c\fR \fIclass\fR|\fI-\fR ] [ \fB\-a\fR \fIauth_type\fR ]
+[ \fB\-u\fR \fIusername\fR|\fI#uid\fR ] \fIcommand\fR
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBsudo\fR allows a permitted user to execute a \fIcommand\fR as the
+superuser or another user, as specified in the \fIsudoers\fR file.
+The real and effective uid and gid are set to match those of the
+target user as specified in the passwd file (the group vector is
+also initialized when the target user is not root).  By default,
+\&\fBsudo\fR requires that users authenticate themselves with a password
+(\s-1NOTE:\s0 by default this is the user's password, not the root password).
+Once a user has been authenticated, a timestamp is updated and the
+user may then use sudo without a password for a short period of
+time (\f(CW\*(C`@timeout@\*(C'\fR minutes unless overridden in \fIsudoers\fR).
+.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).
+.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 the \fIsudoers\fR file (defaults to root).
+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 users to
+determine for themselves whether or not they are allowed to use
+\&\fBsudo\fR.
+.PP
+\&\fBsudo\fR can log both successful and unsuccessful attempts (as well
+as errors) to \fIsyslog\fR\|(3), a log file, or both.  By default \fBsudo\fR
+will log via \fIsyslog\fR\|(3) but this is changeable at configure time
+or via the \fIsudoers\fR file.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBsudo\fR accepts the following command line options:
+.Ip "\-V" 4
+.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 "\-l" 4
+.IX Item "-l"
+The \fB\-l\fR (\fIlist\fR) option will list out the allowed (and
+forbidden) commands for the user on the current host.
+.Ip "\-L" 4
+.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 "\-h" 4
+.IX Item "-h"
+The \fB\-h\fR (\fIhelp\fR) option causes \fBsudo\fR to print a usage message and exit.
+.Ip "\-v" 4
+.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 "\-k" 4
+.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 "\-K" 4
+.IX Item "-K"
+The \fB\-K\fR (sure \fIkill\fR) option to \fBsudo\fR removes the user's timestamp
+entirely.  Likewise, this option does not require a password.
+.Ip "\-b" 4
+.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.
+.Ip "\-p" 4
+.IX Item "-p"
+The \fB\-p\fR (\fIprompt\fR) option allows you to override the default
+password prompt and use a custom one.  If the password prompt
+contains the \f(CW\*(C`%u\*(C'\fR escape, \f(CW\*(C`%u\*(C'\fR will be replaced with the user's
+login name.  Similarly, \f(CW\*(C`%h\*(C'\fR will be replaced with the local
+hostname.
+.Ip "\-c" 4
+.IX Item "-c"
+The \fB\-c\fR (\fIclass\fR) option causes \fBsudo\fR to run the specified command
+with resources limited by the specified login class.  The \fIclass\fR
+argument can be either a class name as defined in /etc/login.conf,
+or a single '\-' character.  Specifying a \fIclass\fR of \f(CW\*(C`\-\*(C'\fR indicates
+that the command should be run restricted by the default login
+capabilities for the user the command is run as.  If the \fIclass\fR
+argument specifies an existing user class, the command must be run
+as root, or the \fBsudo\fR command must be run from a shell that is already
+root.  This option is only available on systems with \s-1BSD\s0 login classes
+where \fBsudo\fR has been configured with the \-\-with-logincap option.
+.Ip "\-a" 4
+.IX Item "-a"
+The \fB\-a\fR (\fIauthentication type\fR) option causes \fBsudo\fR to use the
+specified authentication type when validating the user, as allowed
+by /etc/login.conf.  The system administrator may specify a list
+of sudo-specific authentication methods by adding an \*(L"auth-sudo\*(R"
+entry in /etc/login.conf.  This option is only available on systems
+that support \s-1BSD\s0 authentication where \fBsudo\fR has been configured
+with the \-\-with-bsdauth option.
+.Ip "\-u" 4
+.IX Item "-u"
+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.
+.Ip "\-s" 4
+.IX Item "-s"
+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@).
+.Ip "\-H" 4
+.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.
+.Ip "\-P" 4
+.IX Item "-P"
+The \fB\-P\fR (\fIpreserve group vector\fR) option causes \fBsudo\fR to preserve
+the 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 "\-S" 4
+.IX Item "-S"
+The \fB\-S\fR (\fIstdin\fR) option causes \fBsudo\fR to read the password from
+standard input instead of the terminal device.
+.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.
+.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.
+.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
+given command.  In the latter case the error string is printed to
+stderr.  If \fBsudo\fR cannot \fIstat\fR\|(2) one or more entries in the user's
+\&\f(CW\*(C`PATH\*(C'\fR an error is printed on stderr.  (If the directory does not
+exist or if it is not really a directory, the entry is ignored and
+no error is printed.)  This should not happen under normal
+circumstances.  The most common reason for \fIstat\fR\|(2) to return
+\&\*(L"permission denied\*(R" is if you are running an automounter and one
+of the directories in your \f(CW\*(C`PATH\*(C'\fR is on a machine that is currently
+unreachable.
+.SH "SECURITY NOTES"
+.IX Header "SECURITY NOTES"
+\&\fBsudo\fR tries to be safe when executing external commands.  Variables
+that control how dynamic loading and binding is done can be used
+to subvert the program that \fBsudo\fR runs.  To combat this the
+\&\f(CW\*(C`LD_*\*(C'\fR, \f(CW\*(C`_RLD_*\*(C'\fR, \f(CW\*(C`SHLIB_PATH\*(C'\fR (\s-1HP-UX\s0 only), and \f(CW\*(C`LIBPATH\*(C'\fR (\s-1AIX\s0
+only) environment variables are removed from the environment passed
+on to all commands executed.  \fBsudo\fR will also remove the \f(CW\*(C`IFS\*(C'\fR,
+\&\f(CW\*(C`ENV\*(C'\fR, \f(CW\*(C`BASH_ENV\*(C'\fR, \f(CW\*(C`KRB_CONF\*(C'\fR, \f(CW\*(C`KRBCONFDIR\*(C'\fR, \f(CW\*(C`KRBTKFILE\*(C'\fR,
+\&\f(CW\*(C`KRB5_CONFIG\*(C'\fR, \f(CW\*(C`LOCALDOMAIN\*(C'\fR, \f(CW\*(C`RES_OPTIONS\*(C'\fR, \f(CW\*(C`HOSTALIASES\*(C'\fR,
+\&\f(CW\*(C`NLSPATH\*(C'\fR, \f(CW\*(C`PATH_LOCALE\*(C'\fR, \f(CW\*(C`TERMINFO\*(C'\fR, \f(CW\*(C`TERMINFO_DIRS\*(C'\fR and
+\&\f(CW\*(C`TERMPATH\*(C'\fR variables as they too can pose a threat.  If the
+\&\f(CW\*(C`TERMCAP\*(C'\fR variable is set and is a pathname, it too is ignored.
+Additionally, if the \f(CW\*(C`LC_*\*(C'\fR or \f(CW\*(C`LANGUAGE\*(C'\fR variables contain the
+\&\f(CW\*(C`/\*(C'\fR or \f(CW\*(C`%\*(C'\fR characters, they are ignored.  If \fBsudo\fR has been
+compiled with SecurID support, the \f(CW\*(C`VAR_ACE\*(C'\fR, \f(CW\*(C`USR_ACE\*(C'\fR and
+\&\f(CW\*(C`DLC_ACE\*(C'\fR variables are cleared as well.  The list of environment
+variables that \fBsudo\fR clears is contained in the output of
+\&\f(CW\*(C`sudo \-V\*(C'\fR when run as root.
+.PP
+To prevent command spoofing, \fBsudo\fR checks \*(L".\*(R" and "" (both denoting
+current directory) last when searching for a command in the user's
+\&\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.
+.PP
+For security reasons, if your \s-1OS\s0 supports shared libraries and does
+not disable user-defined library search paths for setuid programs
+(most do), you should either use a linker option that disables this
+behavior or link \fBsudo\fR statically.
+.PP
+\&\fBsudo\fR will check the ownership of its timestamp directory
+(\fI@timedir@\fR by default) and ignore the directory's contents if
+it is not owned by root and only writable by root.  On systems that
+allow non-root users to give away files via \fIchown\fR\|(2), if the timestamp
+directory is located in a directory writable by anyone (e.g.: \fI/tmp\fR),
+it is possible for a user to create the timestamp directory before
+\&\fBsudo\fR is run.  However, because \fBsudo\fR checks the ownership and
+mode of the directory and its contents, the only damage that can
+be done is to \*(L"hide\*(R" files by putting them in the timestamp dir.
+This is unlikely to happen since once the timestamp dir is owned
+by root and inaccessible by any other user the user placing files
+there would be unable to get them back out.  To get around this
+issue you can use a directory that is not world-writable for the
+timestamps (\fI/var/adm/sudo\fR for instance) or create \fI@timedir@\fR
+with the appropriate owner (root) and permissions (0700) in the
+system startup files.
+.PP
+\&\fBsudo\fR will not honor timestamps set far in the future.
+Timestamps with a date greater than current_time + 2 * \f(CW\*(C`TIMEOUT\*(C'\fR
+will be ignored and sudo will log and complain.  This is done to
+keep a user from creating his/her own timestamp with a bogus
+date on systems that allow users to give away files.
+.PP
+Please note that \fBsudo\fR will only log the command it explicitly
+runs.  If a user runs a command such as \f(CW\*(C`sudo su\*(C'\fR or \f(CW\*(C`sudo sh\*(C'\fR,
+subsequent commands run from that shell will \fInot\fR be logged, nor
+will \fBsudo\fR's access control affect them.  The same is true for
+commands that offer shell escapes (including most editors).  Because
+of this, care must be taken when giving users access to commands
+via \fBsudo\fR to verify that the command does not inadvertantly give
+the user an effective root shell.
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+Note: the following examples assume suitable \fIsudoers\fR\|(@mansectform@) entries.
+.PP
+To get a file listing of an unreadable directory:
+.PP
+.Vb 1
+\& % sudo ls /usr/local/protected
+.Ve
+To list the home directory of user yazza on a machine where the
+filesystem holding ~yazza is not exported as root:
+.PP
+.Vb 1
+\& % sudo -u yazza ls ~yazza
+.Ve
+To edit the \fIindex.html\fR file as user www:
+.PP
+.Vb 1
+\& % sudo -u www vi ~www/htdocs/index.html
+.Ve
+To shutdown a machine:
+.PP
+.Vb 1
+\& % sudo shutdown -r +15 "quick reboot"
+.Ve
+To make a usage listing of the directories in the /home
+partition.  Note that this runs the commands in a sub-shell
+to make the \f(CW\*(C`cd\*(C'\fR and file redirection work.
+.PP
+.Vb 1
+\& % sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+.Ve
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+\&\fBsudo\fR utilizes the following environment variables:
+.PP
+.Vb 13
+\& PATH                   Set to a sane value if SECURE_PATH is set
+\& SHELL                  Used to determine shell to run with -s option
+\& USER                   Set to the target user (root unless the -u option
+\&                        is specified)
+\& HOME                   In -s or -H mode (or if sudo was configured with
+\&                        the --enable-shell-sets-home option), set to
+\&                        homedir of the target user.
+\& SUDO_PROMPT            Used as the default password prompt
+\& SUDO_COMMAND           Set to the command run by sudo
+\& SUDO_USER              Set to the login of the user who invoked sudo
+\& SUDO_UID               Set to the uid of the user who invoked sudo
+\& SUDO_GID               Set to the gid of the user who invoked sudo
+\& SUDO_PS1               If set, PS1 will be set to its value
+.Ve
+.SH "FILES"
+.IX Header "FILES"
+.Vb 2
+\& @sysconfdir@/sudoers           List of who can run what
+\& @timedir@              Directory containing timestamps
+.Ve
+.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
+\&        Todd Miller
+\&        Chris Jepeway
+.Ve
+See the \s-1HISTORY\s0 file in the \fBsudo\fR distribution or visit
+http://www.sudo.ws/sudo/history.html for a short history
+of \fBsudo\fR.
+.SH "BUGS"
+.IX Header "BUGS"
+If you feel you have found a bug in sudo, please submit a bug report
+at http://www.sudo.ws/sudo/bugs/
+.SH "DISCLAIMER"
+.IX Header "DISCLAIMER"
+\&\fBSudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties,
+including, but not limited to, the implied warranties of merchantability
+and fitness for a particular purpose are disclaimed.
+See the \s-1LICENSE\s0 file distributed with \fBsudo\fR for complete details.
+.SH "CAVEATS"
+.IX Header "CAVEATS"
+There is no easy way to prevent a user from gaining a root shell if
+that user has access to commands allowing shell escapes.
+.PP
+If users have sudo \f(CW\*(C`ALL\*(C'\fR there is nothing to prevent them from creating
+their own program that gives them a root shell regardless of any '!'
+elements in the user specification.
+.PP
+Running shell scripts via \fBsudo\fR can expose the same kernel bugs
+that make setuid shell scripts unsafe on some operating systems
+(if your \s-1OS\s0 supports the /dev/fd/ directory, setuid shell scripts
+are generally safe).
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIstat\fR\|(2), \fIlogin_cap\fR\|(3), \fIsudoers\fR\|(@mansectform@), \fIpasswd\fR\|(5), \fIvisudo\fR\|(@mansectsu@), \fIgrep\fR\|(1), \fIsu\fR\|(1).
diff --git a/sudo.pod b/sudo.pod
new file mode 100644 (file)
index 0000000..2a05698
--- /dev/null
+++ b/sudo.pod
@@ -0,0 +1,376 @@
+=cut
+Copyright (c) 1994-1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission
+   from the author.
+
+4. Products derived from this software may not be called "Sudo" nor
+   may "Sudo" appear in their names without specific prior written
+   permission from the author.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$Sudo: sudo.pod,v 1.51 2002/01/12 22:55:01 millert Exp $
+=pod
+
+=head1 NAME
+
+sudo - execute a command as another user
+
+=head1 SYNOPSIS
+
+B<sudo> B<-V> | B<-h> | B<-l> | B<-L> | B<-v> | B<-k> | B<-K> | B<-s> |
+[ B<-H> ] [B<-P> ] [B<-S> ] [ B<-b> ] | [ B<-p> I<prompt> ]
+[ B<-c> I<class>|I<-> ] [ B<-a> I<auth_type> ]
+[ B<-u> I<username>|I<#uid> ] I<command>
+
+=head1 DESCRIPTION
+
+B<sudo> allows a permitted user to execute a I<command> as the
+superuser or another user, as specified in the I<sudoers> file.
+The real and effective uid and gid are set to match those of the
+target user as specified in the passwd file (the group vector is
+also initialized when the target user is not root).  By default,
+B<sudo> requires that users authenticate themselves with a password
+(NOTE: by default this is the user's password, not the root password).
+Once a user has been authenticated, a timestamp is updated and the
+user may then use sudo without a password for a short period of
+time (C<@timeout@> minutes unless overridden in I<sudoers>).
+
+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>).
+
+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 the I<sudoers> file (defaults to root).
+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 users to
+determine for themselves whether or not they are allowed to use
+B<sudo>.
+
+B<sudo> can log both successful and unsuccessful attempts (as well
+as errors) to syslog(3), a log file, or both.  By default B<sudo>
+will log via syslog(3) but this is changeable at configure time
+or via the I<sudoers> file.
+
+=head1 OPTIONS
+
+B<sudo> accepts the following command line options:
+
+=over 4
+
+=item -V
+
+The B<-V> (I<version>) option causes B<sudo> to print the
+version number and exit.  If the invoking user is already root
+the B<-V> option will print out a list of the defaults B<sudo>
+was compiled with as well as the machine's local network addresses.
+
+=item -l
+
+The B<-l> (I<list>) option will list out the allowed (and
+forbidden) commands for the user on the current host.
+
+=item -L
+
+The B<-L> (I<list> defaults) option will list out the parameters
+that may be set in a I<Defaults> line along with a short description
+for each.  This option is useful in conjunction with grep(1).
+
+=item -h
+
+The B<-h> (I<help>) option causes B<sudo> to print a usage message and exit.
+
+=item -v
+
+If given the B<-v> (I<validate>) option, B<sudo> will update the
+user's timestamp, prompting for the user's password if necessary.
+This extends the B<sudo> timeout for another C<@timeout@> minutes
+(or whatever the timeout is set to in I<sudoers>) but does not run
+a command.
+
+=item -k
+
+The B<-k> (I<kill>) option to B<sudo> invalidates the user's timestamp
+by setting the time on it to the epoch.  The next time B<sudo> is
+run a password will be required.  This option does not require a password
+and was added to allow a user to revoke B<sudo> permissions from a .logout
+file.
+
+=item -K
+
+The B<-K> (sure I<kill>) option to B<sudo> removes the user's timestamp
+entirely.  Likewise, this option does not require a password.
+
+=item -b
+
+The B<-b> (I<background>) option tells B<sudo> to run the given
+command in the background.  Note that if you use the B<-b>
+option you cannot use shell job control to manipulate the process.
+
+=item -p
+
+The B<-p> (I<prompt>) option allows you to override the default
+password prompt and use a custom one.  If the password prompt
+contains the C<%u> escape, C<%u> will be replaced with the user's
+login name.  Similarly, C<%h> will be replaced with the local
+hostname.
+
+=item -c
+
+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 /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>
+argument specifies an existing user class, the command must be run
+as root, or the B<sudo> command must be run from a shell that is already
+root.  This option is only available on systems with BSD login classes
+where B<sudo> has been configured with the --with-logincap option.
+
+=item -a
+
+The B<-a> (I<authentication type>) option causes B<sudo> to use the
+specified authentication type when validating the user, as allowed
+by /etc/login.conf.  The system administrator may specify a list
+of sudo-specific authentication methods by adding an "auth-sudo"
+entry in /etc/login.conf.  This option is only available on systems
+that support BSD authentication where B<sudo> has been configured
+with the --with-bsdauth option.
+
+=item -u
+
+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>.
+
+=item -s
+
+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 passwd(5).
+
+=item -H
+
+The B<-H> (I<HOME>) option sets the C<HOME> environment variable
+to the homedir of the target user (root by default) as specified
+in passwd(5).  By default, B<sudo> does not modify C<HOME>.
+
+=item -P
+
+The B<-P> (I<preserve group vector>) option causes B<sudo> to preserve
+the user's group vector unaltered.  By default, B<sudo> 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.
+
+=item -S
+
+The B<-S> (I<stdin>) option causes B<sudo> to read the password from
+standard input instead of the terminal device.
+
+=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.
+
+=back
+
+=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.
+
+Otherwise, B<sudo> quits with an exit value of 1 if there is a
+configuration/permission problem or if B<sudo> cannot execute the
+given command.  In the latter case the error string is printed to
+stderr.  If B<sudo> cannot stat(2) one or more entries in the user's
+C<PATH> an error is printed on stderr.  (If the directory does not
+exist or if it is not really a directory, the entry is ignored and
+no error is printed.)  This should not happen under normal
+circumstances.  The most common reason for stat(2) to return
+"permission denied" is if you are running an automounter and one
+of the directories in your C<PATH> is on a machine that is currently
+unreachable.
+
+=head1 SECURITY NOTES
+
+B<sudo> tries to be safe when executing external commands.  Variables
+that control how dynamic loading and binding is done can be used
+to subvert the program that B<sudo> runs.  To combat this the
+C<LD_*>, C<_RLD_*>, C<SHLIB_PATH> (HP-UX only), and C<LIBPATH> (AIX
+only) environment variables are removed from the environment passed
+on to all commands executed.  B<sudo> will also remove the C<IFS>,
+C<ENV>, C<BASH_ENV>, C<KRB_CONF>, C<KRBCONFDIR>, C<KRBTKFILE>,
+C<KRB5_CONFIG>, C<LOCALDOMAIN>, C<RES_OPTIONS>, C<HOSTALIASES>,
+C<NLSPATH>, C<PATH_LOCALE>, C<TERMINFO>, C<TERMINFO_DIRS> and
+C<TERMPATH> variables as they too can pose a threat.  If the
+C<TERMCAP> variable is set and is a pathname, it too is ignored.
+Additionally, if the C<LC_*> or C<LANGUAGE> variables contain the
+C</> or C<%> characters, they are ignored.  If B<sudo> has been
+compiled with SecurID support, the C<VAR_ACE>, C<USR_ACE> and
+C<DLC_ACE> variables are cleared as well.  The list of environment
+variables that B<sudo> clears is contained in the output of
+C<sudo -V> when run as root.
+
+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.
+
+For security reasons, if your OS supports shared libraries and does
+not disable user-defined library search paths for setuid programs
+(most do), you should either use a linker option that disables this
+behavior or link B<sudo> statically.
+
+B<sudo> will check the ownership of its timestamp directory
+(F<@timedir@> by default) and ignore the directory's contents if
+it is not owned by root and only writable by root.  On systems that
+allow non-root users to give away files via chown(2), if the timestamp
+directory is located in a directory writable by anyone (e.g.: F</tmp>),
+it is possible for a user to create the timestamp directory before
+B<sudo> is run.  However, because B<sudo> checks the ownership and
+mode of the directory and its contents, the only damage that can
+be done is to "hide" files by putting them in the timestamp dir.
+This is unlikely to happen since once the timestamp dir is owned
+by root and inaccessible by any other user the user placing files
+there would be unable to get them back out.  To get around this
+issue you can use a directory that is not world-writable for the
+timestamps (F</var/adm/sudo> for instance) or create F<@timedir@>
+with the appropriate owner (root) and permissions (0700) in the
+system startup files.
+
+B<sudo> will not honor timestamps set far in the future.
+Timestamps with a date greater than current_time + 2 * C<TIMEOUT>
+will be ignored and sudo will log and complain.  This is done to
+keep a user from creating his/her own timestamp with a bogus
+date on systems that allow users to give away files.
+
+Please note that B<sudo> will only log the command it explicitly
+runs.  If a user runs a command such as C<sudo su> or C<sudo sh>,
+subsequent commands run from that shell will I<not> be logged, nor
+will B<sudo>'s access control affect them.  The same is true for
+commands that offer shell escapes (including most editors).  Because
+of this, care must be taken when giving users access to commands
+via B<sudo> to verify that the command does not inadvertantly give
+the user an effective root shell.
+
+=head1 EXAMPLES
+
+Note: the following examples assume suitable sudoers(5) entries.
+
+To get a file listing of an unreadable directory:
+
+ % sudo ls /usr/local/protected
+
+To list the home directory of user yazza on a machine where the
+filesystem holding ~yazza is not exported as root:
+
+ % sudo -u yazza ls ~yazza
+
+To edit the F<index.html> file as user www:
+
+ % sudo -u www vi ~www/htdocs/index.html
+
+To shutdown a machine:
+
+ % sudo shutdown -r +15 "quick reboot"
+
+To make a usage listing of the directories in the /home
+partition.  Note that this runs the commands in a sub-shell
+to make the C<cd> and file redirection work.
+
+ % sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+
+=head1 ENVIRONMENT
+
+B<sudo> utilizes the following environment variables:
+
+ PATH                  Set to a sane value if SECURE_PATH is set
+ SHELL                 Used to determine shell to run with -s option
+ USER                  Set to the target user (root unless the -u option
+                       is specified)
+ HOME                  In -s or -H mode (or if sudo was configured with
+                       the --enable-shell-sets-home option), set to
+                       homedir of the target user.
+ SUDO_PROMPT           Used as the default password prompt
+ SUDO_COMMAND          Set to the command run by sudo
+ SUDO_USER             Set to the login of the user who invoked sudo
+ SUDO_UID              Set to the uid of the user who invoked sudo
+ SUDO_GID              Set to the gid of the user who invoked sudo
+ SUDO_PS1              If set, PS1 will be set to its value
+
+=head1 FILES
+
+ @sysconfdir@/sudoers          List of who can run what
+ @timedir@             Directory containing timestamps
+
+=head1 AUTHORS
+
+Many people have worked on B<sudo> over the years; this
+version consists of code written primarily by:
+
+       Todd 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
+of B<sudo>.
+
+=head1 BUGS
+
+If you feel you have found a bug in sudo, please submit a bug report
+at http://www.sudo.ws/sudo/bugs/
+
+=head1 DISCLAIMER
+
+B<Sudo> is provided ``AS IS'' and any express or implied warranties,
+including, but not limited to, the implied warranties of merchantability
+and fitness for a particular purpose are disclaimed.
+See the LICENSE file distributed with B<sudo> for complete details.
+
+=head1 CAVEATS
+
+There is no easy way to prevent a user from gaining a root shell if
+that user has access to commands allowing shell escapes.
+
+If users have sudo C<ALL> there is nothing to prevent them from creating
+their own program that gives them a root shell regardless of any '!'
+elements in the user specification.
+
+Running shell scripts via B<sudo> can expose the same kernel bugs
+that make setuid shell scripts unsafe on some operating systems
+(if your OS supports the /dev/fd/ directory, setuid shell scripts
+are generally safe).
+
+=head1 SEE ALSO
+
+stat(2), login_cap(3), sudoers(5), passwd(5), visudo(8), grep(1), su(1).
diff --git a/sudo.tab.c b/sudo.tab.c
new file mode 100644 (file)
index 0000000..db81c13
--- /dev/null
@@ -0,0 +1,1898 @@
+#ifndef lint
+/*static char yysccsid[] = "from: @(#)yaccpar  1.9 (Berkeley) 02/21/93";*/
+static char yyrcsid[]
+#if __GNUC__ == 2
+  __attribute__ ((unused))
+#endif /* __GNUC__ == 2 */
+  = "$OpenBSD: skeleton.c,v 1.18 2001/11/19 19:02:18 mpech Exp $";
+#endif
+#include <stdlib.h>
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYLEX yylex()
+#define YYEMPTY -1
+#define yyclearin (yychar=(YYEMPTY))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING() (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 2 "parse.yacc"
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * XXX - the whole opFOO naming thing is somewhat bogus.
+ *
+ * XXX - the way things are stored for printmatches is stupid,
+ *       they should be stored as elements in an array and then
+ *       list_matches() can format things the way it wants.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+# include <alloca.h>
+#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
+#ifdef HAVE_LSEARCH
+# include <search.h>
+#endif /* HAVE_LSEARCH */
+
+#include "sudo.h"
+#include "parse.h"
+
+#ifndef HAVE_LSEARCH
+#include "emul/search.h"
+#endif /* HAVE_LSEARCH */
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.58 2002/03/16 00:45:48 millert Exp $";
+#endif /* lint */
+
+/*
+ * Globals
+ */
+extern int sudolineno, parse_error;
+int errorlineno = -1;
+int clearaliases = TRUE;
+int printmatches = FALSE;
+int pedantic = FALSE;
+int keepall = FALSE;
+int quiet = FALSE;
+
+/*
+ * Alias types
+ */
+#define HOST_ALIAS              1
+#define CMND_ALIAS              2
+#define USER_ALIAS              3
+#define RUNAS_ALIAS             4
+
+/*
+ * The matching stack, initial space allocated in init_parser().
+ */
+struct matchstack *match;
+int top = 0, stacksize = 0;
+
+#define push \
+    do { \
+       if (top >= stacksize) { \
+           while ((stacksize += STACKINCREMENT) < top); \
+           match = (struct matchstack *) erealloc(match, sizeof(struct matchstack) * stacksize); \
+       } \
+       match[top].user   = -1; \
+       match[top].cmnd   = -1; \
+       match[top].host   = -1; \
+       match[top].runas  = -1; \
+       match[top].nopass = def_flag(I_AUTHENTICATE) ? -1 : TRUE; \
+       top++; \
+    } while (0)
+
+#define pushcp \
+    do { \
+       if (top >= stacksize) { \
+           while ((stacksize += STACKINCREMENT) < top); \
+           match = (struct matchstack *) erealloc(match, sizeof(struct matchstack) * stacksize); \
+       } \
+       match[top].user   = match[top-1].user; \
+       match[top].cmnd   = match[top-1].cmnd; \
+       match[top].host   = match[top-1].host; \
+       match[top].runas  = match[top-1].runas; \
+       match[top].nopass = match[top-1].nopass; \
+       top++; \
+    } while (0)
+
+#define pop \
+    { \
+       if (top == 0) \
+           yyerror("matching stack underflow"); \
+       else \
+           top--; \
+    }
+
+/*
+ * Shortcuts for append()
+ */
+#define append_cmnd(s, p) append(s, &cm_list[cm_list_len].cmnd, \
+       &cm_list[cm_list_len].cmnd_len, &cm_list[cm_list_len].cmnd_size, p)
+
+#define append_runas(s, p) append(s, &cm_list[cm_list_len].runas, \
+       &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, p)
+
+#define append_entries(s, p) append(s, &ga_list[ga_list_len-1].entries, \
+       &ga_list[ga_list_len-1].entries_len, \
+       &ga_list[ga_list_len-1].entries_size, p)
+
+/*
+ * The stack for printmatches.  A list of allowed commands for the user.
+ */
+static struct command_match *cm_list = NULL;
+static size_t cm_list_len = 0, cm_list_size = 0;
+
+/*
+ * List of Cmnd_Aliases and expansions for `sudo -l'
+ */
+static int in_alias = FALSE;
+static size_t ga_list_len = 0, ga_list_size = 0;
+static struct generic_alias *ga_list = NULL;
+
+/*
+ * Does this Defaults list pertain to this user?
+ */
+static int defaults_matches = 0;
+
+/*
+ * Local protoypes
+ */
+static int  add_alias          __P((char *, int, int));
+static void append             __P((char *, char **, size_t *, size_t *, char *));
+static void expand_ga_list     __P((void));
+static void expand_match_list  __P((void));
+static aliasinfo *find_alias   __P((char *, int));
+static int  more_aliases       __P((void));
+       void init_parser                __P((void));
+       void yyerror            __P((char *));
+
+void
+yyerror(s)
+    char *s;
+{
+    /* Save the line the first error occurred on. */
+    if (errorlineno == -1)
+       errorlineno = sudolineno ? sudolineno - 1 : 0;
+    if (s && !quiet) {
+#ifndef TRACELEXER
+       (void) fprintf(stderr, ">>> sudoers file: %s, line %d <<<\n", s,
+           sudolineno ? sudolineno - 1 : 0);
+#else
+       (void) fprintf(stderr, "<*> ");
+#endif
+    }
+    parse_error = TRUE;
+}
+#line 214 "parse.yacc"
+typedef union {
+    char *string;
+    int BOOLEAN;
+    struct sudo_command command;
+    int tok;
+} YYSTYPE;
+#line 238 "sudo.tab.c"
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DEFAULTS 264
+#define DEFAULTS_HOST 265
+#define DEFAULTS_USER 266
+#define RUNAS 267
+#define NOPASSWD 268
+#define PASSWD 269
+#define ALL 270
+#define COMMENT 271
+#define HOSTALIAS 272
+#define CMNDALIAS 273
+#define USERALIAS 274
+#define RUNASALIAS 275
+#define ERROR 276
+#define YYERRCODE 256
+short yylhs[] = {                                        -1,
+    0,    0,    7,    7,    9,    7,    7,    7,    7,    7,
+    7,   15,   16,   18,   16,   20,   16,   17,   17,   21,
+   21,   21,   21,   21,   10,   10,   22,   24,   24,    2,
+    2,    2,    2,    2,   23,   23,   25,   28,   29,   28,
+   26,   26,    5,    5,    4,   30,    4,    3,    3,    3,
+    3,    3,   27,   27,   27,    1,    1,    1,   12,   12,
+   32,   31,   19,   19,   13,   13,   34,   33,   35,   35,
+   14,   14,   37,   36,   11,   11,   39,   38,    8,    8,
+   40,   40,    6,    6,    6,    6,    6,
+};
+short yylen[] = {                                         2,
+    1,    2,    1,    2,    0,    3,    2,    2,    2,    2,
+    1,    2,    1,    0,    3,    0,    3,    1,    3,    1,
+    2,    3,    3,    3,    1,    3,    3,    1,    2,    1,
+    1,    1,    1,    1,    1,    3,    3,    1,    0,    3,
+    0,    2,    1,    3,    1,    0,    3,    1,    1,    1,
+    1,    1,    0,    1,    1,    1,    1,    1,    1,    3,
+    0,    4,    1,    3,    1,    3,    0,    4,    1,    3,
+    1,    3,    0,    4,    1,    3,    0,    4,    1,    3,
+    1,    2,    1,    1,    1,    1,    1,
+};
+short yydefred[] = {                                      0,
+    0,   13,   16,   14,    3,    0,    0,    0,    0,    0,
+    1,    0,   11,    0,    4,    0,    0,   61,    0,   59,
+   67,    0,   65,   77,    0,   75,   73,    0,   71,    2,
+   86,   85,   84,   83,   87,    0,   81,    0,   79,    0,
+    0,   12,    0,   34,   31,   32,   33,   30,    0,   28,
+    0,   63,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   82,    0,    0,    0,   25,    0,    0,    0,   21,
+    0,   29,    0,    0,   60,    0,   66,    0,   76,    0,
+   72,   80,    0,    0,   22,   23,   24,   19,   64,    0,
+   58,   57,   56,   39,   38,   69,    0,    0,   51,   50,
+   49,   48,   52,   46,   45,   43,    0,   26,    0,    0,
+   35,    0,    0,    0,    0,    0,    0,    0,   54,   55,
+    0,   40,   70,   47,   44,   36,   37,
+};
+short yydgoto[] = {                                      10,
+   95,   50,  105,  106,  107,   37,   11,   38,   12,   64,
+   25,   19,   22,   28,   13,   14,   42,   17,   65,   16,
+   43,   66,  110,   52,  111,  112,  121,   96,  113,  115,
+   20,   54,   23,   56,   97,   29,   60,   26,   58,   39,
+};
+short yysindex[] = {                                   -236,
+ -264,    0,    0,    0,    0, -249, -243, -231, -227, -236,
+    0,  -23,    0,  -30,    0,  -17,  -23,    0,  -36,    0,
+    0,  -26,    0,    0,  -14,    0,    0,   -7,    0,    0,
+    0,    0,    0,    0,    0, -215,    0,  -33,    0,   -3,
+ -226,    0,    5,    0,    0,    0,    0,    0, -194,    0,
+    6,    0,    8,   -5, -249,   -4, -243,   -2, -231,   -1,
+ -227,    0,  -23,    7,  -38,    0, -210, -193, -188,    0,
+  -30,    0,  -17,  -17,    0,  -25,    0,  -23,    0,  245,
+    0,    0,  -17, -189,    0,    0,    0,    0,    0,    6,
+    0,    0,    0,    0,    0,    0,   33,    8,    0,    0,
+    0,    0,    0,    0,    0,    0,   38,    0,  245,   39,
+    0, -251, -244,  -25, -190,  245,   38, -189,    0,    0,
+  -25,    0,    0,    0,    0,    0,    0,
+};
+short yyrindex[] = {                                    255,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  255,
+    0,    0,    0,    0,    0,    0,    0,    0,  121,    0,
+    0,  141,    0,    0,  161,    0,    0,  181,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
+    0,    0,  201,    0,    0,    0,    0,    0,    0,    0,
+  -28,    0,   -8,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  221,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  265,    0,    0,    0,    0,    0,   21,
+    0,    0,    0,    0,    0,    0,   41,   61,    0,    0,
+    0,    0,    0,    0,    0,    0,   81,    0,    0,  101,
+    0,   -9,    0,    0,    0,    0,  285,  265,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,
+};
+short yygindex[] = {                                      0,
+  -29,   36,  -27,  -24,  -22,   50,   79,  -15,    0,    0,
+    0,    0,    0,    0,    0,    0,   19,    0,  -12,    0,
+    0,   10,    0,   18,  -21,    0,    0, -102,    0,    0,
+   40,    0,   43,    0,    0,   35,    0,   44,    0,   42,
+};
+#define YYTABLESIZE 555
+short yytable[] = {                                      49,
+   20,   53,   41,   51,   17,   73,   15,   94,   18,   36,
+   63,  123,   91,   92,   21,   49,  119,  120,  127,    1,
+   62,   55,   84,   53,   15,   93,   24,    2,    3,    4,
+   27,   57,   70,   20,    5,    6,    7,    8,    9,   68,
+   68,   69,   31,   59,   20,   32,   33,   34,   71,   73,
+   61,   63,   85,   62,   35,   74,   76,   67,   78,   80,
+   78,   90,   98,   44,   83,   45,   46,   99,   47,   86,
+  100,  101,  102,   68,   87,   48,  114,  109,   62,  103,
+   74,  116,  118,  122,   72,   62,  117,  124,   30,   88,
+   89,  125,  108,   78,   75,   81,  126,    0,   68,   77,
+   27,    0,   79,    0,   82,    0,    0,    0,    0,    0,
+    0,    0,    0,   74,    0,    0,    0,    0,   78,    0,
+    8,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   27,    0,    0,    0,    0,   74,    0,
+    9,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    8,    0,    0,    0,    0,   27,    0,
+    7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    9,    0,    0,    0,    0,    0,    0,
+   10,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    7,    0,    0,    0,    0,    0,    0,
+   18,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   10,    0,    0,    0,    0,    0,    0,
+    6,    0,    0,    0,   44,    0,   45,   46,   40,   47,
+   17,   91,   92,   18,   31,    0,   48,   32,   33,   34,
+   44,    0,   45,   46,   93,   47,   35,   53,   53,    0,
+   15,    0,   48,    6,    0,    0,   20,    0,   20,    0,
+   53,   20,   20,   20,   20,   20,   20,    0,    0,    0,
+   20,   20,   20,   20,   20,   20,   62,  104,   62,    0,
+    0,   62,   62,   62,   62,   62,   62,    5,    0,    0,
+   62,   62,   62,   62,   62,   62,   68,   41,   68,    0,
+    0,   68,   68,   68,   68,   68,   68,    0,    0,    0,
+   68,   68,   68,   68,   68,   68,   78,   42,   78,    0,
+    0,   78,   78,   78,   78,   78,   78,    0,    0,    0,
+   78,   78,   78,   78,   78,   78,   74,    0,   74,    0,
+    0,   74,   74,   74,   74,   74,   74,    0,    0,    0,
+   74,   74,   74,   74,   74,   74,   27,    0,   27,    0,
+    0,   27,   27,   27,   27,   27,   27,    0,    0,    0,
+   27,   27,   27,   27,   27,   27,    8,    0,    8,    0,
+    0,    8,    8,    8,    8,    8,    8,    0,    0,    0,
+    8,    8,    8,    8,    8,    8,    9,    0,    9,    0,
+    0,    9,    9,    9,    9,    9,    9,    0,    0,    0,
+    9,    9,    9,    9,    9,    9,    7,    0,    7,    0,
+    0,    7,    7,    7,    7,    7,    7,    0,    0,    0,
+    7,    7,    7,    7,    7,    7,   10,    0,   10,    0,
+    0,   10,   10,   10,   10,   10,   10,    0,    0,    0,
+   10,   10,   10,   10,   10,   10,   18,    0,   18,    0,
+    0,   18,   18,   18,   18,   18,   18,    0,    0,    0,
+   18,   18,   18,   18,   18,   18,    6,    0,    6,    0,
+    0,    6,    6,    6,    6,    6,    6,    0,    0,    0,
+    6,    6,    6,    6,    6,    6,    0,    0,    0,    0,
+    0,    0,   99,    0,    0,  100,  101,  102,    0,    0,
+    0,    0,    5,    0,  103,    5,    5,    5,    0,    0,
+    0,   41,   41,    0,    5,    0,    0,    0,    0,    0,
+    0,    0,   41,   41,   41,    0,    0,    0,    0,    0,
+    0,   42,   42,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   42,   42,   42,
+};
+short yycheck[] = {                                      33,
+    0,   17,   33,   16,   33,   44,  271,   33,  258,   33,
+   44,  114,  257,  258,  258,   33,  268,  269,  121,  256,
+    0,   58,   61,   33,   33,  270,  258,  264,  265,  266,
+  258,   58,  259,   33,  271,  272,  273,  274,  275,   43,
+    0,   45,  258,   58,   44,  261,  262,  263,   44,   44,
+   58,   44,  263,   33,  270,   61,   61,   61,   61,   61,
+    0,   74,   78,  258,   58,  260,  261,  258,  263,  263,
+  261,  262,  263,   33,  263,  270,   44,  267,   58,  270,
+    0,   44,   44,  113,   49,   36,  109,  115,   10,   71,
+   73,  116,   83,   33,   55,   61,  118,   -1,   58,   57,
+    0,   -1,   59,   -1,   63,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,  258,   -1,  260,  261,  259,  263,
+  259,  257,  258,   33,  258,   -1,  270,  261,  262,  263,
+  258,   -1,  260,  261,  270,  263,  270,  257,  258,   -1,
+  259,   -1,  270,   33,   -1,   -1,  256,   -1,  258,   -1,
+  270,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   33,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
+   -1,   -1,  258,   -1,   -1,  261,  262,  263,   -1,   -1,
+   -1,   -1,  258,   -1,  270,  261,  262,  263,   -1,   -1,
+   -1,  257,  258,   -1,  270,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  268,  269,  270,   -1,   -1,   -1,   -1,   -1,
+   -1,  257,  258,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  268,  269,  270,
+};
+#define YYFINAL 10
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 276
+#if YYDEBUG
+#if defined(__cplusplus) || __STDC__
+const char * const yyname[] =
+#else
+char *yyname[] =
+#endif
+       {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'!'",0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,
+"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
+"DEFAULTS_HOST","DEFAULTS_USER","RUNAS","NOPASSWD","PASSWD","ALL","COMMENT",
+"HOSTALIAS","CMNDALIAS","USERALIAS","RUNASALIAS","ERROR",
+};
+#if defined(__cplusplus) || __STDC__
+const char * const yyrule[] =
+#else
+char *yyrule[] =
+#endif
+       {"$accept : file",
+"file : entry",
+"file : file entry",
+"entry : COMMENT",
+"entry : error COMMENT",
+"$$1 :",
+"entry : $$1 userlist privileges",
+"entry : USERALIAS useraliases",
+"entry : HOSTALIAS hostaliases",
+"entry : CMNDALIAS cmndaliases",
+"entry : RUNASALIAS runasaliases",
+"entry : defaults_line",
+"defaults_line : defaults_type defaults_list",
+"defaults_type : DEFAULTS",
+"$$2 :",
+"defaults_type : DEFAULTS_USER $$2 userlist",
+"$$3 :",
+"defaults_type : DEFAULTS_HOST $$3 hostlist",
+"defaults_list : defaults_entry",
+"defaults_list : defaults_entry ',' defaults_list",
+"defaults_entry : DEFVAR",
+"defaults_entry : '!' DEFVAR",
+"defaults_entry : DEFVAR '=' WORD",
+"defaults_entry : DEFVAR '+' WORD",
+"defaults_entry : DEFVAR '-' WORD",
+"privileges : privilege",
+"privileges : privileges ':' privilege",
+"privilege : hostlist '=' cmndspeclist",
+"ophost : host",
+"ophost : '!' host",
+"host : ALL",
+"host : NTWKADDR",
+"host : NETGROUP",
+"host : WORD",
+"host : ALIAS",
+"cmndspeclist : cmndspec",
+"cmndspeclist : cmndspeclist ',' cmndspec",
+"cmndspec : runasspec nopasswd opcmnd",
+"opcmnd : cmnd",
+"$$4 :",
+"opcmnd : '!' $$4 cmnd",
+"runasspec :",
+"runasspec : RUNAS runaslist",
+"runaslist : oprunasuser",
+"runaslist : runaslist ',' oprunasuser",
+"oprunasuser : runasuser",
+"$$5 :",
+"oprunasuser : '!' $$5 runasuser",
+"runasuser : WORD",
+"runasuser : USERGROUP",
+"runasuser : NETGROUP",
+"runasuser : ALIAS",
+"runasuser : ALL",
+"nopasswd :",
+"nopasswd : NOPASSWD",
+"nopasswd : PASSWD",
+"cmnd : ALL",
+"cmnd : ALIAS",
+"cmnd : COMMAND",
+"hostaliases : hostalias",
+"hostaliases : hostaliases ':' hostalias",
+"$$6 :",
+"hostalias : ALIAS $$6 '=' hostlist",
+"hostlist : ophost",
+"hostlist : hostlist ',' ophost",
+"cmndaliases : cmndalias",
+"cmndaliases : cmndaliases ':' cmndalias",
+"$$7 :",
+"cmndalias : ALIAS $$7 '=' cmndlist",
+"cmndlist : opcmnd",
+"cmndlist : cmndlist ',' opcmnd",
+"runasaliases : runasalias",
+"runasaliases : runasaliases ':' runasalias",
+"$$8 :",
+"runasalias : ALIAS $$8 '=' runaslist",
+"useraliases : useralias",
+"useraliases : useraliases ':' useralias",
+"$$9 :",
+"useralias : ALIAS $$9 '=' userlist",
+"userlist : opuser",
+"userlist : userlist ',' opuser",
+"opuser : user",
+"opuser : '!' user",
+"user : WORD",
+"user : USERGROUP",
+"user : NETGROUP",
+"user : ALIAS",
+"user : ALL",
+};
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+#define YYINITSTACKSIZE 200
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short *yyss;
+short *yysslim;
+YYSTYPE *yyvs;
+int yystacksize;
+#line 844 "parse.yacc"
+
+#define MOREALIASES (32)
+aliasinfo *aliases = NULL;
+size_t naliases = 0;
+size_t nslots = 0;
+
+
+/*
+ * Compare two aliasinfo structures, strcmp() style.
+ * Note that we do *not* compare their values.
+ */
+static int
+aliascmp(a1, a2)
+    const VOID *a1, *a2;
+{
+    int r;
+    aliasinfo *ai1, *ai2;
+
+    ai1 = (aliasinfo *) a1;
+    ai2 = (aliasinfo *) a2;
+    if ((r = strcmp(ai1->name, ai2->name)) == 0)
+       r = ai1->type - ai2->type;
+
+    return(r);
+}
+
+/*
+ * Compare two generic_alias structures, strcmp() style.
+ */
+static int
+genaliascmp(entry, key)
+    const VOID *entry, *key;
+{
+    int r;
+    struct generic_alias *ga1, *ga2;
+
+    ga1 = (struct generic_alias *) key;
+    ga2 = (struct generic_alias *) entry;
+    if ((r = strcmp(ga1->alias, ga2->alias)) == 0)
+       r = ga1->type - ga2->type;
+
+    return(r);
+}
+
+
+/*
+ * Adds the named alias of the specified type to the aliases list.
+ */
+static int
+add_alias(alias, type, val)
+    char *alias;
+    int type;
+    int val;
+{
+    aliasinfo ai, *aip;
+    size_t onaliases;
+    char s[512];
+
+    if (naliases >= nslots && !more_aliases()) {
+       (void) snprintf(s, sizeof(s), "Out of memory defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
+
+    ai.type = type;
+    ai.val = val;
+    ai.name = estrdup(alias);
+    onaliases = naliases;
+
+    aip = (aliasinfo *) lsearch((VOID *)&ai, (VOID *)aliases, &naliases,
+                               sizeof(ai), aliascmp);
+    if (aip == NULL) {
+       (void) snprintf(s, sizeof(s), "Aliases corrupted defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
+    if (onaliases == naliases) {
+       (void) snprintf(s, sizeof(s), "Alias `%s' already defined", alias);
+       yyerror(s);
+       return(FALSE);
+    }
+
+    return(TRUE);
+}
+
+/*
+ * Searches for the named alias of the specified type.
+ */
+static aliasinfo *
+find_alias(alias, type)
+    char *alias;
+    int type;
+{
+    aliasinfo ai;
+
+    ai.name = alias;
+    ai.type = type;
+
+    return((aliasinfo *) lfind((VOID *)&ai, (VOID *)aliases, &naliases,
+                sizeof(ai), aliascmp));
+}
+
+/*
+ * Allocates more space for the aliases list.
+ */
+static int
+more_aliases()
+{
+
+    nslots += MOREALIASES;
+    if (nslots == MOREALIASES)
+       aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
+    else
+       aliases = (aliasinfo *) realloc(aliases, nslots * sizeof(aliasinfo));
+
+    return(aliases != NULL);
+}
+
+/*
+ * Lists the contents of the aliases list.
+ */
+void
+dumpaliases()
+{
+    size_t n;
+
+    for (n = 0; n < naliases; n++) {
+       if (aliases[n].val == -1)
+           continue;
+
+       switch (aliases[n].type) {
+       case HOST_ALIAS:
+           (void) puts("HOST_ALIAS");
+           break;
+
+       case CMND_ALIAS:
+           (void) puts("CMND_ALIAS");
+           break;
+
+       case USER_ALIAS:
+           (void) puts("USER_ALIAS");
+           break;
+
+       case RUNAS_ALIAS:
+           (void) puts("RUNAS_ALIAS");
+           break;
+       }
+       (void) printf("\t%s: %d\n", aliases[n].name, aliases[n].val);
+    }
+}
+
+/*
+ * Lists the contents of cm_list and ga_list for `sudo -l'.
+ */
+void
+list_matches()
+{
+    int i; 
+    char *p;
+    struct generic_alias *ga, key;
+
+    (void) printf("User %s may run the following commands on this host:\n",
+       user_name);
+    for (i = 0; i < cm_list_len; i++) {
+
+       /* Print the runas list. */
+       (void) fputs("    ", stdout);
+       if (cm_list[i].runas) {
+           (void) putchar('(');
+           p = strtok(cm_list[i].runas, ", ");
+           do {
+               if (p != cm_list[i].runas)
+                   (void) fputs(", ", stdout);
+
+               key.alias = p;
+               key.type = RUNAS_ALIAS;
+               if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+                   (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+                   (void) fputs(ga->entries, stdout);
+               else
+                   (void) fputs(p, stdout);
+           } while ((p = strtok(NULL, ", ")));
+           (void) fputs(") ", stdout);
+       } else {
+           (void) printf("(%s) ", def_str(I_RUNAS_DEFAULT));
+       }
+
+       /* Is a password required? */
+       if (cm_list[i].nopasswd == TRUE && def_flag(I_AUTHENTICATE))
+           (void) fputs("NOPASSWD: ", stdout);
+       else if (cm_list[i].nopasswd == FALSE && !def_flag(I_AUTHENTICATE))
+           (void) fputs("PASSWD: ", stdout);
+
+       /* Print the actual command or expanded Cmnd_Alias. */
+       key.alias = cm_list[i].cmnd;
+       key.type = CMND_ALIAS;
+       if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+           (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+           (void) puts(ga->entries);
+       else
+           (void) puts(cm_list[i].cmnd);
+    }
+
+    /* Be nice and free up space now that we are done. */
+    for (i = 0; i < ga_list_len; i++) {
+       free(ga_list[i].alias);
+       free(ga_list[i].entries);
+    }
+    free(ga_list);
+    ga_list = NULL;
+
+    for (i = 0; i < cm_list_len; i++) {
+       free(cm_list[i].runas);
+       free(cm_list[i].cmnd);
+    }
+    free(cm_list);
+    cm_list = NULL;
+    cm_list_len = 0;
+    cm_list_size = 0;
+}
+
+/*
+ * Appends a source string to the destination, optionally prefixing a separator.
+ */
+static void
+append(src, dstp, dst_len, dst_size, separator)
+    char *src, **dstp;
+    size_t *dst_len, *dst_size;
+    char *separator;
+{
+    size_t src_len = strlen(src);
+    char *dst = *dstp;
+
+    /*
+     * Only add the separator if there is something to separate from.
+     * If the last char is a '!', don't apply the separator (XXX).
+     */
+    if (separator && dst && dst[*dst_len - 1] != '!')
+       src_len += strlen(separator);
+    else
+       separator = NULL;
+
+    /* Assumes dst will be NULL if not set. */
+    if (dst == NULL) {
+       dst = (char *) emalloc(BUFSIZ);
+       *dst_size = BUFSIZ;
+       *dst_len = 0;
+       *dstp = dst;
+    }
+
+    /* Allocate more space if necessary. */
+    if (*dst_size <= *dst_len + src_len) {
+       while (*dst_size <= *dst_len + src_len)
+           *dst_size += BUFSIZ;
+
+       dst = (char *) erealloc(dst, *dst_size);
+       *dstp = dst;
+    }
+
+    /* Copy src -> dst adding a separator if appropriate and adjust len. */
+    dst += *dst_len;
+    *dst_len += src_len;
+    *dst = '\0';
+    if (separator)
+       (void) strcat(dst, separator);
+    (void) strcat(dst, src);
+}
+
+/*
+ * Frees up space used by the aliases list and resets the associated counters.
+ */
+void
+reset_aliases()
+{
+    size_t n;
+
+    if (aliases) {
+       for (n = 0; n < naliases; n++)
+           free(aliases[n].name);
+       free(aliases);
+       aliases = NULL;
+    }
+    naliases = nslots = 0;
+}
+
+/*
+ * Increments ga_list_len, allocating more space as necessary.
+ */
+static void
+expand_ga_list()
+{
+
+    if (++ga_list_len >= ga_list_size) {
+       while ((ga_list_size += STACKINCREMENT) < ga_list_len)
+           ;
+       ga_list = (struct generic_alias *)
+           erealloc(ga_list, sizeof(struct generic_alias) * ga_list_size);
+    }
+
+    ga_list[ga_list_len - 1].entries = NULL;
+}
+
+/*
+ * Increments cm_list_len, allocating more space as necessary.
+ */
+static void
+expand_match_list()
+{
+
+    if (++cm_list_len >= cm_list_size) {
+       while ((cm_list_size += STACKINCREMENT) < cm_list_len)
+           ;
+       if (cm_list == NULL)
+           cm_list_len = 0;            /* start at 0 since it is a subscript */
+       cm_list = (struct command_match *)
+           erealloc(cm_list, sizeof(struct command_match) * cm_list_size);
+    }
+
+    cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
+    cm_list[cm_list_len].nopasswd = FALSE;
+}
+
+/*
+ * Frees up spaced used by a previous parser run and allocates new space
+ * for various data structures.
+ */
+void
+init_parser()
+{
+
+    /* Free up old data structures if we run the parser more than once. */
+    if (match) {
+       free(match);
+       match = NULL;
+       top = 0;
+       parse_error = FALSE;
+       errorlineno = -1;   
+       sudolineno = 1;     
+    }
+
+    /* Allocate space for the matching stack. */
+    stacksize = STACKINCREMENT;
+    match = (struct matchstack *) emalloc(sizeof(struct matchstack) * stacksize);
+
+    /* Allocate space for the match list (for `sudo -l'). */
+    if (printmatches == TRUE)
+       expand_match_list();
+}
+#line 940 "sudo.tab.c"
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+#if defined(__cplusplus) || __STDC__
+static int yygrowstack(void)
+#else
+static int yygrowstack()
+#endif
+{
+    int newsize, i;
+    short *newss;
+    YYSTYPE *newvs;
+
+    if ((newsize = yystacksize) == 0)
+        newsize = YYINITSTACKSIZE;
+    else if (newsize >= YYMAXDEPTH)
+        return -1;
+    else if ((newsize *= 2) > YYMAXDEPTH)
+        newsize = YYMAXDEPTH;
+    i = yyssp - yyss;
+    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
+      (short *)malloc(newsize * sizeof *newss);
+    if (newss == NULL)
+        goto bail;
+    yyss = newss;
+    yyssp = newss + i;
+    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
+      (YYSTYPE *)malloc(newsize * sizeof *newvs);
+    if (newvs == NULL)
+        goto bail;
+    yyvs = newvs;
+    yyvsp = newvs + i;
+    yystacksize = newsize;
+    yysslim = yyss + newsize - 1;
+    return 0;
+bail:
+    if (yyss)
+            free(yyss);
+    if (yyvs)
+            free(yyvs);
+    yyss = yyssp = NULL;
+    yyvs = yyvsp = NULL;
+    yystacksize = 0;
+    return -1;
+}
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+#if defined(__cplusplus) || __STDC__
+yyparse(void)
+#else
+yyparse()
+#endif
+{
+    int yym, yyn, yystate;
+#if YYDEBUG
+#if defined(__cplusplus) || __STDC__
+    const char *yys;
+#else /* !(defined(__cplusplus) || __STDC__) */
+    char *yys;
+#endif /* !(defined(__cplusplus) || __STDC__) */
+
+    if ((yys = getenv("YYDEBUG")))
+    {
+        yyn = *yys;
+        if (yyn >= '0' && yyn <= '9')
+            yydebug = yyn - '0';
+    }
+#endif /* YYDEBUG */
+
+    yynerrs = 0;
+    yyerrflag = 0;
+    yychar = (-1);
+
+    if (yyss == NULL && yygrowstack()) goto yyoverflow;
+    yyssp = yyss;
+    yyvsp = yyvs;
+    *yyssp = yystate = 0;
+
+yyloop:
+    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+    if (yychar < 0)
+    {
+        if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+        if (yydebug)
+        {
+            yys = 0;
+            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+            if (!yys) yys = "illegal-symbol";
+            printf("%sdebug: state %d, reading %d (%s)\n",
+                    YYPREFIX, yystate, yychar, yys);
+        }
+#endif
+    }
+    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+    {
+#if YYDEBUG
+        if (yydebug)
+            printf("%sdebug: state %d, shifting to state %d\n",
+                    YYPREFIX, yystate, yytable[yyn]);
+#endif
+        if (yyssp >= yysslim && yygrowstack())
+        {
+            goto yyoverflow;
+        }
+        *++yyssp = yystate = yytable[yyn];
+        *++yyvsp = yylval;
+        yychar = (-1);
+        if (yyerrflag > 0)  --yyerrflag;
+        goto yyloop;
+    }
+    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+    {
+        yyn = yytable[yyn];
+        goto yyreduce;
+    }
+    if (yyerrflag) goto yyinrecovery;
+#if defined(lint) || defined(__GNUC__)
+    goto yynewerror;
+#endif
+yynewerror:
+    yyerror("syntax error");
+#if defined(lint) || defined(__GNUC__)
+    goto yyerrlab;
+#endif
+yyerrlab:
+    ++yynerrs;
+yyinrecovery:
+    if (yyerrflag < 3)
+    {
+        yyerrflag = 3;
+        for (;;)
+        {
+            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+            {
+#if YYDEBUG
+                if (yydebug)
+                    printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+                if (yyssp >= yysslim && yygrowstack())
+                {
+                    goto yyoverflow;
+                }
+                *++yyssp = yystate = yytable[yyn];
+                *++yyvsp = yylval;
+                goto yyloop;
+            }
+            else
+            {
+#if YYDEBUG
+                if (yydebug)
+                    printf("%sdebug: error recovery discarding state %d\n",
+                            YYPREFIX, *yyssp);
+#endif
+                if (yyssp <= yyss) goto yyabort;
+                --yyssp;
+                --yyvsp;
+            }
+        }
+    }
+    else
+    {
+        if (yychar == 0) goto yyabort;
+#if YYDEBUG
+        if (yydebug)
+        {
+            yys = 0;
+            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+            if (!yys) yys = "illegal-symbol";
+            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+                    YYPREFIX, yystate, yychar, yys);
+        }
+#endif
+        yychar = (-1);
+        goto yyloop;
+    }
+yyreduce:
+#if YYDEBUG
+    if (yydebug)
+        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+                YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+    yym = yylen[yyn];
+    yyval = yyvsp[1-yym];
+    switch (yyn)
+    {
+case 3:
+#line 264 "parse.yacc"
+{ ; }
+break;
+case 4:
+#line 266 "parse.yacc"
+{ yyerrok; }
+break;
+case 5:
+#line 267 "parse.yacc"
+{ push; }
+break;
+case 6:
+#line 267 "parse.yacc"
+{
+                           while (top && user_matches != TRUE)
+                               pop;
+                       }
+break;
+case 7:
+#line 272 "parse.yacc"
+{ ; }
+break;
+case 8:
+#line 274 "parse.yacc"
+{ ; }
+break;
+case 9:
+#line 276 "parse.yacc"
+{ ; }
+break;
+case 10:
+#line 278 "parse.yacc"
+{ ; }
+break;
+case 11:
+#line 280 "parse.yacc"
+{ ; }
+break;
+case 13:
+#line 285 "parse.yacc"
+{
+                           defaults_matches = TRUE;
+                       }
+break;
+case 14:
+#line 288 "parse.yacc"
+{ push; }
+break;
+case 15:
+#line 288 "parse.yacc"
+{
+                           defaults_matches = user_matches;
+                           pop;
+                       }
+break;
+case 16:
+#line 292 "parse.yacc"
+{ push; }
+break;
+case 17:
+#line 292 "parse.yacc"
+{
+                           defaults_matches = host_matches;
+                           pop;
+                       }
+break;
+case 20:
+#line 301 "parse.yacc"
+{
+                           if (defaults_matches == TRUE &&
+                               !set_default(yyvsp[0].string, NULL, TRUE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 21:
+#line 309 "parse.yacc"
+{
+                           if (defaults_matches == TRUE &&
+                               !set_default(yyvsp[0].string, NULL, FALSE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 22:
+#line 317 "parse.yacc"
+{
+                           if (defaults_matches == TRUE &&
+                               !set_default(yyvsp[-2].string, yyvsp[0].string, TRUE)) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free(yyvsp[-2].string);
+                           free(yyvsp[0].string);
+                       }
+break;
+case 23:
+#line 326 "parse.yacc"
+{
+                           if (defaults_matches == TRUE &&
+                               !set_default(yyvsp[-2].string, yyvsp[0].string, '+')) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free(yyvsp[-2].string);
+                           free(yyvsp[0].string);
+                       }
+break;
+case 24:
+#line 335 "parse.yacc"
+{
+                           if (defaults_matches == TRUE &&
+                               !set_default(yyvsp[-2].string, yyvsp[0].string, '-')) {
+                               yyerror(NULL);
+                               YYERROR;
+                           }
+                           free(yyvsp[-2].string);
+                           free(yyvsp[0].string);
+                       }
+break;
+case 27:
+#line 349 "parse.yacc"
+{
+                           /*
+                            * We already did a push if necessary in
+                            * cmndspec so just reset some values so
+                            * the next 'privilege' gets a clean slate.
+                            */
+                           host_matches = -1;
+                           runas_matches = -1;
+                           if (def_flag(I_AUTHENTICATE))
+                               no_passwd = -1;
+                           else
+                               no_passwd = TRUE;
+                       }
+break;
+case 28:
+#line 364 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               host_matches = yyvsp[0].BOOLEAN;
+                       }
+break;
+case 29:
+#line 368 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               host_matches = ! yyvsp[0].BOOLEAN;
+                       }
+break;
+case 30:
+#line 373 "parse.yacc"
+{
+                           yyval.BOOLEAN = TRUE;
+                       }
+break;
+case 31:
+#line 376 "parse.yacc"
+{
+                           if (addr_matches(yyvsp[0].string))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 32:
+#line 383 "parse.yacc"
+{
+                           if (netgr_matches(yyvsp[0].string, user_host, user_shost, NULL))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 33:
+#line 390 "parse.yacc"
+{
+                           if (hostname_matches(user_shost, user_host, yyvsp[0].string) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 34:
+#line 397 "parse.yacc"
+{
+                           aliasinfo *aip = find_alias(yyvsp[0].string, HOST_ALIAS);
+
+                           /* could be an all-caps hostname */
+                           if (aip)
+                               yyval.BOOLEAN = aip->val;
+                           else if (strcasecmp(user_shost, yyvsp[0].string) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Host_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               yyval.BOOLEAN = -1;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 37:
+#line 425 "parse.yacc"
+{
+                           /*
+                            * Push the entry onto the stack if it is worth
+                            * saving and clear cmnd_matches for next cmnd.
+                            *
+                            * We need to save at least one entry on
+                            * the stack so sudoers_lookup() can tell that
+                            * the user was listed in sudoers.  Also, we
+                            * need to be able to tell whether or not a
+                            * user was listed for this specific host.
+                            *
+                            * If keepall is set and the user matches then
+                            * we need to keep entries around too...
+                            */
+                           if (user_matches != -1 && host_matches != -1 &&
+                               cmnd_matches != -1 && runas_matches != -1)
+                               pushcp;
+                           else if (user_matches != -1 && (top == 1 ||
+                               (top == 2 && host_matches != -1 &&
+                               match[0].host == -1)))
+                               pushcp;
+                           else if (user_matches == TRUE && keepall)
+                               pushcp;
+                           cmnd_matches = -1;
+                       }
+break;
+case 38:
+#line 452 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               cmnd_matches = yyvsp[0].BOOLEAN;
+                       }
+break;
+case 39:
+#line 456 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("!", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_cmnd("!", NULL);
+                           }
+                       }
+break;
+case 40:
+#line 464 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               cmnd_matches = ! yyvsp[0].BOOLEAN;
+                       }
+break;
+case 41:
+#line 470 "parse.yacc"
+{
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE) {
+                               if (runas_matches == -1) {
+                                   cm_list[cm_list_len].runas_len = 0;
+                               } else {
+                                   /* Inherit runas data. */
+                                   cm_list[cm_list_len].runas =
+                                       estrdup(cm_list[cm_list_len-1].runas);
+                                   cm_list[cm_list_len].runas_len =
+                                       cm_list[cm_list_len-1].runas_len;
+                                   cm_list[cm_list_len].runas_size =
+                                       cm_list[cm_list_len-1].runas_size;
+                               }
+                           }
+                           /*
+                            * If this is the first entry in a command list
+                            * then check against default runas user.
+                            */
+                           if (runas_matches == -1)
+                               runas_matches = (strcmp(*user_runas,
+                                   def_str(I_RUNAS_DEFAULT)) == 0);
+                       }
+break;
+case 42:
+#line 493 "parse.yacc"
+{
+                           runas_matches = (yyvsp[0].BOOLEAN == TRUE ? TRUE : FALSE);
+                       }
+break;
+case 43:
+#line 498 "parse.yacc"
+{ ; }
+break;
+case 44:
+#line 499 "parse.yacc"
+{
+                           /* Later entries override earlier ones. */
+                           if (yyvsp[0].BOOLEAN != -1)
+                               yyval.BOOLEAN = yyvsp[0].BOOLEAN;
+                           else
+                               yyval.BOOLEAN = yyvsp[-2].BOOLEAN;
+                       }
+break;
+case 45:
+#line 508 "parse.yacc"
+{ ; }
+break;
+case 46:
+#line 509 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("!", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas("!", ", ");
+                           }
+                       }
+break;
+case 47:
+#line 517 "parse.yacc"
+{
+                           /* Set $$ to the negation of runasuser */
+                           yyval.BOOLEAN = (yyvsp[0].BOOLEAN == -1 ? -1 : ! yyvsp[0].BOOLEAN);
+                       }
+break;
+case 48:
+#line 522 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries(yyvsp[0].string, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas(yyvsp[0].string, ", ");
+                           }
+                           if (strcmp(yyvsp[0].string, *user_runas) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 49:
+#line 536 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries(yyvsp[0].string, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas(yyvsp[0].string, ", ");
+                           }
+                           if (usergr_matches(yyvsp[0].string, *user_runas))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 50:
+#line 550 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries(yyvsp[0].string, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas(yyvsp[0].string, ", ");
+                           }
+                           if (netgr_matches(yyvsp[0].string, NULL, NULL, *user_runas))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 51:
+#line 564 "parse.yacc"
+{
+                           aliasinfo *aip = find_alias(yyvsp[0].string, RUNAS_ALIAS);
+
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries(yyvsp[0].string, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas(yyvsp[0].string, ", ");
+                           }
+                           /* could be an all-caps username */
+                           if (aip)
+                               yyval.BOOLEAN = aip->val;
+                           else if (strcmp(yyvsp[0].string, *user_runas) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Runas_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               yyval.BOOLEAN = -1;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 52:
+#line 593 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("ALL", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE)
+                                   append_runas("ALL", ", ");
+                           }
+                           yyval.BOOLEAN = TRUE;
+                       }
+break;
+case 53:
+#line 605 "parse.yacc"
+{
+                           /* Inherit NOPASSWD/PASSWD status. */
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE) {
+                               if (no_passwd == TRUE)
+                                   cm_list[cm_list_len].nopasswd = TRUE;
+                               else
+                                   cm_list[cm_list_len].nopasswd = FALSE;
+                           }
+                       }
+break;
+case 54:
+#line 615 "parse.yacc"
+{
+                           no_passwd = TRUE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].nopasswd = TRUE;
+                       }
+break;
+case 55:
+#line 621 "parse.yacc"
+{
+                           no_passwd = FALSE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].nopasswd = FALSE;
+                       }
+break;
+case 56:
+#line 629 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries("ALL", ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE) {
+                                   append_cmnd("ALL", NULL);
+                                   expand_match_list();
+                               }
+                           }
+
+                           yyval.BOOLEAN = TRUE;
+
+                           if (safe_cmnd)
+                               free(safe_cmnd);
+                           safe_cmnd = estrdup(user_cmnd);
+                       }
+break;
+case 57:
+#line 646 "parse.yacc"
+{
+                           aliasinfo *aip;
+
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE)
+                                   append_entries(yyvsp[0].string, ", ");
+                               else if (host_matches == TRUE &&
+                                   user_matches == TRUE) {
+                                   append_cmnd(yyvsp[0].string, NULL);
+                                   expand_match_list();
+                               }
+                           }
+
+                           if ((aip = find_alias(yyvsp[0].string, CMND_ALIAS)))
+                               yyval.BOOLEAN = aip->val;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared Cmnd_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
+                                   if (pedantic > 1) {
+                                       yyerror(NULL);
+                                       YYERROR;
+                                   }
+                               }
+                               yyval.BOOLEAN = -1;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 58:
+#line 675 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               if (in_alias == TRUE) {
+                                   append_entries(yyvsp[0].command.cmnd, ", ");
+                                   if (yyvsp[0].command.args)
+                                       append_entries(yyvsp[0].command.args, " ");
+                               }
+                               if (host_matches == TRUE &&
+                                   user_matches == TRUE)  {
+                                   append_cmnd(yyvsp[0].command.cmnd, NULL);
+                                   if (yyvsp[0].command.args)
+                                       append_cmnd(yyvsp[0].command.args, " ");
+                                   expand_match_list();
+                               }
+                           }
+
+                           if (command_matches(user_cmnd, user_args,
+                               yyvsp[0].command.cmnd, yyvsp[0].command.args))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+
+                           free(yyvsp[0].command.cmnd);
+                           if (yyvsp[0].command.args)
+                               free(yyvsp[0].command.args);
+                       }
+break;
+case 61:
+#line 707 "parse.yacc"
+{ push; }
+break;
+case 62:
+#line 707 "parse.yacc"
+{
+                           if ((host_matches != -1 || pedantic) &&
+                               !add_alias(yyvsp[-3].string, HOST_ALIAS, host_matches))
+                               YYERROR;
+                           pop;
+                       }
+break;
+case 67:
+#line 723 "parse.yacc"
+{
+                           push;
+                           if (printmatches == TRUE) {
+                               in_alias = TRUE;
+                               /* Allocate space for ga_list if necessary. */
+                               expand_ga_list();
+                               ga_list[ga_list_len-1].type = CMND_ALIAS;
+                               ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
+                            }
+                       }
+break;
+case 68:
+#line 732 "parse.yacc"
+{
+                           if ((cmnd_matches != -1 || pedantic) &&
+                               !add_alias(yyvsp[-3].string, CMND_ALIAS, cmnd_matches))
+                               YYERROR;
+                           pop;
+                           free(yyvsp[-3].string);
+
+                           if (printmatches == TRUE)
+                               in_alias = FALSE;
+                       }
+break;
+case 69:
+#line 744 "parse.yacc"
+{ ; }
+break;
+case 73:
+#line 752 "parse.yacc"
+{
+                           if (printmatches == TRUE) {
+                               in_alias = TRUE;
+                               /* Allocate space for ga_list if necessary. */
+                               expand_ga_list();
+                               ga_list[ga_list_len-1].type = RUNAS_ALIAS;
+                               ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
+                           }
+                       }
+break;
+case 74:
+#line 760 "parse.yacc"
+{
+                           if ((yyvsp[0].BOOLEAN != -1 || pedantic) &&
+                               !add_alias(yyvsp[-3].string, RUNAS_ALIAS, yyvsp[0].BOOLEAN))
+                               YYERROR;
+                           free(yyvsp[-3].string);
+
+                           if (printmatches == TRUE)
+                               in_alias = FALSE;
+                       }
+break;
+case 77:
+#line 775 "parse.yacc"
+{ push; }
+break;
+case 78:
+#line 775 "parse.yacc"
+{
+                           if ((user_matches != -1 || pedantic) &&
+                               !add_alias(yyvsp[-3].string, USER_ALIAS, user_matches))
+                               YYERROR;
+                           pop;
+                           free(yyvsp[-3].string);
+                       }
+break;
+case 81:
+#line 788 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               user_matches = yyvsp[0].BOOLEAN;
+                       }
+break;
+case 82:
+#line 792 "parse.yacc"
+{
+                           if (yyvsp[0].BOOLEAN != -1)
+                               user_matches = ! yyvsp[0].BOOLEAN;
+                       }
+break;
+case 83:
+#line 797 "parse.yacc"
+{
+                           if (strcmp(yyvsp[0].string, user_name) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 84:
+#line 804 "parse.yacc"
+{
+                           if (usergr_matches(yyvsp[0].string, user_name))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 85:
+#line 811 "parse.yacc"
+{
+                           if (netgr_matches(yyvsp[0].string, NULL, NULL, user_name))
+                               yyval.BOOLEAN = TRUE;
+                           else
+                               yyval.BOOLEAN = -1;
+                           free(yyvsp[0].string);
+                       }
+break;
+case 86:
+#line 818 "parse.yacc"
+{
+                           aliasinfo *aip = find_alias(yyvsp[0].string, USER_ALIAS);
+
+                           /* could be an all-caps username */
+                           if (aip)
+                               yyval.BOOLEAN = aip->val;
+                           else if (strcmp(yyvsp[0].string, user_name) == 0)
+                               yyval.BOOLEAN = TRUE;
+                           else {
+                               if (pedantic) {
+                                   (void) fprintf(stderr,
+                                       "%s: undeclared User_Alias `%s' referenced near line %d\n",
+                                       (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
+                                   if (pedantic > 1)
+                                       YYERROR;
+                               }
+                               yyval.BOOLEAN = -1;
+                           }
+                           free(yyvsp[0].string);
+                       }
+break;
+case 87:
+#line 838 "parse.yacc"
+{
+                           yyval.BOOLEAN = TRUE;
+                       }
+break;
+#line 1834 "sudo.tab.c"
+    }
+    yyssp -= yym;
+    yystate = *yyssp;
+    yyvsp -= yym;
+    yym = yylhs[yyn];
+    if (yystate == 0 && yym == 0)
+    {
+#if YYDEBUG
+        if (yydebug)
+            printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+        yystate = YYFINAL;
+        *++yyssp = YYFINAL;
+        *++yyvsp = yyval;
+        if (yychar < 0)
+        {
+            if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+            if (yydebug)
+            {
+                yys = 0;
+                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+                if (!yys) yys = "illegal-symbol";
+                printf("%sdebug: state %d, reading %d (%s)\n",
+                        YYPREFIX, YYFINAL, yychar, yys);
+            }
+#endif
+        }
+        if (yychar == 0) goto yyaccept;
+        goto yyloop;
+    }
+    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+        yystate = yytable[yyn];
+    else
+        yystate = yydgoto[yym];
+#if YYDEBUG
+    if (yydebug)
+        printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+    if (yyssp >= yysslim && yygrowstack())
+    {
+        goto yyoverflow;
+    }
+    *++yyssp = yystate;
+    *++yyvsp = yyval;
+    goto yyloop;
+yyoverflow:
+    yyerror("yacc stack overflow");
+yyabort:
+    return (1);
+yyaccept:
+    return (0);
+}
diff --git a/sudo.tab.h b/sudo.tab.h
new file mode 100644 (file)
index 0000000..71b1255
--- /dev/null
@@ -0,0 +1,27 @@
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DEFAULTS 264
+#define DEFAULTS_HOST 265
+#define DEFAULTS_USER 266
+#define RUNAS 267
+#define NOPASSWD 268
+#define PASSWD 269
+#define ALL 270
+#define COMMENT 271
+#define HOSTALIAS 272
+#define CMNDALIAS 273
+#define USERALIAS 274
+#define RUNASALIAS 275
+#define ERROR 276
+typedef union {
+    char *string;
+    int BOOLEAN;
+    struct sudo_command command;
+    int tok;
+} YYSTYPE;
+extern YYSTYPE yylval;
diff --git a/sudoers b/sudoers
new file mode 100644 (file)
index 0000000..0bc6c9a
--- /dev/null
+++ b/sudoers
@@ -0,0 +1,28 @@
+# sudoers file.
+#
+# This file MUST be edited with the 'visudo' command as root.
+#
+# See the sudoers man page for the details on how to write a sudoers file.
+#
+
+# Host alias specification
+
+# User alias specification
+
+# Cmnd alias specification
+
+# Defaults specification
+
+# User privilege specification
+root   ALL=(ALL) ALL
+
+# Uncomment to allow people in group wheel to run all commands
+# %wheel       ALL=(ALL)       ALL
+
+# Same thing without a password
+# %wheel       ALL=(ALL)       NOPASSWD: ALL
+
+# Samples
+# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
+# %users  localhost=/sbin/shutdown -h now
+
diff --git a/sudoers.cat b/sudoers.cat
new file mode 100644 (file)
index 0000000..a78c030
--- /dev/null
@@ -0,0 +1,1188 @@
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+N\bN\bN\bNA\bA\bA\bAM\bM\bM\bME\bE\bE\bE
+       sudoers - list of which users may execute what
+
+D\bD\bD\bDE\bE\bE\bES\bS\bS\bSC\bC\bC\bCR\bR\bR\bRI\bI\bI\bIP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bN
+       The _\bs_\bu_\bd_\bo_\be_\br_\bs file is composed of two types of entries:
+       aliases (basically variables) and user specifications
+       (which specify who may run what).  The grammar of _\bs_\bu_\bd_\bo_\be_\br_\bs
+       will be described below in Extended Backus-Naur Form
+       (EBNF).  Don't despair if you don't know what EBNF is; it
+       is fairly simple, and the definitions below are annotated.
+
+       Q\bQ\bQ\bQu\bu\bu\bui\bi\bi\bic\bc\bc\bck\bk\bk\bk g\bg\bg\bgu\bu\bu\bui\bi\bi\bid\bd\bd\bde\be\be\be t\bt\bt\bto\bo\bo\bo E\bE\bE\bEB\bB\bB\bBN\bN\bN\bNF\bF\bF\bF
+
+       EBNF is a concise and exact way of describing the grammar
+       of a language.  Each EBNF definition is made up of _\bp_\br_\bo_\bd_\bu_\bc_\b­
+       _\bt_\bi_\bo_\bn _\br_\bu_\bl_\be_\bs.  E.g.,
+
+        symbol ::= definition | alternate1 | alternate2 ...
+
+       Each _\bp_\br_\bo_\bd_\bu_\bc_\bt_\bi_\bo_\bn _\br_\bu_\bl_\be references others and thus makes up a
+       grammar for the language.  EBNF also contains the follow­
+       ing operators, which many readers will recognize from reg­
+       ular expressions.  Do not, however, confuse them with
+       "wildcard" characters, which have different meanings.
+
+       ?       Means that the preceding symbol (or group of sym­
+               bols) is optional.  That is, it may appear once or
+               not at all.
+
+       *       Means that the preceding symbol (or group of sym­
+               bols) may appear zero or more times.
+
+       +       Means that the preceding symbol (or group of sym­
+               bols) may appear one or more times.
+
+       Parentheses may be used to group symbols together.  For
+       clarity, we will use single quotes ('') to designate what
+       is a verbatim character string (as opposed to a symbol
+       name).
+
+       A\bA\bA\bAl\bl\bl\bli\bi\bi\bia\ba\ba\bas\bs\bs\bse\be\be\bes\bs\bs\bs
+
+       There are four kinds of aliases: User_Alias, Runas_Alias,
+       Host_Alias and Cmnd_Alias.
+
+        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)*
+
+        User_Alias ::= NAME '=' User_List
+
+        Runas_Alias ::= NAME '=' Runas_List
+
+
+
+
+April 25, 2002                1.6.6                             1
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+        Host_Alias ::= NAME '=' Host_List
+
+        Cmnd_Alias ::= NAME '=' Cmnd_List
+
+        NAME ::= [A-Z]([A-Z][0-9]_)*
+
+       Each _\ba_\bl_\bi_\ba_\bs definition is of the form
+
+        Alias_Type NAME = item1, item2, ...
+
+       where _\bA_\bl_\bi_\ba_\bs_\b__\bT_\by_\bp_\be is one of User_Alias, Runas_Alias,
+       Host_Alias, or Cmnd_Alias.  A NAME is a string of upper­
+       case letters, numbers, and the underscore characters
+       ('_').  A NAME m\bm\bm\bmu\bu\bu\bus\bs\bs\bst\bt\bt\bt start with an uppercase letter.  It is
+       possible to put several alias definitions of the same type
+       on a single line, joined by a colon (':').  E.g.,
+
+        Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+
+       The definitions of what constitutes a valid _\ba_\bl_\bi_\ba_\bs member
+       follow.
+
+        User_List ::= User |
+                      User ',' User_List
+
+        User ::= '!'* username |
+                 '!'* '%'group |
+                 '!'* '+'netgroup |
+                 '!'* User_Alias
+
+       A User_List is made up of one or more usernames, uids
+       (prefixed with '#'), 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 Runas_List is similar to a User_List except that it can
+       also contain uids (prefixed with '#') and instead of
+       User_Aliases it can contain Runas_Aliases.
+
+        Host_List ::= Host |
+                      Host ',' Host_List
+
+
+
+
+
+April 25, 2002                1.6.6                             2
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+        Host ::= '!'* hostname |
+                 '!'* ip_addr |
+                 '!'* network(/netmask)? |
+                 '!'* '+'netgroup |
+                 '!'* Host_Alias
+
+       A Host_List is made up of one or more hostnames, IP
+       addresses, network numbers, netgroups (prefixed with '+')
+       and other aliases.  Again, the value of an item may be
+       negated with the '!' operator.  If you do not specify a
+       netmask with a network number, the netmask of the host's
+       ethernet _\bi_\bn_\bt_\be_\br_\bf_\ba_\bc_\be(s) will be used when matching.  The
+       netmask may be specified either in dotted quad notation
+       (e.g.  255.255.255.0) or CIDR notation (number of bits,
+       e.g. 24).  A hostname may include shell-style wildcards
+       (see `Wildcards' section below), but unless the hostname
+       command on your machine returns the fully qualified host­
+       name, you'll need to use the _\bf_\bq_\bd_\bn option for wildcards to
+       be useful.
+
+        Cmnd_List ::= Cmnd |
+                      Cmnd ',' Cmnd_List
+
+        commandname ::= filename |
+                        filename args |
+                        filename '""'
+
+        Cmnd ::= '!'* commandname |
+                 '!'* directory |
+                 '!'* Cmnd_Alias
+
+       A Cmnd_List is a list of one or more commandnames, direc­
+       tories, and other aliases.  A commandname is a fully qual­
+       ified filename which may include shell-style wildcards
+       (see `Wildcards' section below).  A simple filename allows
+       the user to run the command with any arguments he/she
+       wishes.  However, you may also specify command line argu­
+       ments (including wildcards).  Alternately, you can specify
+       "" to indicate that the command may only be run w\bw\bw\bwi\bi\bi\bit\bt\bt\bth\bh\bh\bho\bo\bo\bou\bu\bu\but\bt\bt\bt
+       command line arguments.  A directory is a fully qualified
+       pathname ending in a '/'.  When you specify a directory in
+       a Cmnd_List, the user will be able to run any file within
+       that directory (but not in any subdirectories therein).
+
+       If a Cmnd has associated command line arguments, then the
+       arguments in the Cmnd must match exactly those given by
+       the user on the command line (or match the wildcards if
+       there are any).  Note that the following characters must
+       be escaped with a '\' if they are used in command argu­
+       ments: ',', ':', '=', '\'.
+
+
+
+
+
+
+
+April 25, 2002                1.6.6                             3
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       D\bD\bD\bDe\be\be\bef\bf\bf\bfa\ba\ba\bau\bu\bu\bul\bl\bl\blt\bt\bt\bts\bs\bs\bs
+
+       Certain configuration options may be changed from their
+       default values at runtime via one or more Default_Entry
+       lines.  These may affect all users on any host, all users
+       on a specific host, or just a specific user.  When multi­
+       ple entries match, they are applied in order.  Where there
+       are conflicting values, the last value on a matching line
+       takes effect.
+
+        Default_Type ::= 'Defaults' ||
+                         'Defaults' ':' User ||
+                         'Defaults' '@' Host
+
+        Default_Entry ::= Default_Type Parameter_List
+
+        Parameter ::= Parameter '=' Value ||
+                      Parameter '+=' Value ||
+                      Parameter '-=' Value ||
+                      '!'* Parameter ||
+
+       Parameters may be f\bf\bf\bfl\bl\bl\bla\ba\ba\bag\bg\bg\bgs\bs\bs\bs, i\bi\bi\bin\bn\bn\bnt\bt\bt\bte\be\be\beg\bg\bg\bge\be\be\ber\br\br\br values, s\bs\bs\bst\bt\bt\btr\br\br\bri\bi\bi\bin\bn\bn\bng\bg\bg\bgs\bs\bs\bs, or
+       l\bl\bl\bli\bi\bi\bis\bs\bs\bst\bt\bt\bts\bs\bs\bs.  Flags are implicitly boolean and can be turned off
+       via the '!'  operator.  Some integer, string and list
+       parameters may also be used in a boolean context to dis­
+       able them.  Values may be enclosed in double quotes (")
+       when they contain multiple words.  Special characters may
+       be escaped with a backslash (\).
+
+       Lists have two additional assignment operators, += and -=.
+       These operators are used to add to and delete from a list
+       respectively.  It is not an error to use the -= operator
+       to remove an element that does not exist in a list.
+
+       Note that since the _\bs_\bu_\bd_\bo_\be_\br_\bs file is parsed in order the
+       best place to put the Defaults section is after the Host,
+       User, and Cmnd aliases but before the user specifications.
+
+       F\bF\bF\bFl\bl\bl\bla\ba\ba\bag\bg\bg\bgs\bs\bs\bs:
+
+       long_otp_prompt
+                   When validating with a One Time Password
+                   scheme (S\bS\bS\bS/\b/\b/\b/K\bK\bK\bKe\be\be\bey\by\by\by or O\bO\bO\bOP\bP\bP\bPI\bI\bI\bIE\bE\bE\bE), a two-line prompt is
+                   used to make it easier to cut and paste the
+                   challenge to a local window.  It's not as
+                   pretty as the default but some people find it
+                   more convenient.  This flag is _\bo_\bf_\bf by default.
+
+       ignore_dot  If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will ignore '.' or '' (current
+                   dir) in the PATH environment variable; the
+                   PATH itself is not modified.  This flag is _\bo_\bf_\bf
+                   by default.
+
+
+
+
+
+April 25, 2002                1.6.6                             4
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       mail_always Send mail to the _\bm_\ba_\bi_\bl_\bt_\bo user every time a
+                   users runs s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo.  This flag is _\bo_\bf_\bf by default.
+
+       mail_badpass
+                   Send mail to the _\bm_\ba_\bi_\bl_\bt_\bo user if the user run­
+                   ning sudo does not enter the correct password.
+                   This flag is _\bo_\bf_\bf by default.
+
+       mail_no_user
+                   If set, mail will be sent to the _\bm_\ba_\bi_\bl_\bt_\bo user
+                   if the invoking user is not in the _\bs_\bu_\bd_\bo_\be_\br_\bs
+                   file.  This flag is _\bo_\bn by default.
+
+       mail_no_host
+                   If set, mail will be sent to the _\bm_\ba_\bi_\bl_\bt_\bo user
+                   if the invoking user exists in the _\bs_\bu_\bd_\bo_\be_\br_\bs
+                   file, but is not allowed to run commands on
+                   the current host.  This flag is _\bo_\bf_\bf by
+                   default.
+
+       mail_no_perms
+                   If set, mail will be sent to the _\bm_\ba_\bi_\bl_\bt_\bo user
+                   if the invoking user allowed to use s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo but
+                   the command they are trying is not listed in
+                   their _\bs_\bu_\bd_\bo_\be_\br_\bs file entry.  This flag is _\bo_\bf_\bf by
+                   default.
+
+       tty_tickets If set, users must authenticate on a per-tty
+                   basis.  Normally, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo uses a directory in the
+                   ticket dir with the same name as the user run­
+                   ning it.  With this flag enabled, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will
+                   use a file named for the tty the user is
+                   logged in on in that directory.  This flag is
+                   _\bo_\bf_\bf by default.
+
+       lecture     If set, a user will receive a short lecture
+                   the first time he/she runs s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo.  This flag is
+                   _\bo_\bn by default.
+
+       authenticate
+                   If set, users must authenticate themselves via
+                   a password (or other means of authentication)
+                   before they may run commands.  This default
+                   may be overridden via the PASSWD and NOPASSWD
+                   tags.  This flag is _\bo_\bn by default.
+
+       root_sudo   If set, root is allowed to run s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo too.  Dis­
+                   abling this prevents users from "chaining"
+                   s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo commands to get a root shell by doing
+                   something like "sudo sudo /bin/sh".  This flag
+                   is _\bo_\bn by default.
+
+       log_host    If set, the hostname will be logged in the
+                   (non-syslog) s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo log file.  This flag is _\bo_\bf_\bf
+
+
+
+April 25, 2002                1.6.6                             5
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+                   by default.
+
+       log_year    If set, the four-digit year will be logged in
+                   the (non-syslog) s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo log file.  This flag is
+                   _\bo_\bf_\bf by default.
+
+       shell_noargs
+                   If set and s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is invoked with no arguments
+                   it acts as if the -\b-\b-\b-s\bs\bs\bs flag had been given.
+                   That is, it runs a shell as root (the shell is
+                   determined by the 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 _\bo_\bf_\bf by default.
+
+       set_home    If set and s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is invoked with the -\b-\b-\b-s\bs\bs\bs flag
+                   the HOME environment variable will be set to
+                   the home directory of the target user (which
+                   is root unless the -\b-\b-\b-u\bu\bu\bu option is used).  This
+                   effectively makes the -\b-\b-\b-s\bs\bs\bs flag imply -\b-\b-\b-H\bH\bH\bH.  This
+                   flag is _\bo_\bf_\bf by default.
+
+       always_set_home
+                   If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will set the HOME environment
+                   variable to the home directory of the target
+                   user (which is root unless the -\b-\b-\b-u\bu\bu\bu option is
+                   used).  This effectively means that the -\b-\b-\b-H\bH\bH\bH
+                   flag is always implied.  This flag is _\bo_\bf_\bf by
+                   default.
+
+       path_info   Normally, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will tell the user when a com­
+                   mand could not be found in their PATH environ­
+                   ment variable.  Some sites may wish to disable
+                   this as it could be used to gather information
+                   on the location of executables that the normal
+                   user does not have access to.  The disadvan­
+                   tage is that if the executable is simply not
+                   in the user's PATH, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will tell the user
+                   that they are not allowed to run it, which can
+                   be confusing.  This flag is _\bo_\bf_\bf by default.
+
+       preserve_groups
+                   By default s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will initialize the group vec­
+                   tor to the list of groups the target user is
+                   in.  When _\bp_\br_\be_\bs_\be_\br_\bv_\be_\b__\bg_\br_\bo_\bu_\bp_\bs is set, the user's
+                   existing group vector is left unaltered.  The
+                   real and effective group IDs, however, are
+                   still set to match the target user.  This flag
+                   is _\bo_\bf_\bf by default.
+
+       fqdn        Set this flag if you want to put fully quali­
+                   fied hostnames in the _\bs_\bu_\bd_\bo_\be_\br_\bs file.  I.e.:
+                   instead of myhost you would use myhost.mydo­
+                   main.edu.  You may still use the short form if
+
+
+
+April 25, 2002                1.6.6                             6
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+                   you wish (and even mix the two).  Beware that
+                   turning on _\bf_\bq_\bd_\bn requires s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to make DNS
+                   lookups which may make s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo unusable if DNS
+                   stops working (for example if the machine is
+                   not plugged into the network).  Also note that
+                   you must use the host's official name as DNS
+                   knows it.  That is, you may not use a host
+                   alias (CNAME entry) due to performance issues
+                   and the fact that there is no way to get all
+                   aliases from DNS.  If your machine's hostname
+                   (as returned by the hostname command) is
+                   already fully qualified you shouldn't need to
+                   set _\bf_\bq_\bd_\bn.  This flag is _\bo_\bf_\bf by default.
+
+       insults     If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will insult users when they enter
+                   an incorrect password.  This flag is _\bo_\bf_\bf by
+                   default.
+
+       requiretty  If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will only run when the user is
+                   logged in to a real tty.  This will disallow
+                   things like "rsh somehost sudo ls" since
+                   _\br_\bs_\bh(1) does not allocate a tty.  Because it is
+                   not possible to turn of echo when there is no
+                   tty present, some sites may with to set this
+                   flag to prevent a user from entering a visible
+                   password.  This flag is _\bo_\bf_\bf by default.
+
+       env_editor  If set, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will use the value of the EDI­
+                   TOR or VISUAL environment variables before
+                   falling back on the default editor list.  Note
+                   that this may create a security hole as it
+                   allows the user to run any arbitrary command
+                   as root without logging.  A safer alternative
+                   is to place a colon-separated list of editors
+                   in the editor variable.  v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will then only
+                   use the EDITOR or VISUAL if they match a value
+                   specified in editor.  This flag is off by
+                   default.
+
+       rootpw      If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will prompt for the root password
+                   instead of the password of the invoking user.
+                   This flag is _\bo_\bf_\bf by default.
+
+       runaspw     If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will prompt for the password of
+                   the user defined by the _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt option
+                   (defaults to root) instead of the password of
+                   the invoking user.  This flag is _\bo_\bf_\bf by
+                   default.
+
+       targetpw    If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will prompt for the password of
+                   the user specified by the -\b-\b-\b-u\bu\bu\bu flag (defaults to
+                   root) instead of the password of the invoking
+                   user.  This flag is _\bo_\bf_\bf by default.
+
+
+
+
+April 25, 2002                1.6.6                             7
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       set_logname Normally, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will set the LOGNAME and USER
+                   environment variables to the name of the tar­
+                   get user (usually root unless the -\b-\b-\b-u\bu\bu\bu flag is
+                   given).  However, since some programs (includ­
+                   ing the RCS revision control system) use LOG­
+                   NAME to determine the real identity of the
+                   user, it may be desirable to change this
+                   behavior.  This can be done by negating the
+                   set_logname option.
+
+       stay_setuid Normally, when s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo executes a command the
+                   real and effective UIDs are set to the target
+                   user (root by default).  This option changes
+                   that behavior such that the real UID is left
+                   as the invoking user's UID.  In other words,
+                   this makes s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo act as a setuid wrapper.  This
+                   can be useful on systems that disable some
+                   potentially dangerous functionality when a
+                   program is run setuid.  Note, however, that
+                   this means that sudo will run with the real
+                   uid of the invoking user which may allow that
+                   user to kill s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo before it can log a failure,
+                   depending on how your OS defines the interac­
+                   tion between signals and setuid processes.
+
+       env_reset   If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will reset the environment to
+                   only contain the following variables: HOME,
+                   LOGNAME, PATH, SHELL, TERM, and USER (in addi­
+                   tion to the SUDO_* variables).  Of these, only
+                   TERM is copied unaltered from the old environ­
+                   ment.  The other variables are set to default
+                   values (possibly modified by the value of the
+                   _\bs_\be_\bt_\b__\bl_\bo_\bg_\bn_\ba_\bm_\be option).  If s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo was compiled
+                   with the SECURE_PATH option, its value will be
+                   used for the PATH environment variable.  Other
+                   variables may be preserved with the _\be_\bn_\bv_\b__\bk_\be_\be_\bp
+                   option.
+
+       use_loginclass
+                   If set, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will apply the defaults specified
+                   for the target user's login class if one
+                   exists.  Only available if s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is configured
+                   with the --with-logincap option.  This flag is
+                   _\bo_\bf_\bf by default.
+
+       I\bI\bI\bIn\bn\bn\bnt\bt\bt\bte\be\be\beg\bg\bg\bge\be\be\ber\br\br\brs\bs\bs\bs:
+
+       passwd_tries
+                   The number of tries a user gets to enter
+                   his/her password before s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo logs the failure
+                   and exits.  The default is 3.
+
+       I\bI\bI\bIn\bn\bn\bnt\bt\bt\bte\be\be\beg\bg\bg\bge\be\be\ber\br\br\brs\bs\bs\bs t\bt\bt\bth\bh\bh\bha\ba\ba\bat\bt\bt\bt c\bc\bc\bca\ba\ba\ban\bn\bn\bn b\bb\bb\bbe\be\be\be u\bu\bu\bus\bs\bs\bse\be\be\bed\bd\bd\bd i\bi\bi\bin\bn\bn\bn a\ba\ba\ba b\bb\bb\bbo\bo\bo\boo\bo\bo\bol\bl\bl\ble\be\be\bea\ba\ba\ban\bn\bn\bn c\bc\bc\bco\bo\bo\bon\bn\bn\bnt\bt\bt\bte\be\be\bex\bx\bx\bxt\bt\bt\bt:
+
+
+
+
+April 25, 2002                1.6.6                             8
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       loglinelen  Number of characters per line for the file
+                   log.  This value is used to decide when to
+                   wrap lines for nicer log files.  This has no
+                   effect on the syslog log file, only the file
+                   log.  The default is 80 (use 0 or negate the
+                   option to disable word wrap).
+
+       timestamp_timeout
+                   Number of minutes that can elapse before s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo
+                   will ask for a passwd again.  The default is
+                   5.  Set this to 0 to always prompt for a pass­
+                   word.  If set to a value less than 0 the
+                   user's timestamp will never expire.  This can
+                   be used to allow users to create or delete
+                   their own timestamps via sudo -v and sudo -k
+                   respectively.
+
+       passwd_timeout
+                   Number of minutes before the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo password
+                   prompt times out.  The default is 5, set this
+                   to 0 for no password timeout.
+
+       umask       Umask to use when running the command.  Negate
+                   this option or set it to 0777 to preserve the
+                   user's umask.  The default is 0022.
+
+       S\bS\bS\bSt\bt\bt\btr\br\br\bri\bi\bi\bin\bn\bn\bng\bg\bg\bgs\bs\bs\bs:
+
+       mailsub     Subject of the mail sent to the _\bm_\ba_\bi_\bl_\bt_\bo user.
+                   The escape %h will expand to the hostname of
+                   the machine.  Default is *** SECURITY informa­
+                   tion for %h ***.
+
+       badpass_message
+                   Message that is displayed if a user enters an
+                   incorrect password.  The default is Sorry, try
+                   again. unless insults are enabled.
+
+       timestampdir
+                   The directory in which s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo stores its times­
+                   tamp files.  The default is _\b/_\bv_\ba_\br_\b/_\br_\bu_\bn_\b/_\bs_\bu_\bd_\bo.
+
+       passprompt  The default prompt to use when asking for a
+                   password; can be overridden via the -\b-\b-\b-p\bp\bp\bp option
+                   or the SUDO_PROMPT environment variable. Sup­
+                   ports two escapes: "%u" expands to the user's
+                   login name and "%h" expands to the local host­
+                   name.  The default value is Password:.
+
+       runas_default
+                   The default user to run commands as if the -\b-\b-\b-u\bu\bu\bu
+                   flag is not specified on the command line.
+                   This defaults to root.
+
+
+
+
+April 25, 2002                1.6.6                             9
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       syslog_goodpri
+                   Syslog priority to use when user authenticates
+                   successfully.  Defaults to notice.
+
+       syslog_badpri
+                   Syslog priority to use when user authenticates
+                   unsuccessfully.  Defaults to alert.
+
+       editor      A colon (':') separated list of editors
+                   allowed to be used with v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo.  v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will
+                   choose the editor that matches the user's USER
+                   environment variable if possible, or the first
+                   editor in the list that exists and is exe­
+                   cutable.  The default is the path to vi on
+                   your system.
+
+       S\bS\bS\bSt\bt\bt\btr\br\br\bri\bi\bi\bin\bn\bn\bng\bg\bg\bgs\bs\bs\bs t\bt\bt\bth\bh\bh\bha\ba\ba\bat\bt\bt\bt c\bc\bc\bca\ba\ba\ban\bn\bn\bn b\bb\bb\bbe\be\be\be u\bu\bu\bus\bs\bs\bse\be\be\bed\bd\bd\bd i\bi\bi\bin\bn\bn\bn a\ba\ba\ba b\bb\bb\bbo\bo\bo\boo\bo\bo\bol\bl\bl\ble\be\be\bea\ba\ba\ban\bn\bn\bn c\bc\bc\bco\bo\bo\bon\bn\bn\bnt\bt\bt\bte\be\be\bex\bx\bx\bxt\bt\bt\bt:
+
+       logfile     Path to the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo log file (not the syslog log
+                   file).  Setting a path turns on logging to a
+                   file; negating this option turns it off.
+
+       syslog      Syslog facility if syslog is being used for
+                   logging (negate to disable syslog logging).
+                   Defaults to local2.
+
+       mailerpath  Path to mail program used to send warning
+                   mail.  Defaults to the path to sendmail found
+                   at configure time.
+
+       mailerflags Flags to use when invoking mailer. Defaults to
+                   -\b-\b-\b-t\bt\bt\bt.
+
+       mailto      Address to send warning and error mail to.
+                   The address should be enclosed in double
+                   quotes (") to protect against sudo interpret­
+                   ing the @ sign.  Defaults to root.
+
+       exempt_group
+                   Users in this group are exempt from password
+                   and PATH requirements.  This is not set by
+                   default.
+
+       verifypw    This option controls when a password will be
+                   required when a user runs s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo with the -\b-\b-\b-v\bv\bv\bv
+                   flag.  It has the following possible values:
+
+                   all     All the user's _\bs_\bu_\bd_\bo_\be_\br_\bs entries for the
+                           current host must have the NOPASSWD
+                           flag set to avoid entering a password.
+
+                   any     At least one of the user's _\bs_\bu_\bd_\bo_\be_\br_\bs
+                           entries for the current host must have
+                           the NOPASSWD flag set to avoid
+
+
+
+April 25, 2002                1.6.6                            10
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+                           entering a password.
+
+                   never   The user need never enter a password
+                           to use the -\b-\b-\b-v\bv\bv\bv flag.
+
+                   always  The user must always enter a password
+                           to use the -\b-\b-\b-v\bv\bv\bv flag.
+
+                   The default value is `all'.
+
+       listpw      This option controls when a password will be
+                   required when a user runs s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo with the -\b-\b-\b-l\bl\bl\bl.
+                   It has the following possible values:
+
+                   all     All the user's _\bs_\bu_\bd_\bo_\be_\br_\bs entries for the
+                           current host must have the NOPASSWD
+                           flag set to avoid entering a password.
+
+                   any     At least one of the user's _\bs_\bu_\bd_\bo_\be_\br_\bs
+                           entries for the current host must have
+                           the NOPASSWD flag set to avoid enter­
+                           ing a password.
+
+                   never   The user need never enter a password
+                           to use the -\b-\b-\b-l\bl\bl\bl flag.
+
+                   always  The user must always enter a password
+                           to use the -\b-\b-\b-l\bl\bl\bl flag.
+
+                   The default value is `any'.
+
+       L\bL\bL\bLi\bi\bi\bis\bs\bs\bst\bt\bt\bts\bs\bs\bs t\bt\bt\bth\bh\bh\bha\ba\ba\bat\bt\bt\bt c\bc\bc\bca\ba\ba\ban\bn\bn\bn b\bb\bb\bbe\be\be\be u\bu\bu\bus\bs\bs\bse\be\be\bed\bd\bd\bd i\bi\bi\bin\bn\bn\bn a\ba\ba\ba b\bb\bb\bbo\bo\bo\boo\bo\bo\bol\bl\bl\ble\be\be\bea\ba\ba\ban\bn\bn\bn c\bc\bc\bco\bo\bo\bon\bn\bn\bnt\bt\bt\bte\be\be\bex\bx\bx\bxt\bt\bt\bt:
+
+       env_check   Environment variables to be removed from the
+                   user's environment if the variable's value
+                   contains % or / characters.  This can be used
+                   to guard against printf-style format vulnera­
+                   bilties in poorly-written programs.  The argu­
+                   ment 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 =, +=, -=, and
+                   ! operators respectively.  The default list of
+                   environment variable to check is printed when
+                   s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is run by root with the _\b-_\bV option.
+
+       env_delete  Environment variables to be removed from the
+                   user's environment.  The argument may be a
+                   double-quoted, space-separated list or a sin­
+                   gle value without double-quotes.  The list can
+                   be replaced, added to, deleted from, or dis­
+                   abled by using the =, +=, -=, and ! operators
+                   respectively.  The default list of environment
+                   variable to remove is printed when s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is run
+
+
+
+April 25, 2002                1.6.6                            11
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+                   by root with the _\b-_\bV option.
+
+       env_keep    Environment variables to be preserved in the
+                   user's environment when the _\be_\bn_\bv_\b__\br_\be_\bs_\be_\bt option
+                   is in effect.  This allows fine-grained con­
+                   trol over the environment s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo-spawned pro­
+                   cesses will receive.  The argument may be a
+                   double-quoted, space-separated list or a sin­
+                   gle value without double-quotes.  The list can
+                   be replaced, added to, deleted from, or dis­
+                   abled by using the =, +=, -=, and ! operators
+                   respectively.  This list has no default mem­
+                   bers.
+
+       When logging via _\bs_\by_\bs_\bl_\bo_\bg(3), s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo accepts the following
+       values for the syslog facility (the value of the s\bs\bs\bsy\by\by\bys\bs\bs\bsl\bl\bl\blo\bo\bo\bog\bg\bg\bg
+       Parameter): a\ba\ba\bau\bu\bu\but\bt\bt\bth\bh\bh\bhp\bp\bp\bpr\br\br\bri\bi\bi\biv\bv\bv\bv (if your OS supports it), a\ba\ba\bau\bu\bu\but\bt\bt\bth\bh\bh\bh, d\bd\bd\bda\ba\ba\bae\be\be\b\b­\b­\b­
+       m\bm\bm\bmo\bo\bo\bon\bn\bn\bn, u\bu\bu\bus\bs\bs\bse\be\be\ber\br\br\br, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl0\b0\b0\b0, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl1\b1\b1\b1, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl2\b2\b2\b2, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl3\b3\b3\b3, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl4\b4\b4\b4, l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl5\b5\b5\b5,
+       l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl6\b6\b6\b6, and l\bl\bl\blo\bo\bo\boc\bc\bc\bca\ba\ba\bal\bl\bl\bl7\b7\b7\b7.  The following syslog priorities are
+       supported: a\ba\ba\bal\bl\bl\ble\be\be\ber\br\br\brt\bt\bt\bt, c\bc\bc\bcr\br\br\bri\bi\bi\bit\bt\bt\bt, d\bd\bd\bde\be\be\beb\bb\bb\bbu\bu\bu\bug\bg\bg\bg, e\be\be\bem\bm\bm\bme\be\be\ber\br\br\brg\bg\bg\bg, e\be\be\ber\br\br\brr\br\br\br, i\bi\bi\bin\bn\bn\bnf\bf\bf\bfo\bo\bo\bo, n\bn\bn\bno\bo\bo\bot\bt\bt\bti\bi\bi\bic\bc\bc\bce\be\be\be,
+       and w\bw\bw\bwa\ba\ba\bar\br\br\brn\bn\bn\bni\bi\bi\bin\bn\bn\bng\bg\bg\bg.
+
+       U\bU\bU\bUs\bs\bs\bse\be\be\ber\br\br\br S\bS\bS\bSp\bp\bp\bpe\be\be\bec\bc\bc\bci\bi\bi\bif\bf\bf\bfi\bi\bi\bic\bc\bc\bca\ba\ba\bat\bt\bt\bti\bi\bi\bio\bo\bo\bon\bn\bn\bn
+
+        User_Spec ::= User_list Host_List '=' Cmnd_Spec_List \
+                      (':' User_Spec)*
+
+        Cmnd_Spec_List ::= Cmnd_Spec |
+                           Cmnd_Spec ',' Cmnd_Spec_List
+
+        Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
+
+        Runas_Spec ::= '(' Runas_List ')'
+
+       A u\bu\bu\bus\bs\bs\bse\be\be\ber\br\br\br s\bs\bs\bsp\bp\bp\bpe\be\be\bec\bc\bc\bci\bi\bi\bif\bf\bf\bfi\bi\bi\bic\bc\bc\bca\ba\ba\bat\bt\bt\bti\bi\bi\bio\bo\bo\bon\bn\bn\bn determines which commands a user may
+       run (and as what user) on specified hosts.  By default,
+       commands are run as r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt, but this can be changed on a
+       per-command basis.
+
+       Let's break that down into its constituent parts:
+
+       R\bR\bR\bRu\bu\bu\bun\bn\bn\bna\ba\ba\bas\bs\bs\bs_\b_\b_\b_S\bS\bS\bSp\bp\bp\bpe\be\be\bec\bc\bc\bc
+
+       A Runas_Spec is simply a Runas_List (as defined above)
+       enclosed in a set of parentheses.  If you do not specify a
+       Runas_Spec in the user specification, a default Runas_Spec
+       of r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt will be used.  A Runas_Spec sets the default for
+       commands that follow it.  What this means is that for the
+       entry:
+
+        dgb    boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
+
+       The user d\bd\bd\bdg\bg\bg\bgb\bb\bb\bb may run _\b/_\bb_\bi_\bn_\b/_\bl_\bs, _\b/_\bb_\bi_\bn_\b/_\bk_\bi_\bl_\bl, and _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bl_\bp_\br_\bm
+       -- but only as o\bo\bo\bop\bp\bp\bpe\be\be\ber\br\br\bra\ba\ba\bat\bt\bt\bto\bo\bo\bor\br\br\br.  E.g.,
+
+
+
+April 25, 2002                1.6.6                            12
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+           sudo -u operator /bin/ls.
+
+       It is also possible to override a Runas_Spec later on in
+       an entry.  If we modify the entry like so:
+
+        dgb    boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+
+       Then user d\bd\bd\bdg\bg\bg\bgb\bb\bb\bb is now allowed to run _\b/_\bb_\bi_\bn_\b/_\bl_\bs as o\bo\bo\bop\bp\bp\bpe\be\be\ber\br\br\bra\ba\ba\bat\bt\bt\bto\bo\bo\bor\br\br\br,
+       but  _\b/_\bb_\bi_\bn_\b/_\bk_\bi_\bl_\bl and _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bl_\bp_\br_\bm as r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt.
+
+       N\bN\bN\bNO\bO\bO\bOP\bP\bP\bPA\bA\bA\bAS\bS\bS\bSS\bS\bS\bSW\bW\bW\bWD\bD\bD\bD a\ba\ba\ban\bn\bn\bnd\bd\bd\bd P\bP\bP\bPA\bA\bA\bAS\bS\bS\bSS\bS\bS\bSW\bW\bW\bWD\bD\bD\bD
+
+       By default, s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo requires that a user authenticate him or
+       herself before running a command.  This behavior can be
+       modified via the NOPASSWD tag.  Like a Runas_Spec, the
+       NOPASSWD tag sets a default for the commands that follow
+       it in the Cmnd_Spec_List.  Conversely, the PASSWD tag can
+       be used to reverse things.  For example:
+
+        ray    rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
+
+       would allow the user r\br\br\bra\ba\ba\bay\by\by\by to run _\b/_\bb_\bi_\bn_\b/_\bk_\bi_\bl_\bl, _\b/_\bb_\bi_\bn_\b/_\bl_\bs, and
+       _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bl_\bp_\br_\bm as root on the machine rushmore as r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt
+       without authenticating himself.  If we only want r\br\br\bra\ba\ba\bay\by\by\by to be
+       able to run _\b/_\bb_\bi_\bn_\b/_\bk_\bi_\bl_\bl without a password the entry would
+       be:
+
+        ray    rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+
+       Note, however, that the PASSWD tag has no effect on users
+       who are in the group specified by the exempt_group option.
+
+       By default, if the NOPASSWD tag is applied to any of the
+       entries for a user on the current host, he or she will be
+       able to run sudo -l without a password.  Additionally, a
+       user may only run sudo -v without a password if the
+       NOPASSWD tag is present for all a user's entries that per­
+       tain to the current host.  This behavior may be overridden
+       via the verifypw and listpw options.
+
+       W\bW\bW\bWi\bi\bi\bil\bl\bl\bld\bd\bd\bdc\bc\bc\bca\ba\ba\bar\br\br\brd\bd\bd\bds\bs\bs\bs (\b(\b(\b(a\ba\ba\bak\bk\bk\bka\ba\ba\ba m\bm\bm\bme\be\be\bet\bt\bt\bta\ba\ba\ba c\bc\bc\bch\bh\bh\bha\ba\ba\bar\br\br\bra\ba\ba\bac\bc\bc\bct\bt\bt\bte\be\be\ber\br\br\brs\bs\bs\bs)\b)\b)\b):\b:\b:\b:
+
+       s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo allows shell-style _\bw_\bi_\bl_\bd_\bc_\ba_\br_\bd_\bs to be used in pathnames
+       as well as command line arguments in the _\bs_\bu_\bd_\bo_\be_\br_\bs file.
+       Wildcard matching is done via the P\bP\bP\bPO\bO\bO\bOS\bS\bS\bSI\bI\bI\bIX\bX\bX\bX fnmatch(3) rou­
+       tine.  Note that these are _\bn_\bo_\bt regular expressions.
+
+       *       Matches any set of zero or more characters.
+
+       ?       Matches any single character.
+
+       [...]   Matches any character in the specified range.
+
+
+
+
+
+April 25, 2002                1.6.6                            13
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       [!...]  Matches any character n\bn\bn\bno\bo\bo\bot\bt\bt\bt in the specified range.
+
+       \x      For any character "x", evaluates to "x".  This is
+               used to escape special characters such as: "*",
+               "?", "[", and "}".
+
+       Note that a forward slash ('/') will n\bn\bn\bno\bo\bo\bot\bt\bt\bt be matched by
+       wildcards used in the pathname.  When matching the command
+       line arguments, however, as slash d\bd\bd\bdo\bo\bo\boe\be\be\bes\bs\bs\bs get matched by
+       wildcards.  This is to make a path like:
+
+           /usr/bin/*
+
+       match /usr/bin/who but not /usr/bin/X11/xterm.
+
+       E\bE\bE\bEx\bx\bx\bxc\bc\bc\bce\be\be\bep\bp\bp\bpt\bt\bt\bti\bi\bi\bio\bo\bo\bon\bn\bn\bns\bs\bs\bs t\bt\bt\bto\bo\bo\bo w\bw\bw\bwi\bi\bi\bil\bl\bl\bld\bd\bd\bdc\bc\bc\bca\ba\ba\bar\br\br\brd\bd\bd\bd r\br\br\bru\bu\bu\bul\bl\bl\ble\be\be\bes\bs\bs\bs:\b:\b:\b:
+
+       The following exceptions apply to the above rules:
+
+       """"    If the empty string "" is the only command line
+               argument in the _\bs_\bu_\bd_\bo_\be_\br_\bs entry it means that com­
+               mand is not allowed to be run with a\ba\ba\ban\bn\bn\bny\by\by\by arguments.
+
+       O\bO\bO\bOt\bt\bt\bth\bh\bh\bhe\be\be\ber\br\br\br s\bs\bs\bsp\bp\bp\bpe\be\be\bec\bc\bc\bci\bi\bi\bia\ba\ba\bal\bl\bl\bl c\bc\bc\bch\bh\bh\bha\ba\ba\bar\br\br\bra\ba\ba\bac\bc\bc\bct\bt\bt\bte\be\be\ber\br\br\brs\bs\bs\bs a\ba\ba\ban\bn\bn\bnd\bd\bd\bd r\br\br\bre\be\be\bes\bs\bs\bse\be\be\ber\br\br\brv\bv\bv\bve\be\be\bed\bd\bd\bd w\bw\bw\bwo\bo\bo\bor\br\br\brd\bd\bd\bds\bs\bs\bs:\b:\b:\b:
+
+       The pound sign ('#') is used to indicate a comment (unless
+       it occurs in the context of a user name and is followed by
+       one or more digits, in which case it is treated as a uid).
+       Both the comment character and any text after it, up to
+       the end of the line, are ignored.
+
+       The reserved word A\bA\bA\bAL\bL\bL\bLL\bL\bL\bL is a built in _\ba_\bl_\bi_\ba_\bs that always
+       causes a match to succeed.  It can be used wherever one
+       might otherwise use a Cmnd_Alias, User_Alias, Runas_Alias,
+       or Host_Alias.  You should not try to define your own
+       _\ba_\bl_\bi_\ba_\bs called A\bA\bA\bAL\bL\bL\bLL\bL\bL\bL as the built in alias will be used in
+       preference to your own.  Please note that using A\bA\bA\bAL\bL\bL\bLL\bL\bL\bL can be
+       dangerous since in a command context, it allows the user
+       to run a\ba\ba\ban\bn\bn\bny\by\by\by command on the system.
+
+       An exclamation point ('!') can be used as a logical _\bn_\bo_\bt
+       operator both in an _\ba_\bl_\bi_\ba_\bs and in front of a Cmnd.  This
+       allows one to exclude certain values.  Note, however, that
+       using a ! in conjunction with the built in ALL alias to
+       allow a user to run "all but a few" commands rarely works
+       as intended (see SECURITY NOTES below).
+
+       Long lines can be continued with a backslash ('\') as the
+       last character on the line.
+
+       Whitespace between elements in a list as well as special
+       syntactic characters in a _\bU_\bs_\be_\br _\bS_\bp_\be_\bc_\bi_\bf_\bi_\bc_\ba_\bt_\bi_\bo_\bn ('=', ':',
+       '(', ')') is optional.
+
+
+
+
+April 25, 2002                1.6.6                            14
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       The following characters must be escaped with a backslash
+       ('\') when used as part of a word (e.g. a username or
+       hostname): '@', '!', '=', ':', ',', '(', ')', '\'.
+
+E\bE\bE\bEX\bX\bX\bXA\bA\bA\bAM\bM\bM\bMP\bP\bP\bPL\bL\bL\bLE\bE\bE\bES\bS\bS\bS
+       Below are example _\bs_\bu_\bd_\bo_\be_\br_\bs entries.  Admittedly, some of
+       these are a bit contrived.  First, we define our _\ba_\bl_\bi_\ba_\bs_\be_\bs:
+
+        # User alias specification
+        User_Alias     FULLTIMERS = millert, mikef, dowdy
+        User_Alias     PARTTIMERS = bostley, jwfox, crawl
+        User_Alias     WEBMASTERS = will, wendy, wim
+
+        # Runas alias specification
+        Runas_Alias    OP = root, operator
+        Runas_Alias    DB = oracle, sybase
+
+        # Host alias specification
+        Host_Alias     SPARC = bigtime, eclipse, moet, anchor :\
+                       SGI = grolsch, dandelion, black :\
+                       ALPHA = widget, thalamus, foobar :\
+                       HPPA = boa, nag, python
+        Host_Alias     CUNETS = 128.138.0.0/255.255.0.0
+        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
+
+        # Cmnd alias specification
+        Cmnd_Alias     DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
+                               /usr/sbin/restore, /usr/sbin/rrestore
+        Cmnd_Alias     KILL = /usr/bin/kill
+        Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+        Cmnd_Alias     SHUTDOWN = /usr/sbin/shutdown
+        Cmnd_Alias     HALT = /usr/sbin/halt, /usr/sbin/fasthalt
+        Cmnd_Alias     REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
+        Cmnd_Alias     SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
+                                /usr/local/bin/tcsh, /usr/bin/rsh, \
+                                /usr/local/bin/zsh
+        Cmnd_Alias     SU = /usr/bin/su
+
+       Here we override some of the compiled in default values.
+       We want s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to log via _\bs_\by_\bs_\bl_\bo_\bg(3) using the _\ba_\bu_\bt_\bh facility
+       in all cases.  We don't want to subject the full time
+       staff to the s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo lecture, and user m\bm\bm\bmi\bi\bi\bil\bl\bl\bll\bl\bl\ble\be\be\ber\br\br\brt\bt\bt\bt need not give
+       a password.  In addition, on the machines in the _\bS_\bE_\bR_\bV_\bE_\bR_\bS
+       Host_Alias, we keep an additional local log file and make
+       sure we log the year in each log line since the log
+       entries will be kept around for several years.
+
+        # Override built in defaults
+        Defaults               syslog=auth
+        Defaults:FULLTIMERS    !lecture
+        Defaults:millert       !authenticate
+        Defaults@SERVERS       log_year, logfile=/var/log/sudo.log
+
+
+
+April 25, 2002                1.6.6                            15
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       The _\bU_\bs_\be_\br _\bs_\bp_\be_\bc_\bi_\bf_\bi_\bc_\ba_\bt_\bi_\bo_\bn is the part that actually deter­
+       mines who may run what.
+
+        root           ALL = (ALL) ALL
+        %wheel         ALL = (ALL) ALL
+
+       We let r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt and any user in group w\bw\bw\bwh\bh\bh\bhe\be\be\bee\be\be\bel\bl\bl\bl run any command on
+       any host as any user.
+
+        FULLTIMERS     ALL = NOPASSWD: ALL
+
+       Full time sysadmins (m\bm\bm\bmi\bi\bi\bil\bl\bl\bll\bl\bl\ble\be\be\ber\br\br\brt\bt\bt\bt, m\bm\bm\bmi\bi\bi\bik\bk\bk\bke\be\be\bef\bf\bf\bf, and d\bd\bd\bdo\bo\bo\bow\bw\bw\bwd\bd\bd\bdy\by\by\by) may run
+       any command on any host without authenticating themselves.
+
+        PARTTIMERS     ALL = ALL
+
+       Part time sysadmins (b\bb\bb\bbo\bo\bo\bos\bs\bs\bst\bt\bt\btl\bl\bl\ble\be\be\bey\by\by\by, j\bj\bj\bjw\bw\bw\bwf\bf\bf\bfo\bo\bo\box\bx\bx\bx, and c\bc\bc\bcr\br\br\bra\ba\ba\baw\bw\bw\bwl\bl\bl\bl) may run
+       any command on any host but they must authenticate them­
+       selves first (since the entry lacks the NOPASSWD tag).
+
+        jack           CSNETS = ALL
+
+       The user j\bj\bj\bja\ba\ba\bac\bc\bc\bck\bk\bk\bk may run any command on the machines in the
+       _\bC_\bS_\bN_\bE_\bT_\bS alias (the networks 128.138.243.0, 128.138.204.0,
+       and 128.138.242.0).  Of those networks, only 128.138.204.0
+       has an explicit netmask (in CIDR notation) indicating it
+       is a class C network.  For the other networks in _\bC_\bS_\bN_\bE_\bT_\bS,
+       the local machine's netmask will be used during matching.
+
+        lisa           CUNETS = ALL
+
+       The user l\bl\bl\bli\bi\bi\bis\bs\bs\bsa\ba\ba\ba may run any command on any host in the
+       _\bC_\bU_\bN_\bE_\bT_\bS alias (the class B network 128.138.0.0).
+
+        operator       ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
+                       /usr/oper/bin/
+
+       The o\bo\bo\bop\bp\bp\bpe\be\be\ber\br\br\bra\ba\ba\bat\bt\bt\bto\bo\bo\bor\br\br\br user may run commands limited to simple main­
+       tenance.  Here, those are commands related to backups,
+       killing processes, the printing system, shutting down the
+       system, and any commands in the directory _\b/_\bu_\bs_\br_\b/_\bo_\bp_\be_\br_\b/_\bb_\bi_\bn_\b/.
+
+        joe            ALL = /usr/bin/su operator
+
+       The user j\bj\bj\bjo\bo\bo\boe\be\be\be may only _\bs_\bu(1) to operator.
+
+        pete           HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
+
+       The user p\bp\bp\bpe\be\be\bet\bt\bt\bte\be\be\be is allowed to change anyone's password
+       except for root on the _\bH_\bP_\bP_\bA machines.  Note that this
+       assumes _\bp_\ba_\bs_\bs_\bw_\bd(1) does not take multiple usernames on the
+       command line.
+
+        bob            SPARC = (OP) ALL : SGI = (OP) ALL
+
+
+
+April 25, 2002                1.6.6                            16
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+       The user b\bb\bb\bbo\bo\bo\bob\bb\bb\bb may run anything on the _\bS_\bP_\bA_\bR_\bC and _\bS_\bG_\bI
+       machines as any user listed in the _\bO_\bP Runas_Alias (r\br\br\bro\bo\bo\boo\bo\bo\bot\bt\bt\bt
+       and o\bo\bo\bop\bp\bp\bpe\be\be\ber\br\br\bra\ba\ba\bat\bt\bt\bto\bo\bo\bor\br\br\br).
+
+        jim            +biglab = ALL
+
+       The user j\bj\bj\bji\bi\bi\bim\bm\bm\bm may run any command on machines in the _\bb_\bi_\bg_\bl_\ba_\bb
+       netgroup.  S\bS\bS\bSu\bu\bu\bud\bd\bd\bdo\bo\bo\bo knows that "biglab" is a netgroup due to
+       the '+' prefix.
+
+        +secretaries   ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+
+       Users in the s\bs\bs\bse\be\be\bec\bc\bc\bcr\br\br\bre\be\be\bet\bt\bt\bta\ba\ba\bar\br\br\bri\bi\bi\bie\be\be\bes\bs\bs\bs netgroup need to help manage the
+       printers as well as add and remove users, so they are
+       allowed to run those commands on all machines.
+
+        fred           ALL = (DB) NOPASSWD: ALL
+
+       The user f\bf\bf\bfr\br\br\bre\be\be\bed\bd\bd\bd can run commands as any user in the _\bD_\bB
+       Runas_Alias (o\bo\bo\bor\br\br\bra\ba\ba\bac\bc\bc\bcl\bl\bl\ble\be\be\be or s\bs\bs\bsy\by\by\byb\bb\bb\bba\ba\ba\bas\bs\bs\bse\be\be\be) without giving a password.
+
+        john           ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+
+       On the _\bA_\bL_\bP_\bH_\bA machines, user j\bj\bj\bjo\bo\bo\boh\bh\bh\bhn\bn\bn\bn may su to anyone except
+       root but he is not allowed to give _\bs_\bu(1) any flags.
+
+        jen            ALL, !SERVERS = ALL
+
+       The user j\bj\bj\bje\be\be\ben\bn\bn\bn may run any command on any machine except for
+       those in the _\bS_\bE_\bR_\bV_\bE_\bR_\bS Host_Alias (master, mail, www and
+       ns).
+
+        jill           SERVERS = /usr/bin/, !SU, !SHELLS
+
+       For any machine in the _\bS_\bE_\bR_\bV_\bE_\bR_\bS Host_Alias, j\bj\bj\bji\bi\bi\bil\bl\bl\bll\bl\bl\bl may run
+       any commands in the directory /usr/bin/ except for those
+       commands belonging to the _\bS_\bU and _\bS_\bH_\bE_\bL_\bL_\bS Cmnd_Aliases.
+
+        steve          CSNETS = (operator) /usr/local/op_commands/
+
+       The user s\bs\bs\bst\bt\bt\bte\be\be\bev\bv\bv\bve\be\be\be may run any command in the directory
+       /usr/local/op_commands/ but only as user operator.
+
+        matt           valkyrie = KILL
+
+       On his personal workstation, valkyrie, m\bm\bm\bma\ba\ba\bat\bt\bt\btt\bt\bt\bt needs to be
+       able to kill hung processes.
+
+        WEBMASTERS     www = (www) ALL, (root) /usr/bin/su www
+
+       On the host www, any user in the _\bW_\bE_\bB_\bM_\bA_\bS_\bT_\bE_\bR_\bS User_Alias
+       (will, wendy, and wim), may run any command as user www
+       (which owns the web pages) or simply _\bs_\bu(1) to www.
+
+
+
+
+April 25, 2002                1.6.6                            17
+
+
+
+
+
+sudoers(4)             MAINTENANCE COMMANDS            sudoers(4)
+
+
+        ALL            CDROM = NOPASSWD: /sbin/umount /CDROM,\
+                       /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
+
+       Any user may mount or unmount a CD-ROM on the machines in
+       the CDROM Host_Alias (orion, perseus, hercules) without
+       entering a password.  This is a bit tedious for users to
+       type, so it is a prime candidate for encapsulating in a
+       shell script.
+
+S\bS\bS\bSE\bE\bE\bEC\bC\bC\bCU\bU\bU\bUR\bR\bR\bRI\bI\bI\bIT\bT\bT\bTY\bY\bY\bY N\bN\bN\bNO\bO\bO\bOT\bT\bT\bTE\bE\bE\bES\bS\bS\bS
+       It is generally not effective to "subtract" commands from
+       ALL using the '!' operator.  A user can trivially circum­
+       vent this by copying the desired command to a different
+       name and then executing that.  For example:
+
+           bill        ALL = ALL, !SU, !SHELLS
+
+       Doesn't really prevent b\bb\bb\bbi\bi\bi\bil\bl\bl\bll\bl\bl\bl from running the commands
+       listed in _\bS_\bU or _\bS_\bH_\bE_\bL_\bL_\bS since he can simply copy those com­
+       mands to a different name, or use a shell escape from an
+       editor or other program.  Therefore, these kind of
+       restrictions should be considered advisory at best (and
+       reinforced by policy).
+
+C\bC\bC\bCA\bA\bA\bAV\bV\bV\bVE\bE\bE\bEA\bA\bA\bAT\bT\bT\bTS\bS\bS\bS
+       The _\bs_\bu_\bd_\bo_\be_\br_\bs file should a\ba\ba\bal\bl\bl\blw\bw\bw\bwa\ba\ba\bay\by\by\bys\bs\bs\bs be edited by the v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo
+       command which locks the file and does grammatical check­
+       ing. It is imperative that _\bs_\bu_\bd_\bo_\be_\br_\bs be free of syntax
+       errors since s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will not run with a syntactically incor­
+       rect _\bs_\bu_\bd_\bo_\be_\br_\bs file.
+
+       When using netgroups of machines (as opposed to users), if
+       you store fully qualified hostnames in the netgroup (as is
+       usually the case), you either need to have the machine's
+       hostname be fully qualified as returned by the hostname
+       command or use the _\bf_\bq_\bd_\bn option in _\bs_\bu_\bd_\bo_\be_\br_\bs.
+
+F\bF\bF\bFI\bI\bI\bIL\bL\bL\bLE\bE\bE\bES\bS\bS\bS
+        /etc/sudoers           List of who can run what
+        /etc/group             Local groups file
+        /etc/netgroup          List of network groups
+
+
+S\bS\bS\bSE\bE\bE\bEE\bE\bE\bE A\bA\bA\bAL\bL\bL\bLS\bS\bS\bSO\bO\bO\bO
+       _\br_\bs_\bh(1), _\bs_\bu_\bd_\bo(1m), _\bv_\bi_\bs_\bu_\bd_\bo(8), _\bs_\bu(1), _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3).
+
+
+
+
+
+
+
+
+
+
+
+
+April 25, 2002                1.6.6                            18
+
+
diff --git a/sudoers.man.in b/sudoers.man.in
new file mode 100644 (file)
index 0000000..e75ab0e
--- /dev/null
@@ -0,0 +1,1090 @@
+.\" Automatically generated by Pod::Man version 1.15
+.\" Thu Apr 25 09:34:54 2002
+.\"
+.\" Standard preamble:
+.\" ======================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+
+.fi
+..
+.\" 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
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` 
+.    ds C' 
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" 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 \{\
+.    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
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.bd B 3
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ======================================================================
+.\"
+.IX Title "sudoers @mansectform@"
+.TH sudoers @mansectform@ "1.6.6" "April 25, 2002" "MAINTENANCE COMMANDS"
+.UC
+.SH "NAME"
+sudoers \- list of which users may execute what
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+The \fIsudoers\fR file is composed of two types of entries:
+aliases (basically variables) and user specifications
+(which specify who may run what).  The grammar of \fIsudoers\fR
+will be described below in Extended Backus-Naur Form (\s-1EBNF\s0).
+Don't despair if you don't know what \s-1EBNF\s0 is; it is fairly
+simple, and the definitions below are annotated.
+.Sh "Quick guide to \s-1EBNF\s0"
+.IX Subsection "Quick guide to EBNF"
+\&\s-1EBNF\s0 is a concise and exact way of describing the grammar of a language.
+Each \s-1EBNF\s0 definition is made up of \fIproduction rules\fR.  E.g.,
+.PP
+.Vb 1
+\& symbol ::= definition | alternate1 | alternate2 ...
+.Ve
+Each \fIproduction rule\fR references others and thus makes up a
+grammar for the language.  \s-1EBNF\s0 also contains the following
+operators, which many readers will recognize from regular
+expressions.  Do not, however, confuse them with \*(L"wildcard\*(R"
+characters, which have different meanings.
+.Ip "\f(CW\*(C`?\*(C'\fR" 8
+.IX Item "?"
+Means that the preceding symbol (or group of symbols) is optional.
+That is, it may appear once or not at all.
+.Ip "\f(CW\*(C`*\*(C'\fR" 8
+.IX Item "*"
+Means that the preceding symbol (or group of symbols) may appear
+zero or more times.
+.Ip "\f(CW\*(C`+\*(C'\fR" 8
+.IX Item "+"
+Means that the preceding symbol (or group of symbols) may appear
+one or more times.
+.PP
+Parentheses may be used to group symbols together.  For clarity,
+we will use single quotes ('') to designate what is a verbatim character
+string (as opposed to a symbol name).
+.Sh "Aliases"
+.IX Subsection "Aliases"
+There are four kinds of aliases: \f(CW\*(C`User_Alias\*(C'\fR, \f(CW\*(C`Runas_Alias\*(C'\fR,
+\&\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
+.Vb 1
+\& User_Alias ::= NAME '=' User_List
+.Ve
+.Vb 1
+\& Runas_Alias ::= NAME '=' Runas_List
+.Ve
+.Vb 1
+\& Host_Alias ::= NAME '=' Host_List
+.Ve
+.Vb 1
+\& Cmnd_Alias ::= NAME '=' Cmnd_List
+.Ve
+.Vb 1
+\& NAME ::= [A-Z]([A-Z][0-9]_)*
+.Ve
+Each \fIalias\fR definition is of the form
+.PP
+.Vb 1
+\& Alias_Type NAME = item1, item2, ...
+.Ve
+where \fIAlias_Type\fR is one of \f(CW\*(C`User_Alias\*(C'\fR, \f(CW\*(C`Runas_Alias\*(C'\fR, \f(CW\*(C`Host_Alias\*(C'\fR,
+or \f(CW\*(C`Cmnd_Alias\*(C'\fR.  A \f(CW\*(C`NAME\*(C'\fR is a string of uppercase letters, numbers,
+and the underscore characters ('_').  A \f(CW\*(C`NAME\*(C'\fR \fBmust\fR start with an
+uppercase letter.  It is possible to put several alias definitions
+of the same type on a single line, joined by a colon (':').  E.g.,
+.PP
+.Vb 1
+\& Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+.Ve
+The definitions of what constitutes a valid \fIalias\fR member follow.
+.PP
+.Vb 2
+\& User_List ::= User |
+\&               User ',' User_List
+.Ve
+.Vb 4
+\& User ::= '!'* username |
+\&          '!'* '%'group |
+\&          '!'* '+'netgroup |
+\&          '!'* User_Alias
+.Ve
+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 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.
+.PP
+.Vb 2
+\& Runas_List ::= Runas_User |
+\&                Runas_User ',' Runas_List
+.Ve
+.Vb 5
+\& Runas_User ::= '!'* username |
+\&                '!'* '#'uid |
+\&                '!'* '%'group |
+\&                '!'* +netgroup |
+\&                '!'* Runas_Alias
+.Ve
+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.
+.PP
+.Vb 2
+\& Host_List ::= Host |
+\&               Host ',' Host_List
+.Ve
+.Vb 5
+\& Host ::= '!'* hostname |
+\&          '!'* ip_addr |
+\&          '!'* network(/netmask)? |
+\&          '!'* '+'netgroup |
+\&          '!'* Host_Alias
+.Ve
+A \f(CW\*(C`Host_List\*(C'\fR is made up of one or more hostnames, \s-1IP\s0 addresses,
+network numbers, netgroups (prefixed with '+') and other aliases.
+Again, the value of an item may be negated with the '!' operator.
+If you do not specify a netmask with a network number, the netmask
+of the host's ethernet \fIinterface\fR\|(s) will be used when matching.
+The netmask may be specified either in dotted quad notation (e.g.
+255.255.255.0) or \s-1CIDR\s0 notation (number of bits, e.g. 24).  A hostname
+may include shell-style wildcards (see `Wildcards' section below),
+but unless the \f(CW\*(C`hostname\*(C'\fR command on your machine returns the fully
+qualified hostname, you'll need to use the \fIfqdn\fR option for wildcards
+to be useful.
+.PP
+.Vb 2
+\& Cmnd_List ::= Cmnd |
+\&               Cmnd ',' Cmnd_List
+.Ve
+.Vb 3
+\& commandname ::= filename |
+\&                 filename args |
+\&                 filename '""'
+.Ve
+.Vb 3
+\& Cmnd ::= '!'* commandname |
+\&          '!'* directory |
+\&          '!'* Cmnd_Alias
+.Ve
+A \f(CW\*(C`Cmnd_List\*(C'\fR is a list of one or more commandnames, directories, and other
+aliases.  A commandname is a fully qualified filename which may include
+shell-style wildcards (see `Wildcards' section below).  A simple
+filename allows the user to run the command with any arguments he/she
+wishes.  However, you may also specify command line arguments (including
+wildcards).  Alternately, you can specify \f(CW\*(C`""\*(C'\fR to indicate that the command
+may only be run \fBwithout\fR command line arguments.  A directory is a
+fully qualified pathname ending in a '/'.  When you specify a directory
+in a \f(CW\*(C`Cmnd_List\*(C'\fR, the user will be able to run any file within that directory
+(but not in any subdirectories therein).
+.PP
+If a \f(CW\*(C`Cmnd\*(C'\fR has associated command line arguments, then the arguments
+in the \f(CW\*(C`Cmnd\*(C'\fR must match exactly those given by the user on the command line
+(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'.
+.Sh "Defaults"
+.IX Subsection "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,
+or just a specific user.  When multiple entries match, they are
+applied in order.  Where there are conflicting values, the last
+value on a matching line takes effect.
+.PP
+.Vb 3
+\& Default_Type ::= 'Defaults' ||
+\&                  'Defaults' ':' User ||
+\&                  'Defaults' '@' Host
+.Ve
+.Vb 1
+\& Default_Entry ::= Default_Type Parameter_List
+.Ve
+.Vb 4
+\& Parameter ::= Parameter '=' Value ||
+\&               Parameter '+=' Value ||
+\&               Parameter '-=' Value ||
+\&               '!'* Parameter ||
+.Ve
+Parameters may be \fBflags\fR, \fBinteger\fR values, \fBstrings\fR, or \fBlists\fR.
+Flags are implicitly boolean and can be turned off via the '!'
+operator.  Some integer, string and list parameters may also be
+used in a boolean context to disable them.  Values may be enclosed
+in double quotes (\f(CW\*(C`"\*(C'\fR) when they contain multiple words.  Special
+characters may be escaped with a backslash (\f(CW\*(C`\e\*(C'\fR).
+.PP
+Lists have two additional assignment operators, \f(CW\*(C`+=\*(C'\fR and \f(CW\*(C`\-=\*(C'\fR.
+These operators are used to add to and delete from a list respectively.
+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
+Note that since the \fIsudoers\fR file is parsed in order the best place
+to put the Defaults section is after the Host, User, and Cmnd aliases
+but before the user specifications.
+.PP
+\&\fBFlags\fR:
+.Ip "long_otp_prompt" 12
+.IX Item "long_otp_prompt"
+When validating with a One Time Password scheme (\fBS/Key\fR or \fB\s-1OPIE\s0\fR),
+a two-line prompt is used to make it easier to cut and paste the
+challenge to a local window.  It's not as pretty as the default but
+some people find it more convenient.  This flag is \fI@long_otp_prompt@\fR
+by default.
+.Ip "ignore_dot" 12
+.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.
+.Ip "mail_always" 12
+.IX Item "mail_always"
+Send mail to the \fImailto\fR user every time a users runs \fBsudo\fR.
+This flag is \fIoff\fR by default.
+.Ip "mail_badpass" 12
+.IX Item "mail_badpass"
+Send mail to the \fImailto\fR user if the user running sudo does not
+enter the correct password.  This flag is \fIoff\fR by default.
+.Ip "mail_no_user" 12
+.IX Item "mail_no_user"
+If set, mail will be sent to the \fImailto\fR user if the invoking
+user is not in the \fIsudoers\fR file.  This flag is \fI@mail_no_user@\fR
+by default.
+.Ip "mail_no_host" 12
+.IX Item "mail_no_host"
+If set, mail will be sent to the \fImailto\fR user if the invoking
+user exists in the \fIsudoers\fR file, but is not allowed to run
+commands on the current host.  This flag is \fI@mail_no_host@\fR by default.
+.Ip "mail_no_perms" 12
+.IX Item "mail_no_perms"
+If set, mail will be sent to the \fImailto\fR user if the invoking
+user allowed to use \fBsudo\fR but the command they are trying is not
+listed in their \fIsudoers\fR file entry.  This flag is \fI@mail_no_perms@\fR
+by default.
+.Ip "tty_tickets" 12
+.IX Item "tty_tickets"
+If set, users must authenticate on a per-tty basis.  Normally,
+\&\fBsudo\fR uses a directory in the ticket dir with the same name as
+the user running it.  With this flag enabled, \fBsudo\fR will use a
+file named for the tty the user is logged in on in that directory.
+This flag is \fI@tty_tickets@\fR by default.
+.Ip "lecture" 12
+.IX Item "lecture"
+If set, a user will receive a short lecture the first time he/she
+runs \fBsudo\fR.  This flag is \fI@lecture@\fR by default.
+.Ip "authenticate" 12
+.IX Item "authenticate"
+If set, users must authenticate themselves via a password (or other
+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 "root_sudo" 12
+.IX Item "root_sudo"
+If set, root is allowed to run \fBsudo\fR too.  Disabling this prevents users
+from \*(L"chaining\*(R" \fBsudo\fR commands to get a root shell by doing something
+like \f(CW\*(C`"sudo sudo /bin/sh"\*(C'\fR.
+This flag is \fIon\fR by default.
+.Ip "log_host" 12
+.IX Item "log_host"
+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" 12
+.IX Item "log_year"
+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 "shell_noargs" 12
+.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
+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.
+.Ip "set_home" 12
+.IX Item "set_home"
+If set and \fBsudo\fR is invoked with the \fB\-s\fR flag 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.
+.Ip "always_set_home" 12
+.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 flag is \fIoff\fR by default.
+.Ip "path_info" 12
+.IX Item "path_info"
+Normally, \fBsudo\fR will tell the user when a command could not be
+found in their \f(CW\*(C`PATH\*(C'\fR environment variable.  Some sites may wish
+to disable this as it could be used to gather information on the
+location of executables that the normal user does not have access
+to.  The disadvantage is that if the executable is simply not in
+the user's \f(CW\*(C`PATH\*(C'\fR, \fBsudo\fR will tell the user that they are not
+allowed to run it, which can be confusing.  This flag is \fIoff\fR by
+default.
+.Ip "preserve_groups" 12
+.IX Item "preserve_groups"
+By default \fBsudo\fR will initialize the group vector to the list of
+groups the target user is in.  When \fIpreserve_groups\fR is set, the
+user's existing group vector is left unaltered.  The real and
+effective group IDs, however, are still set to match the target
+user.  This flag is \fIoff\fR by default.
+.Ip "fqdn" 12
+.IX Item "fqdn"
+Set this flag if you want to put fully qualified hostnames in the
+\&\fIsudoers\fR file.  I.e.: instead of myhost you would use myhost.mydomain.edu.
+You may still use the short form if you wish (and even mix the two).
+Beware that turning on \fIfqdn\fR requires \fBsudo\fR to make \s-1DNS\s0 lookups
+which may make \fBsudo\fR unusable if \s-1DNS\s0 stops working (for example
+if the machine is not plugged into the network).  Also note that
+you must use the host's official name as \s-1DNS\s0 knows it.  That is,
+you may not use a host alias (\f(CW\*(C`CNAME\*(C'\fR entry) due to performance
+issues and the fact that there is no way to get all aliases from
+\&\s-1DNS\s0.  If your machine's hostname (as returned by the \f(CW\*(C`hostname\*(C'\fR
+command) is already fully qualified you shouldn't need to set
+\&\fIfqdn\fR.  This flag is \fI@fqdn@\fR by default.
+.Ip "insults" 12
+.IX Item "insults"
+If set, \fBsudo\fR will insult users when they enter an incorrect
+password.  This flag is \fI@insults@\fR by default.
+.Ip "requiretty" 12
+.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\*(C`"rsh somehost sudo ls"\*(C'\fR since
+\&\fIrsh\fR\|(1) does not allocate a tty.  Because it is not possible to turn
+of echo when there is no tty present, some sites may with to set
+this flag to prevent a user from entering a visible password.  This
+flag is \fIoff\fR by default.
+.Ip "env_editor" 12
+.IX Item "env_editor"
+If set, \fBvisudo\fR will use the value of the \s-1EDITOR\s0 or \s-1VISUAL\s0
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.  A safer alternative
+is to place a colon-separated list of editors in the \f(CW\*(C`editor\*(C'\fR
+variable.  \fBvisudo\fR will then only use the \s-1EDITOR\s0 or \s-1VISUAL\s0 if
+they match a value specified in \f(CW\*(C`editor\*(C'\fR.  This flag is \f(CW\*(C`@env_editor@\*(C'\fR by
+default.
+.Ip "rootpw" 12
+.IX Item "rootpw"
+If set, \fBsudo\fR will prompt for the root password instead of the password
+of the invoking user.  This flag is \fIoff\fR by default.
+.Ip "runaspw" 12
+.IX Item "runaspw"
+If set, \fBsudo\fR will prompt for the password of the user defined by the
+\&\fIrunas_default\fR option (defaults to \f(CW\*(C`root\*(C'\fR) instead of the password
+of the invoking user.  This flag is \fIoff\fR by default.
+.Ip "targetpw" 12
+.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
+invoking user.  This flag is \fIoff\fR by default.
+.Ip "set_logname" 12
+.IX Item "set_logname"
+Normally, \fBsudo\fR will set the \f(CW\*(C`LOGNAME\*(C'\fR and \f(CW\*(C`USER\*(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 (including the \s-1RCS\s0 revision control system)
+use \f(CW\*(C`LOGNAME\*(C'\fR to determine the real identity of the user, it may be desirable
+to change this behavior.  This can be done by negating the set_logname option.
+.Ip "stay_setuid" 12
+.IX Item "stay_setuid"
+Normally, when \fBsudo\fR executes a command the real and effective
+UIDs are set to the target user (root by default).  This option
+changes that behavior such that the real \s-1UID\s0 is left as the invoking
+user's \s-1UID\s0.  In other words, this makes \fBsudo\fR act as a setuid
+wrapper.  This can be useful on systems that disable some potentially
+dangerous functionality when a program is run setuid.  Note, however,
+that this means that sudo will run with the real uid of the invoking
+user which may allow that user to kill \fBsudo\fR before it can log a
+failure, depending on how your \s-1OS\s0 defines the interaction between
+signals and setuid processes.
+.Ip "env_reset" 12
+.IX Item "env_reset"
+If set, \fBsudo\fR will reset the environment to only contain the
+following variables: \f(CW\*(C`HOME\*(C'\fR, \f(CW\*(C`LOGNAME\*(C'\fR, \f(CW\*(C`PATH\*(C'\fR, \f(CW\*(C`SHELL\*(C'\fR, \f(CW\*(C`TERM\*(C'\fR,
+and \f(CW\*(C`USER\*(C'\fR (in addition to the \f(CW\*(C`SUDO_*\*(C'\fR variables).
+Of these, only \f(CW\*(C`TERM\*(C'\fR is copied unaltered from the old environment.
+The other variables are set to default values (possibly modified
+by the value of the \fIset_logname\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.
+Other variables may be preserved with the \fIenv_keep\fR option.
+.Ip "use_loginclass" 12
+.IX Item "use_loginclass"
+If set, \fBsudo\fR will apply the defaults specified for the target user's
+login class if one exists.  Only available if \fBsudo\fR is configured with
+the \-\-with-logincap option.  This flag is \fIoff\fR by default.
+.PP
+\&\fBIntegers\fR:
+.Ip "passwd_tries" 12
+.IX Item "passwd_tries"
+The number of tries a user gets to enter his/her password before
+\&\fBsudo\fR logs the failure and exits.  The default is \f(CW\*(C`@passwd_tries@\*(C'\fR.
+.PP
+\&\fBIntegers that can be used in a boolean context\fR:
+.Ip "loglinelen" 12
+.IX Item "loglinelen"
+Number of characters per line for the file log.  This value is used
+to decide when to wrap lines for nicer log files.  This has no
+effect on the syslog log file, only the file log.  The default is
+\&\f(CW\*(C`@loglen@\*(C'\fR (use 0 or negate the option to disable word wrap).
+.Ip "timestamp_timeout" 12
+.IX Item "timestamp_timeout"
+Number of minutes that can elapse before \fBsudo\fR will ask for a
+passwd again.  The default is \f(CW\*(C`@timeout@\*(C'\fR.  Set this to \f(CW\*(C`0\*(C'\fR to always
+prompt for a password.
+If set to a value less than \f(CW\*(C`0\*(C'\fR the user's timestamp will never
+expire.  This can be used to allow users to create or delete their
+own timestamps via \f(CW\*(C`sudo \-v\*(C'\fR and \f(CW\*(C`sudo \-k\*(C'\fR respectively.
+.Ip "passwd_timeout" 12
+.IX Item "passwd_timeout"
+Number of minutes before the \fBsudo\fR password prompt times out.
+The default is \f(CW\*(C`@password_timeout@\*(C'\fR, set this to \f(CW\*(C`0\*(C'\fR for no password timeout.
+.Ip "umask" 12
+.IX Item "umask"
+Umask to use when running the command.  Negate this option or set
+it to 0777 to preserve the user's umask.  The default is \f(CW\*(C`@sudo_umask@\*(C'\fR.
+.PP
+\&\fBStrings\fR:
+.Ip "mailsub" 12
+.IX Item "mailsub"
+Subject of the mail sent to the \fImailto\fR user. The escape \f(CW\*(C`%h\*(C'\fR
+will expand to the hostname of the machine.
+Default is \f(CW\*(C`@mailsub@\*(C'\fR.
+.Ip "badpass_message" 12
+.IX Item "badpass_message"
+Message that is displayed if a user enters an incorrect password.
+The default is \f(CW\*(C`@badpass_message@\*(C'\fR unless insults are enabled.
+.Ip "timestampdir" 12
+.IX Item "timestampdir"
+The directory in which \fBsudo\fR stores its timestamp files.
+The default is \fI@timedir@\fR.
+.Ip "passprompt" 12
+.IX Item "passprompt"
+The default prompt to use when asking for a password; can be overridden
+via the \fB\-p\fR option or the \f(CW\*(C`SUDO_PROMPT\*(C'\fR environment variable. Supports
+two escapes: \*(L"%u\*(R" expands to the user's login name and \*(L"%h\*(R" expands
+to the local hostname.  The default value is \f(CW\*(C`@passprompt@\*(C'\fR.
+.Ip "runas_default" 12
+.IX Item "runas_default"
+The default user to run commands as if the \fB\-u\fR flag is not specified
+on the command line.  This defaults to \f(CW\*(C`@runas_default@\*(C'\fR.
+.Ip "syslog_goodpri" 12
+.IX Item "syslog_goodpri"
+Syslog priority to use when user authenticates successfully.
+Defaults to \f(CW\*(C`@goodpri@\*(C'\fR.
+.Ip "syslog_badpri" 12
+.IX Item "syslog_badpri"
+Syslog priority to use when user authenticates unsuccessfully.
+Defaults to \f(CW\*(C`@badpri@\*(C'\fR.
+.Ip "editor" 12
+.IX Item "editor"
+A colon (':') separated list of editors allowed to be used with
+\&\fBvisudo\fR.  \fBvisudo\fR will choose the editor that matches the user's
+\&\s-1USER\s0 environment variable if possible, or the first editor in the
+list that exists and is executable.  The default is the path to vi
+on your system.
+.PP
+\&\fBStrings that can be used in a boolean context\fR:
+.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.
+.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 "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 "mailerflags" 12
+.IX Item "mailerflags"
+Flags to use when invoking mailer. Defaults to \fB\-t\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 sudo
+interpreting the \f(CW\*(C`@\*(C'\fR sign.  Defaults to \f(CW\*(C`@mailto@\*(C'\fR.
+.Ip "exempt_group" 12
+.IX Item "exempt_group"
+Users in this group are exempt from password and \s-1PATH\s0 requirements.
+This is not set by default.
+.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:
+.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 "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.
+.Ip "always" 8
+.IX Item "always"
+The user must always enter a password to use the \fB\-v\fR flag.
+.RE
+.RS 12
+.Sp
+The default value is `all'.
+.RE
+.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.  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 "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.
+.Ip "always" 8
+.IX Item "always"
+The user must always enter a password to use the \fB\-l\fR flag.
+.RE
+.RS 12
+.Sp
+The default value is `any'.
+.RE
+.PP
+\&\fBLists that can be used in a boolean context\fR:
+.Ip "env_check" 12
+.IX Item "env_check"
+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 vulnerabilties in
+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.  The default
+list of environment variable to check is printed when \fBsudo\fR is
+run by root with the \fI\-V\fR option.
+.Ip "env_delete" 12
+.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
+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
+variable to remove is printed when \fBsudo\fR is run by root with the
+\&\fI\-V\fR option.
+.Ip "env_keep" 12
+.IX Item "env_keep"
+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
+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.  This list has no default members.
+.PP
+When logging via \fIsyslog\fR\|(3), \fBsudo\fR accepts the following values for the syslog
+facility (the value of the \fBsyslog\fR Parameter): \fBauthpriv\fR (if your \s-1OS\s0
+supports it), \fBauth\fR, \fBdaemon\fR, \fBuser\fR, \fBlocal0\fR, \fBlocal1\fR, \fBlocal2\fR,
+\&\fBlocal3\fR, \fBlocal4\fR, \fBlocal5\fR, \fBlocal6\fR, and \fBlocal7\fR.  The following
+syslog priorities are supported: \fBalert\fR, \fBcrit\fR, \fBdebug\fR, \fBemerg\fR,
+\&\fBerr\fR, \fBinfo\fR, \fBnotice\fR, and \fBwarning\fR.
+.Sh "User Specification"
+.IX Subsection "User Specification"
+.Vb 2
+\& User_Spec ::= User_list Host_List '=' Cmnd_Spec_List \e
+\&               (':' User_Spec)*
+.Ve
+.Vb 2
+\& Cmnd_Spec_List ::= Cmnd_Spec |
+\&                    Cmnd_Spec ',' Cmnd_Spec_List
+.Ve
+.Vb 1
+\& Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
+.Ve
+.Vb 1
+\& Runas_Spec ::= '(' Runas_List ')'
+.Ve
+A \fBuser specification\fR determines which commands a user may run
+(and as what user) on specified hosts.  By default, commands are
+run as \fBroot\fR, but this can be changed on a per-command basis.
+.PP
+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:
+.PP
+.Vb 1
+\& dgb    boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
+.Ve
+The user \fBdgb\fR may run \fI/bin/ls\fR, \fI/bin/kill\fR, and
+\&\fI/usr/bin/lprm\fR \*(-- but only as \fBoperator\fR.  E.g.,
+.PP
+.Vb 1
+\&    sudo -u operator /bin/ls.
+.Ve
+It is also possible to override a \f(CW\*(C`Runas_Spec\*(C'\fR later on in an
+entry.  If we modify the entry like so:
+.PP
+.Vb 1
+\& dgb    boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+.Ve
+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.
+.Sh "\s-1NOPASSWD\s0 and \s-1PASSWD\s0"
+.IX Subsection "NOPASSWD and PASSWD"
+By default, \fBsudo\fR requires that a user authenticate him or herself
+before running a command.  This behavior can be modified via the
+\&\f(CW\*(C`NOPASSWD\*(C'\fR tag.  Like a \f(CW\*(C`Runas_Spec\*(C'\fR, the \f(CW\*(C`NOPASSWD\*(C'\fR tag sets
+a default for the commands that follow it in the \f(CW\*(C`Cmnd_Spec_List\*(C'\fR.
+Conversely, the \f(CW\*(C`PASSWD\*(C'\fR tag can be used to reverse things.
+For example:
+.PP
+.Vb 1
+\& ray    rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
+.Ve
+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
+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
+.Vb 1
+\& ray    rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+.Ve
+Note, however, that the \f(CW\*(C`PASSWD\*(C'\fR tag has no effect on users who are
+in the group specified by the exempt_group option.
+.PP
+By default, if the \f(CW\*(C`NOPASSWD\*(C'\fR tag is applied to any of the entries
+for a user on the current host, he or she will be able to run
+\&\f(CW\*(C`sudo \-l\*(C'\fR without a password.  Additionally, a user may only run
+\&\f(CW\*(C`sudo \-v\*(C'\fR without a password if the \f(CW\*(C`NOPASSWD\*(C'\fR tag is present
+for all a user's entries that pertain to the current host.
+This behavior may be overridden via the verifypw and listpw options.
+.Sh "Wildcards (aka meta characters):"
+.IX Subsection "Wildcards (aka meta characters):"
+\&\fBsudo\fR allows shell-style \fIwildcards\fR to be used in pathnames
+as well as command line arguments in the \fIsudoers\fR file.  Wildcard
+matching is done via the \fB\s-1POSIX\s0\fR \f(CW\*(C`fnmatch(3)\*(C'\fR routine.  Note that
+these are \fInot\fR regular expressions.
+.Ip "\f(CW\*(C`*\*(C'\fR" 8
+.IX Item "*"
+Matches any set of zero or more characters.
+.Ip "\f(CW\*(C`?\*(C'\fR" 8
+.IX Item "?"
+Matches any single character.
+.Ip "\f(CW\*(C`[...]\*(C'\fR" 8
+.IX Item "[...]"
+Matches any character in the specified range.
+.Ip "\f(CW\*(C`[!...]\*(C'\fR" 8
+.IX Item "[!...]"
+Matches any character \fBnot\fR in the specified range.
+.Ip "\f(CW\*(C`\ex\*(C'\fR" 8
+.IX Item "x"
+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
+Note that a forward slash ('/') will \fBnot\fR be matched by
+wildcards used in the pathname.  When matching the command
+line arguments, however, as slash \fBdoes\fR get matched by
+wildcards.  This is to make a path like:
+.PP
+.Vb 1
+\&    /usr/bin/*
+.Ve
+match \f(CW\*(C`/usr/bin/who\*(C'\fR but not \f(CW\*(C`/usr/bin/X11/xterm\*(C'\fR.
+.Sh "Exceptions to wildcard rules:"
+.IX Subsection "Exceptions to wildcard rules:"
+The following exceptions apply to the above rules:
+.if n .Ip "\f(CW""""""""\fR" 8
+.el .Ip "\f(CW``''\fR" 8
+.IX Item """""
+If the empty string \f(CW\*(C`""\*(C'\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 "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
+occurs in the context of a user name and is followed by one or
+more digits, in which case it is treated as a uid).  Both the
+comment character and any text after it, up to the end of the line,
+are ignored.
+.PP
+The reserved word \fB\s-1ALL\s0\fR is a built in \fIalias\fR that always causes
+a match to succeed.  It can be used wherever one might otherwise
+use a \f(CW\*(C`Cmnd_Alias\*(C'\fR, \f(CW\*(C`User_Alias\*(C'\fR, \f(CW\*(C`Runas_Alias\*(C'\fR, or \f(CW\*(C`Host_Alias\*(C'\fR.
+You should not try to define your own \fIalias\fR called \fB\s-1ALL\s0\fR as the
+built in alias will be used in preference to your own.  Please note
+that using \fB\s-1ALL\s0\fR can be dangerous since in a command context, it
+allows the user to run \fBany\fR command on the system.
+.PP
+An exclamation point ('!') can be used as a logical \fInot\fR operator
+both in an \fIalias\fR and in front of a \f(CW\*(C`Cmnd\*(C'\fR.  This allows one to
+exclude certain values.  Note, however, that using a \f(CW\*(C`!\*(C'\fR in
+conjunction with the built in \f(CW\*(C`ALL\*(C'\fR alias to allow a user to
+run \*(L"all but a few\*(R" commands rarely works as intended (see \s-1SECURITY\s0
+\&\s-1NOTES\s0 below).
+.PP
+Long lines can be continued with a backslash ('\e') as the last
+character on the line.
+.PP
+Whitespace between elements in a list as well as special syntactic
+characters in a \fIUser Specification\fR ('=', ':', '(', ')') is optional.
+.PP
+The following characters must be escaped with a backslash ('\e') when
+used as part of a word (e.g. a username or hostname):
+\&'@', '!', '=', ':', ',', '(', ')', '\e'.
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+Below are example \fIsudoers\fR entries.  Admittedly, some of
+these are a bit contrived.  First, we define our \fIaliases\fR:
+.PP
+.Vb 4
+\& # User alias specification
+\& User_Alias     FULLTIMERS = millert, mikef, dowdy
+\& User_Alias     PARTTIMERS = bostley, jwfox, crawl
+\& User_Alias     WEBMASTERS = will, wendy, wim
+.Ve
+.Vb 3
+\& # Runas alias specification
+\& Runas_Alias    OP = root, operator
+\& Runas_Alias    DB = oracle, sybase
+.Ve
+.Vb 9
+\& # Host alias specification
+\& Host_Alias     SPARC = bigtime, eclipse, moet, anchor :\e
+\&                SGI = grolsch, dandelion, black :\e
+\&                ALPHA = widget, thalamus, foobar :\e
+\&                HPPA = boa, nag, python
+\& Host_Alias     CUNETS = 128.138.0.0/255.255.0.0
+\& 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
+.Vb 12
+\& # Cmnd alias specification
+\& Cmnd_Alias     DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
+\&                        /usr/sbin/restore, /usr/sbin/rrestore
+\& Cmnd_Alias     KILL = /usr/bin/kill
+\& Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+\& Cmnd_Alias     SHUTDOWN = /usr/sbin/shutdown
+\& Cmnd_Alias     HALT = /usr/sbin/halt, /usr/sbin/fasthalt
+\& Cmnd_Alias     REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
+\& Cmnd_Alias     SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \e
+\&                         /usr/local/bin/tcsh, /usr/bin/rsh, \e
+\&                         /usr/local/bin/zsh
+\& Cmnd_Alias     SU = /usr/bin/su
+.Ve
+Here we override some of the compiled in default values.  We want
+\&\fBsudo\fR to log via \fIsyslog\fR\|(3) using the \fIauth\fR facility in all cases.
+We don't want to subject the full time staff to the \fBsudo\fR lecture,
+and user \fBmillert\fR need not give a password.  In addition, on the
+machines in the \fI\s-1SERVERS\s0\fR \f(CW\*(C`Host_Alias\*(C'\fR, we keep an additional
+local log file and make sure we log the year in each log line since
+the log entries will be kept around for several years.
+.PP
+.Vb 5
+\& # Override built in defaults
+\& Defaults               syslog=auth
+\& Defaults:FULLTIMERS    !lecture
+\& Defaults:millert       !authenticate
+\& Defaults@SERVERS       log_year, logfile=/var/log/sudo.log
+.Ve
+The \fIUser specification\fR is the part that actually determines who may
+run what.
+.PP
+.Vb 2
+\& root           ALL = (ALL) ALL
+\& %wheel         ALL = (ALL) ALL
+.Ve
+We let \fBroot\fR and any user in group \fBwheel\fR run any command on any
+host as any user.
+.PP
+.Vb 1
+\& FULLTIMERS     ALL = NOPASSWD: ALL
+.Ve
+Full time sysadmins (\fBmillert\fR, \fBmikef\fR, and \fBdowdy\fR) may run any
+command on any host without authenticating themselves.
+.PP
+.Vb 1
+\& PARTTIMERS     ALL = ALL
+.Ve
+Part time sysadmins (\fBbostley\fR, \fBjwfox\fR, and \fBcrawl\fR) may run any
+command on any host but they must authenticate themselves first
+(since the entry lacks the \f(CW\*(C`NOPASSWD\*(C'\fR tag).
+.PP
+.Vb 1
+\& jack           CSNETS = ALL
+.Ve
+The user \fBjack\fR may run any command on the machines in the \fI\s-1CSNETS\s0\fR alias
+(the networks \f(CW\*(C`128.138.243.0\*(C'\fR, \f(CW\*(C`128.138.204.0\*(C'\fR, and \f(CW\*(C`128.138.242.0\*(C'\fR).
+Of those networks, only \f(CW\*(C`128.138.204.0\*(C'\fR has an explicit netmask (in
+\&\s-1CIDR\s0 notation) indicating it is a class C network.  For the other
+networks in \fI\s-1CSNETS\s0\fR, the local machine's netmask will be used
+during matching.
+.PP
+.Vb 1
+\& lisa           CUNETS = ALL
+.Ve
+The user \fBlisa\fR may run any command on any host in the \fI\s-1CUNETS\s0\fR alias
+(the class B network \f(CW\*(C`128.138.0.0\*(C'\fR).
+.PP
+.Vb 2
+\& operator       ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\e
+\&                /usr/oper/bin/
+.Ve
+The \fBoperator\fR user may run commands limited to simple maintenance.
+Here, those are commands related to backups, killing processes, the
+printing system, shutting down the system, and any commands in the
+directory \fI/usr/oper/bin/\fR.
+.PP
+.Vb 1
+\& joe            ALL = /usr/bin/su operator
+.Ve
+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
+.Ve
+The user \fBpete\fR is allowed to change anyone's password except for
+root on the \fI\s-1HPPA\s0\fR machines.  Note that this assumes \fIpasswd\fR\|(1)
+does not take multiple usernames on the command line.
+.PP
+.Vb 1
+\& bob            SPARC = (OP) ALL : SGI = (OP) ALL
+.Ve
+The user \fBbob\fR may run anything on the \fI\s-1SPARC\s0\fR and \fI\s-1SGI\s0\fR machines
+as any user listed in the \fI\s-1OP\s0\fR \f(CW\*(C`Runas_Alias\*(C'\fR (\fBroot\fR and \fBoperator\fR).
+.PP
+.Vb 1
+\& jim            +biglab = ALL
+.Ve
+The user \fBjim\fR may run any command on machines in the \fIbiglab\fR netgroup.
+\&\fBSudo\fR knows that \*(L"biglab\*(R" is a netgroup due to the '+' prefix.
+.PP
+.Vb 1
+\& +secretaries   ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+.Ve
+Users in the \fBsecretaries\fR netgroup need to help manage the printers
+as well as add and remove users, so they are allowed to run those
+commands on all machines.
+.PP
+.Vb 1
+\& fred           ALL = (DB) NOPASSWD: ALL
+.Ve
+The user \fBfred\fR can run commands as any user in the \fI\s-1DB\s0\fR \f(CW\*(C`Runas_Alias\*(C'\fR
+(\fBoracle\fR or \fBsybase\fR) without giving a password.
+.PP
+.Vb 1
+\& john           ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+.Ve
+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.
+.PP
+.Vb 1
+\& jen            ALL, !SERVERS = ALL
+.Ve
+The user \fBjen\fR may run any command on any machine except for those
+in the \fI\s-1SERVERS\s0\fR \f(CW\*(C`Host_Alias\*(C'\fR (master, mail, www and ns).
+.PP
+.Vb 1
+\& jill           SERVERS = /usr/bin/, !SU, !SHELLS
+.Ve
+For any machine in the \fI\s-1SERVERS\s0\fR \f(CW\*(C`Host_Alias\*(C'\fR, \fBjill\fR may run
+any commands in the directory /usr/bin/ except for those commands
+belonging to the \fI\s-1SU\s0\fR and \fI\s-1SHELLS\s0\fR \f(CW\*(C`Cmnd_Aliases\*(C'\fR.
+.PP
+.Vb 1
+\& steve          CSNETS = (operator) /usr/local/op_commands/
+.Ve
+The user \fBsteve\fR may run any command in the directory /usr/local/op_commands/
+but only as user operator.
+.PP
+.Vb 1
+\& matt           valkyrie = KILL
+.Ve
+On his personal workstation, valkyrie, \fBmatt\fR needs to be able to
+kill hung processes.
+.PP
+.Vb 1
+\& WEBMASTERS     www = (www) ALL, (root) /usr/bin/su www
+.Ve
+On the host www, any user in the \fI\s-1WEBMASTERS\s0\fR \f(CW\*(C`User_Alias\*(C'\fR (will,
+wendy, and wim), may run any command as user www (which owns the
+web pages) or simply \fIsu\fR\|(1) to www.
+.PP
+.Vb 2
+\& ALL            CDROM = NOPASSWD: /sbin/umount /CDROM,\e
+\&                /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM
+.Ve
+Any user may mount or unmount a \s-1CD-ROM\s0 on the machines in the \s-1CDROM\s0
+\&\f(CW\*(C`Host_Alias\*(C'\fR (orion, perseus, hercules) without entering a password.
+This is a bit tedious for users to type, so it is a prime candidate
+for encapsulating in a shell script.
+.SH "SECURITY NOTES"
+.IX Header "SECURITY NOTES"
+It is generally not effective to \*(L"subtract\*(R" commands from \f(CW\*(C`ALL\*(C'\fR
+using the '!' operator.  A user can trivially circumvent this
+by copying the desired command to a different name and then
+executing that.  For example:
+.PP
+.Vb 1
+\&    bill        ALL = ALL, !SU, !SHELLS
+.Ve
+Doesn't really prevent \fBbill\fR from running the commands listed in
+\&\fI\s-1SU\s0\fR or \fI\s-1SHELLS\s0\fR since he can simply copy those commands to a
+different name, or use a shell escape from an editor or other
+program.  Therefore, these kind of restrictions should be considered
+advisory at best (and reinforced by policy).
+.SH "CAVEATS"
+.IX Header "CAVEATS"
+The \fIsudoers\fR file should \fBalways\fR be edited by the \fBvisudo\fR
+command which locks the file and does grammatical checking. It is
+imperative that \fIsudoers\fR be free of syntax errors since \fBsudo\fR
+will not run with a syntactically incorrect \fIsudoers\fR file.
+.PP
+When using netgroups of machines (as opposed to users), if you
+store fully qualified hostnames in the netgroup (as is usually the
+case), you either need to have the machine's hostname be fully qualified
+as returned by the \f(CW\*(C`hostname\*(C'\fR command or use the \fIfqdn\fR option in
+\&\fIsudoers\fR.
+.SH "FILES"
+.IX Header "FILES"
+.Vb 3
+\& @sysconfdir@/sudoers           List of who can run what
+\& /etc/group             Local groups file
+\& /etc/netgroup          List of network groups
+.Ve
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIrsh\fR\|(1), \fIsudo\fR\|(@mansectsu@), \fIvisudo\fR\|(8), \fIsu\fR\|(1), \fIfnmatch\fR\|(3).
diff --git a/sudoers.pod b/sudoers.pod
new file mode 100644 (file)
index 0000000..80fd724
--- /dev/null
@@ -0,0 +1,1048 @@
+=cut
+Copyright (c) 1994-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission
+   from the author.
+
+4. Products derived from this software may not be called "Sudo" nor
+   may "Sudo" appear in their names without specific prior written
+   permission from the author.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$Sudo: sudoers.pod,v 1.63 2002/01/13 18:36:44 millert Exp $
+=pod
+
+=head1 NAME
+
+sudoers - list of which users may execute what
+
+=head1 DESCRIPTION
+
+The I<sudoers> file is composed of two types of entries:
+aliases (basically variables) and user specifications
+(which specify who may run what).  The grammar of I<sudoers>
+will be described below in Extended Backus-Naur Form (EBNF).
+Don't despair if you don't know what EBNF is; it is fairly
+simple, and the definitions below are annotated.
+
+=head2 Quick guide to EBNF
+
+EBNF is a concise and exact way of describing the grammar of a language.
+Each EBNF definition is made up of I<production rules>.  E.g.,
+
+ symbol ::= definition | alternate1 | alternate2 ...
+
+Each I<production rule> references others and thus makes up a
+grammar for the language.  EBNF also contains the following
+operators, which many readers will recognize from regular
+expressions.  Do not, however, confuse them with "wildcard"
+characters, which have different meanings.
+
+=over 8
+
+=item C<?>
+
+Means that the preceding symbol (or group of symbols) is optional.
+That is, it may appear once or not at all.
+
+=item C<*>
+
+Means that the preceding symbol (or group of symbols) may appear
+zero or more times.
+
+=item C<+>
+
+Means that the preceding symbol (or group of symbols) may appear
+one or more times.
+
+=back
+
+Parentheses may be used to group symbols together.  For clarity,
+we will use single quotes ('') to designate what is a verbatim character
+string (as opposed to a symbol name).
+
+=head2 Aliases
+
+There are four kinds of aliases: C<User_Alias>, C<Runas_Alias>,
+C<Host_Alias> and C<Cmnd_Alias>.
+
+ 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)*
+
+ User_Alias ::= NAME '=' User_List
+
+ Runas_Alias ::= NAME '=' Runas_List
+
+ Host_Alias ::= NAME '=' Host_List
+
+ Cmnd_Alias ::= NAME '=' Cmnd_List
+
+ NAME ::= [A-Z]([A-Z][0-9]_)*
+
+Each I<alias> definition is of the form
+
+ Alias_Type NAME = item1, item2, ...
+
+where I<Alias_Type> is one of C<User_Alias>, C<Runas_Alias>, C<Host_Alias>,
+or C<Cmnd_Alias>.  A C<NAME> is a string of uppercase letters, numbers,
+and the underscore characters ('_').  A C<NAME> B<must> start with an
+uppercase letter.  It is possible to put several alias definitions
+of the same type on a single line, joined by a colon (':').  E.g.,
+
+ Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+
+The definitions of what constitutes a valid I<alias> member follow.
+
+ User_List ::= User |
+              User ',' User_List
+
+ User ::= '!'* username |
+         '!'* '%'group |
+         '!'* '+'netgroup |
+         '!'* User_Alias
+
+A C<User_List> is made up of one or more usernames, uids
+(prefixed with '#'), 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.
+
+ Host_List ::= Host |
+              Host ',' Host_List
+
+ Host ::= '!'* hostname |
+         '!'* ip_addr |
+         '!'* network(/netmask)? |
+         '!'* '+'netgroup |
+         '!'* Host_Alias
+
+A C<Host_List> is made up of one or more hostnames, IP addresses,
+network numbers, netgroups (prefixed with '+') and other aliases.
+Again, the value of an item may be negated with the '!' operator.
+If you do not specify a netmask with a network number, the netmask
+of the host's ethernet interface(s) will be used when matching.
+The netmask may be specified either in dotted quad notation (e.g.
+255.255.255.0) or CIDR notation (number of bits, e.g. 24).  A hostname
+may include shell-style wildcards (see `Wildcards' section below),
+but unless the C<hostname> command on your machine returns the fully
+qualified hostname, you'll need to use the I<fqdn> option for wildcards
+to be useful.
+
+ Cmnd_List ::= Cmnd |
+              Cmnd ',' Cmnd_List
+
+ commandname ::= filename |
+                filename args |
+                filename '""'
+
+ Cmnd ::= '!'* commandname |
+         '!'* directory |
+         '!'* Cmnd_Alias
+
+A C<Cmnd_List> is a list of one or more commandnames, directories, and other
+aliases.  A commandname is a fully qualified filename which may include
+shell-style wildcards (see `Wildcards' section below).  A simple
+filename allows the user to run the command with any arguments he/she
+wishes.  However, you may also specify command line arguments (including
+wildcards).  Alternately, you can specify C<""> to indicate that the command
+may only be run B<without> command line arguments.  A directory is a
+fully qualified pathname ending in a '/'.  When you specify a directory
+in a C<Cmnd_List>, the user will be able to run any file within that directory
+(but not in any subdirectories therein).
+
+If a C<Cmnd> has associated command line arguments, then the arguments
+in the C<Cmnd> must match exactly those given by the user on the command line
+(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: ',', ':', '=', '\'.
+
+=head2 Defaults
+
+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,
+or just a specific user.  When multiple entries match, they are
+applied in order.  Where there are conflicting values, the last
+value on a matching line takes effect.
+
+ Default_Type ::= 'Defaults' ||
+                 'Defaults' ':' User ||
+                 'Defaults' '@' Host
+
+ Default_Entry ::= Default_Type Parameter_List
+
+ Parameter ::= Parameter '=' Value ||
+              Parameter '+=' Value ||
+              Parameter '-=' Value ||
+              '!'* Parameter ||
+
+Parameters may be B<flags>, B<integer> values, B<strings>, or B<lists>.
+Flags are implicitly boolean and can be turned off via the '!'
+operator.  Some integer, string and list parameters may also be
+used in a boolean context to disable them.  Values may be enclosed
+in double quotes (C<">) when they contain multiple words.  Special
+characters may be escaped with a backslash (C<\>).
+
+Lists have two additional assignment operators, C<+=> and C<-=>.
+These operators are used to add to and delete from a list respectively.
+It is not an error to use the C<-=> operator to remove an element
+that does not exist in a list.
+
+Note that since the I<sudoers> file is parsed in order the best place
+to put the Defaults section is after the Host, User, and Cmnd aliases
+but before the user specifications.
+
+B<Flags>:
+
+=over 12
+
+=item long_otp_prompt
+
+When validating with a One Time Password scheme (B<S/Key> or B<OPIE>),
+a two-line prompt is used to make it easier to cut and paste the
+challenge to a local window.  It's not as pretty as the default but
+some people find it more convenient.  This flag is I<@long_otp_prompt@>
+by default.
+
+=item ignore_dot
+
+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.
+
+=item mail_always
+
+Send mail to the I<mailto> user every time a users runs B<sudo>.
+This flag is I<off> by default.
+
+=item mail_badpass
+
+Send mail to the I<mailto> user if the user running sudo does not
+enter the correct password.  This flag is I<off> 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 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 allowed to use B<sudo> but the command they are trying is not
+listed in their I<sudoers> file entry.  This flag is I<@mail_no_perms@>
+by default.
+
+=item tty_tickets
+
+If set, users must authenticate on a per-tty basis.  Normally,
+B<sudo> uses a directory in the ticket dir with the same name as
+the user running it.  With this flag enabled, B<sudo> will use a
+file named for the tty the user is logged in on in that directory.
+This flag is I<@tty_tickets@> by default.
+
+=item lecture
+
+If set, a user will receive a short lecture the first time he/she
+runs B<sudo>.  This flag is I<@lecture@> by default.
+
+=item authenticate
+
+If set, users must authenticate themselves via a password (or other
+means of authentication) before they may run commands.  This default
+may be overridden via the C<PASSWD> and C<NOPASSWD> tags.
+This flag is I<on> by default.
+
+=item root_sudo
+
+If set, root is allowed to run B<sudo> too.  Disabling this prevents users
+from "chaining" B<sudo> commands to get a root shell by doing something
+like C<"sudo sudo /bin/sh">.
+This flag is I<on> by default.
+
+=item log_host
+
+If set, the hostname will be logged in the (non-syslog) B<sudo> log file.
+This flag is I<off> by default.
+
+=item log_year
+
+If set, the four-digit year will be logged in the (non-syslog) B<sudo> log file.
+This flag is I<off> 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
+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.
+
+=item set_home
+
+If set and B<sudo> is invoked with the B<-s> flag 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.
+
+=item always_set_home
+
+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> flag is always implied.
+This flag is I<off> by default.
+
+=item path_info
+
+Normally, B<sudo> will tell the user when a command could not be
+found in their C<PATH> environment variable.  Some sites may wish
+to disable this as it could be used to gather information on the
+location of executables that the normal user does not have access
+to.  The disadvantage is that if the executable is simply not in
+the user's C<PATH>, B<sudo> will tell the user that they are not
+allowed to run it, which can be confusing.  This flag is I<off> by
+default.
+
+=item preserve_groups
+
+By default B<sudo> will initialize the group vector to the list of
+groups the target user is in.  When I<preserve_groups> is set, the
+user's existing group vector is left unaltered.  The real and
+effective group IDs, however, are still set to match the target
+user.  This flag is I<off> by default.
+
+=item fqdn
+
+Set this flag if you want to put fully qualified hostnames in the
+I<sudoers> file.  I.e.: instead of myhost you would use myhost.mydomain.edu.
+You may still use the short form if you wish (and even mix the two).
+Beware that turning on I<fqdn> requires B<sudo> to make DNS lookups
+which may make B<sudo> unusable if DNS stops working (for example
+if the machine is not plugged into the network).  Also note that
+you must use the host's official name as DNS knows it.  That is,
+you may not use a host alias (C<CNAME> entry) due to performance
+issues and the fact that there is no way to get all aliases from
+DNS.  If your machine's hostname (as returned by the C<hostname>
+command) is already fully qualified you shouldn't need to set
+I<fqdn>.  This flag is I<@fqdn@> by default.
+
+=item insults
+
+If set, B<sudo> will insult users when they enter an incorrect
+password.  This flag is I<@insults@> 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
+rsh(1) does not allocate a tty.  Because it is not possible to turn
+of echo when there is no tty present, some sites may with to set
+this flag to prevent a user from entering a visible password.  This
+flag is I<off> by default.
+
+=item env_editor
+
+If set, B<visudo> will use the value of the EDITOR or VISUAL
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.  A safer alternative
+is to place a colon-separated list of editors in the C<editor>
+variable.  B<visudo> will then only use the EDITOR or VISUAL if
+they match a value specified in C<editor>.  This flag is C<@env_editor@> by
+default.
+
+=item rootpw
+
+If set, B<sudo> will prompt for the root password instead of the password
+of the invoking user.  This flag is I<off> by default.
+
+=item runaspw
+
+If set, B<sudo> will prompt for the password of the user defined by the
+I<runas_default> option (defaults to C<root>) instead of the password
+of the invoking user.  This flag is I<off> by default.
+
+=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
+invoking user.  This flag is I<off> by default.
+
+=item set_logname
+
+Normally, B<sudo> will set the C<LOGNAME> and C<USER> environment variables
+to the name of the target user (usually root unless the B<-u> flag 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 option.
+
+=item stay_setuid
+
+Normally, when B<sudo> executes a command the real and effective
+UIDs are set to the target user (root by default).  This option
+changes that behavior such that the real UID is left as the invoking
+user's UID.  In other words, this makes B<sudo> act as a setuid
+wrapper.  This can be useful on systems that disable some potentially
+dangerous functionality when a program is run setuid.  Note, however,
+that this means that sudo will run with the real uid of the invoking
+user which may allow that user to kill B<sudo> before it can log a
+failure, depending on how your OS defines the interaction between
+signals and setuid processes.
+
+=item env_reset
+
+If set, B<sudo> will reset the environment to only contain the
+following variables: C<HOME>, C<LOGNAME>, C<PATH>, C<SHELL>, C<TERM>,
+and C<USER> (in addition to the C<SUDO_*> variables).
+Of these, only C<TERM> is copied unaltered from the old environment.
+The other variables are set to default values (possibly modified
+by the value of the I<set_logname> option).  If B<sudo> was compiled
+with the C<SECURE_PATH> option, its value will be used for the C<PATH>
+environment variable.
+Other variables may be preserved with the I<env_keep> option.
+
+=item use_loginclass
+
+If set, B<sudo> will apply the defaults specified for the target user's
+login class if one exists.  Only available if B<sudo> is configured with
+the --with-logincap option.  This flag is I<off> by default.
+
+=back
+
+B<Integers>:
+
+=over 12
+
+=item passwd_tries
+
+The number of tries a user gets to enter his/her password before
+B<sudo> logs the failure and exits.  The default is C<@passwd_tries@>.
+
+=back
+
+B<Integers that can be used in a boolean context>:
+
+=over 12
+
+=item loglinelen
+
+Number of characters per line for the file log.  This value is used
+to decide when to wrap lines for nicer log files.  This has no
+effect on the syslog log file, only the file log.  The default is
+C<@loglen@> (use 0 or negate the option to disable word wrap).
+
+=item timestamp_timeout
+
+Number of minutes that can elapse before B<sudo> will ask for a
+passwd again.  The default is C<@timeout@>.  Set this to C<0> to always
+prompt for a password.
+If set to a value less than C<0> the user's timestamp will never
+expire.  This can be used to allow users to create or delete their
+own timestamps via C<sudo -v> and C<sudo -k> respectively.
+
+=item passwd_timeout
+
+Number of minutes before the B<sudo> password prompt times out.
+The default is C<@password_timeout@>, set this to C<0> for no password timeout.
+
+=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@>.
+
+=back
+
+B<Strings>:
+
+=over 12
+
+=item mailsub
+
+Subject of the mail sent to the I<mailto> user. The escape C<%h>
+will expand to the hostname of the machine.
+Default is C<@mailsub@>.
+
+=item badpass_message
+
+Message that is displayed if a user enters an incorrect password.
+The default is C<@badpass_message@> unless insults are enabled.
+
+=item timestampdir
+
+The directory in which B<sudo> stores its timestamp files.
+The default is F<@timedir@>.
+
+=item passprompt
+
+The default prompt to use when asking for a password; can be overridden
+via the B<-p> option or the C<SUDO_PROMPT> environment variable. Supports
+two escapes: "%u" expands to the user's login name and "%h" expands
+to the local hostname.  The default value is C<@passprompt@>.
+
+=item runas_default
+
+The default user to run commands as if the B<-u> flag is not specified
+on the command line.  This defaults to C<@runas_default@>.
+
+=item syslog_goodpri
+
+Syslog priority to use when user authenticates successfully.
+Defaults to C<@goodpri@>.
+
+=item syslog_badpri
+
+Syslog priority to use when user authenticates unsuccessfully.
+Defaults to C<@badpri@>.
+
+=item editor
+
+A colon (':') separated list of editors allowed to be used with
+B<visudo>.  B<visudo> will choose the editor that matches the user's
+USER environment variable if possible, or the first editor in the
+list that exists and is executable.  The default is the path to vi
+on your system.
+
+=back
+
+B<Strings that can be used in a boolean context>:
+
+=over 12
+
+=item logfile
+
+Path to the B<sudo> log file (not the syslog log file).  Setting a path
+turns on logging to a file; negating this option turns it off.
+
+=item syslog
+
+Syslog facility if syslog is being used for logging (negate to
+disable syslog logging).  Defaults to C<@logfac@>.
+
+=item mailerpath
+
+Path to mail program used to send warning mail.
+Defaults to the path to sendmail found at configure time.
+
+=item mailerflags
+
+Flags to use when invoking mailer. Defaults to B<-t>.
+
+=item mailto
+
+Address to send warning and error mail to.  The address should
+be enclosed in double quotes (C<">) to protect against sudo
+interpreting the C<@> sign.  Defaults to C<@mailto@>.
+
+=item exempt_group
+
+Users in this group are exempt from password and PATH requirements.
+This is not set by default.
+
+=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:
+
+=over 8
+
+=item all
+
+All the user's I<sudoers> entries for the current host must have
+the C<NOPASSWD> flag set to avoid entering a password.
+
+=item any
+
+At least one of the user's I<sudoers> entries for the current host
+must have the C<NOPASSWD> flag set to avoid entering a password.
+
+=item never
+
+The user need never enter a password to use the B<-v> flag.
+
+=item always
+
+The user must always enter a password to use the B<-v> flag.
+
+=back
+
+The default value is `all'.
+
+=item listpw
+
+This option controls when a password will be required when a
+user runs B<sudo> with the B<-l>.  It has the following possible values:
+
+=over 8
+
+=item all
+
+All the user's I<sudoers> entries for the current host must have
+the C<NOPASSWD> flag set to avoid entering a password.
+
+=item any
+
+At least one of the user's I<sudoers> entries for the current host
+must have the C<NOPASSWD> flag set to avoid entering a password.
+
+=item never
+
+The user need never enter a password to use the B<-l> flag.
+
+=item always
+
+The user must always enter a password to use the B<-l> flag.
+
+=back
+
+The default value is `any'.
+
+=back
+
+B<Lists that can be used in a boolean context>:
+
+=over 12
+
+=item env_check
+
+Environment variables to be removed from the user's environment if
+the variable's value contains C<%> or C</> characters.  This can
+be used to guard against printf-style format vulnerabilties in
+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 C<=>, C<+=>, C<-=>, and C<!> operators respectively.  The default
+list of environment variable to check is printed when B<sudo> is
+run by root with the I<-V> option.
+
+=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
+to, deleted from, or disabled by using the C<=>, C<+=>, C<-=>, and
+C<!> operators respectively.  The default list of environment
+variable to remove is printed when B<sudo> is run by root with the
+I<-V> option.
+
+=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
+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
+to, deleted from, or disabled by using the C<=>, C<+=>, C<-=>, and
+C<!> operators respectively.  This list has no default members.
+
+=back
+
+When logging via syslog(3), B<sudo> accepts the following values for the syslog
+facility (the value of the B<syslog> Parameter): B<authpriv> (if your OS
+supports it), B<auth>, B<daemon>, B<user>, B<local0>, B<local1>, B<local2>,
+B<local3>, B<local4>, B<local5>, B<local6>, and B<local7>.  The following
+syslog priorities are supported: B<alert>, B<crit>, B<debug>, B<emerg>,
+B<err>, B<info>, B<notice>, and B<warning>.
+
+=head2 User Specification
+
+ User_Spec ::= User_list Host_List '=' Cmnd_Spec_List \
+              (':' User_Spec)*
+
+ Cmnd_Spec_List ::= Cmnd_Spec |
+                   Cmnd_Spec ',' Cmnd_Spec_List
+
+ Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
+
+ Runas_Spec ::= '(' Runas_List ')'
+
+A B<user specification> determines which commands a user may run
+(and as what user) on specified hosts.  By default, commands are
+run as B<root>, but this can be changed on a per-command basis.
+
+Let's break that down into its constituent parts:
+
+=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:
+
+ dgb   boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
+
+The user B<dgb> may run F</bin/ls>, F</bin/kill>, and
+F</usr/bin/lprm> -- but only as B<operator>.  E.g.,
+
+    sudo -u operator /bin/ls.
+
+It is also possible to override a C<Runas_Spec> later on in an
+entry.  If we modify the entry like so:
+
+ dgb   boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+
+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>.
+
+=head2 NOPASSWD and PASSWD
+
+By default, B<sudo> requires that a user authenticate him or herself
+before running a command.  This behavior can be modified via the
+C<NOPASSWD> tag.  Like a C<Runas_Spec>, the C<NOPASSWD> tag sets
+a default for the commands that follow it in the C<Cmnd_Spec_List>.
+Conversely, the C<PASSWD> tag can be used to reverse things.
+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
+authenticating himself.  If we only want B<ray> to be able to
+run F</bin/kill> without a password the entry would be:
+
+ ray   rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+
+Note, however, that the C<PASSWD> tag has no effect on users who are
+in the group specified by the exempt_group option.
+
+By default, if the C<NOPASSWD> tag is applied to any of the entries
+for a user on the current host, he or she will be able to run
+C<sudo -l> without a password.  Additionally, a user may only run
+C<sudo -v> without a password if the C<NOPASSWD> tag is present
+for all a user's entries that pertain to the current host.
+This behavior may be overridden via the verifypw and listpw options.
+
+=head2 Wildcards (aka meta characters):
+
+B<sudo> allows shell-style I<wildcards> to be used in pathnames
+as well as command line arguments in the I<sudoers> file.  Wildcard
+matching is done via the B<POSIX> C<fnmatch(3)> routine.  Note that
+these are I<not> regular expressions.
+
+=over 8
+
+=item C<*>
+
+Matches any set of zero or more characters.
+
+=item C<?>
+
+Matches any single character.
+
+=item C<[...]>
+
+Matches any character in the specified range.
+
+=item C<[!...]>
+
+Matches any character B<not> in the specified range.
+
+=item C<\x>
+
+For any character "x", evaluates to "x".  This is used to
+escape special characters such as: "*", "?", "[", and "}".
+
+=back
+
+Note that a forward slash ('/') will B<not> be matched by
+wildcards used in the pathname.  When matching the command
+line arguments, however, as slash B<does> get matched by
+wildcards.  This is to make a path like:
+
+    /usr/bin/*
+
+match C</usr/bin/who> but not C</usr/bin/X11/xterm>.
+
+=head2 Exceptions to wildcard rules:
+
+The following exceptions apply to the above rules:
+
+=over 8
+
+=item C<"">
+
+If the empty string C<""> is the only command line argument in the
+I<sudoers> entry it means that command is not allowed to be run
+with B<any> arguments.
+
+=back
+
+=head2 Other special characters and reserved words:
+
+The pound sign ('#') is used to indicate a comment (unless it
+occurs in the context of a user name and is followed by one or
+more digits, in which case it is treated as a uid).  Both the
+comment character and any text after it, up to the end of the line,
+are ignored.
+
+The reserved word B<ALL> is a built in I<alias> that always causes
+a match to succeed.  It can be used wherever one might otherwise
+use a C<Cmnd_Alias>, C<User_Alias>, C<Runas_Alias>, or C<Host_Alias>.
+You should not try to define your own I<alias> called B<ALL> as the
+built in alias will be used in preference to your own.  Please note
+that using B<ALL> can be dangerous since in a command context, it
+allows the user to run B<any> command on the system.
+
+An exclamation point ('!') can be used as a logical I<not> operator
+both in an I<alias> and in front of a C<Cmnd>.  This allows one to
+exclude certain values.  Note, however, that using a C<!> in
+conjunction with the built in C<ALL> alias to allow a user to
+run "all but a few" commands rarely works as intended (see SECURITY
+NOTES below).
+
+Long lines can be continued with a backslash ('\') as the last
+character on the line.
+
+Whitespace between elements in a list as well as special syntactic
+characters in a I<User Specification> ('=', ':', '(', ')') is optional.
+
+The following characters must be escaped with a backslash ('\') when
+used as part of a word (e.g. a username or hostname):
+'@', '!', '=', ':', ',', '(', ')', '\'.
+
+=head1 EXAMPLES
+
+Below are example I<sudoers> entries.  Admittedly, some of
+these are a bit contrived.  First, we define our I<aliases>:
+
+ # User alias specification
+ User_Alias    FULLTIMERS = millert, mikef, dowdy
+ User_Alias    PARTTIMERS = bostley, jwfox, crawl
+ User_Alias    WEBMASTERS = will, wendy, wim
+
+ # Runas alias specification
+ Runas_Alias   OP = root, operator
+ Runas_Alias   DB = oracle, sybase
+
+ # Host alias specification
+ Host_Alias    SPARC = bigtime, eclipse, moet, anchor :\
+               SGI = grolsch, dandelion, black :\
+               ALPHA = widget, thalamus, foobar :\
+               HPPA = boa, nag, python
+ Host_Alias    CUNETS = 128.138.0.0/255.255.0.0
+ 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
+
+ # Cmnd alias specification
+ Cmnd_Alias    DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
+                       /usr/sbin/restore, /usr/sbin/rrestore
+ Cmnd_Alias    KILL = /usr/bin/kill
+ Cmnd_Alias    PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+ Cmnd_Alias    SHUTDOWN = /usr/sbin/shutdown
+ Cmnd_Alias    HALT = /usr/sbin/halt, /usr/sbin/fasthalt
+ Cmnd_Alias    REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
+ Cmnd_Alias    SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
+                        /usr/local/bin/tcsh, /usr/bin/rsh, \
+                        /usr/local/bin/zsh
+ Cmnd_Alias    SU = /usr/bin/su
+
+Here we override some of the compiled in default values.  We want
+B<sudo> to log via syslog(3) using the I<auth> facility in all cases.
+We don't want to subject the full time staff to the B<sudo> lecture,
+and user B<millert> need not give a password.  In addition, on the
+machines in the I<SERVERS> C<Host_Alias>, we keep an additional
+local log file and make sure we log the year in each log line since
+the log entries will be kept around for several years.
+
+ # Override built in defaults
+ Defaults              syslog=auth
+ Defaults:FULLTIMERS   !lecture
+ Defaults:millert      !authenticate
+ Defaults@SERVERS      log_year, logfile=/var/log/sudo.log
+
+The I<User specification> is the part that actually determines who may
+run what.
+
+ root          ALL = (ALL) ALL
+ %wheel                ALL = (ALL) ALL
+
+We let B<root> and any user in group B<wheel> run any command on any
+host as any user.
+
+ FULLTIMERS    ALL = NOPASSWD: ALL
+
+Full time sysadmins (B<millert>, B<mikef>, and B<dowdy>) may run any
+command on any host without authenticating themselves.
+
+ PARTTIMERS    ALL = ALL
+
+Part time sysadmins (B<bostley>, B<jwfox>, and B<crawl>) may run any
+command on any host but they must authenticate themselves first
+(since the entry lacks the C<NOPASSWD> tag).
+
+ jack          CSNETS = ALL
+
+The user B<jack> may run any command on the machines in the I<CSNETS> alias
+(the networks C<128.138.243.0>, C<128.138.204.0>, and C<128.138.242.0>).
+Of those networks, only C<128.138.204.0> has an explicit netmask (in
+CIDR notation) indicating it is a class C network.  For the other
+networks in I<CSNETS>, the local machine's netmask will be used
+during matching.
+
+ lisa          CUNETS = ALL
+
+The user B<lisa> may run any command on any host in the I<CUNETS> alias
+(the class B network C<128.138.0.0>).
+
+ operator      ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
+               /usr/oper/bin/
+
+The B<operator> user may run commands limited to simple maintenance.
+Here, those are commands related to backups, killing processes, the
+printing system, shutting down the system, and any commands in the
+directory F</usr/oper/bin/>.
+
+ joe           ALL = /usr/bin/su operator
+
+The user B<joe> may only su(1) to operator.
+
+ pete          HPPA = /usr/bin/passwd [A-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 passwd(1)
+does not take multiple usernames on the command line.
+
+ bob           SPARC = (OP) ALL : SGI = (OP) ALL
+
+The user B<bob> may run anything on the I<SPARC> and I<SGI> machines
+as any user listed in the I<OP> C<Runas_Alias> (B<root> and B<operator>).
+
+ jim           +biglab = ALL
+
+The user B<jim> may run any command on machines in the I<biglab> netgroup.
+B<Sudo> knows that "biglab" is a netgroup due to the '+' prefix.
+
+ +secretaries  ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+
+Users in the B<secretaries> netgroup need to help manage the printers
+as well as add and remove users, so they are allowed to run those
+commands on all machines.
+
+ fred          ALL = (DB) NOPASSWD: ALL
+
+The user B<fred> can run commands as any user in the I<DB> C<Runas_Alias>
+(B<oracle> or B<sybase>) without giving a password.
+
+ 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 su(1) any flags.
+
+ jen           ALL, !SERVERS = ALL
+
+The user B<jen> may run any command on any machine except for those
+in the I<SERVERS> C<Host_Alias> (master, mail, www and ns).
+
+ jill          SERVERS = /usr/bin/, !SU, !SHELLS
+
+For any machine in the I<SERVERS> C<Host_Alias>, B<jill> may run
+any commands in the directory /usr/bin/ except for those commands
+belonging to the I<SU> and I<SHELLS> C<Cmnd_Aliases>.
+
+ steve         CSNETS = (operator) /usr/local/op_commands/
+
+The user B<steve> may run any command in the directory /usr/local/op_commands/
+but only as user operator.
+
+ matt          valkyrie = KILL
+
+On his personal workstation, valkyrie, B<matt> needs to be able to
+kill hung processes.
+
+ WEBMASTERS    www = (www) ALL, (root) /usr/bin/su www
+
+On the host www, any user in the I<WEBMASTERS> C<User_Alias> (will,
+wendy, and wim), may run any command as user www (which owns the
+web pages) or simply su(1) to www.
+
+ ALL           CDROM = NOPASSWD: /sbin/umount /CDROM,\
+               /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
+
+Any user may mount or unmount a CD-ROM on the machines in the CDROM
+C<Host_Alias> (orion, perseus, hercules) without entering a password.
+This is a bit tedious for users to type, so it is a prime candidate
+for encapsulating in a shell script.
+
+=head1 SECURITY NOTES
+
+It is generally not effective to "subtract" commands from C<ALL>
+using the '!' operator.  A user can trivially circumvent this
+by copying the desired command to a different name and then
+executing that.  For example:
+
+    bill       ALL = ALL, !SU, !SHELLS
+
+Doesn't really prevent B<bill> from running the commands listed in
+I<SU> or I<SHELLS> since he can simply copy those commands to a
+different name, or use a shell escape from an editor or other
+program.  Therefore, these kind of restrictions should be considered
+advisory at best (and reinforced by policy).
+
+=head1 CAVEATS
+
+The I<sudoers> file should B<always> be edited by the B<visudo>
+command which locks the file and does grammatical checking. It is
+imperative that I<sudoers> be free of syntax errors since B<sudo>
+will not run with a syntactically incorrect I<sudoers> file.
+
+When using netgroups of machines (as opposed to users), if you
+store fully qualified hostnames in the netgroup (as is usually the
+case), you either need to have the machine's hostname be fully qualified
+as returned by the C<hostname> command or use the I<fqdn> option in
+I<sudoers>.
+
+=head1 FILES
+
+ @sysconfdir@/sudoers          List of who can run what
+ /etc/group            Local groups file
+ /etc/netgroup         List of network groups
+
+=head1 SEE ALSO
+
+rsh(1), sudo(8), visudo(8), su(1), fnmatch(3).
diff --git a/testsudoers.c b/testsudoers.c
new file mode 100644 (file)
index 0000000..88fc2af
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed by Chris Jepeway.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_FNMATCH
+# include <fnmatch.h>
+#endif /* HAVE_FNMATCH_H */
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#endif /* HAVE_NETGROUP_H */
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <dirent.h>
+
+#include "sudo.h"
+#include "parse.h"
+#include "interfaces.h"
+
+#ifndef HAVE_FNMATCH
+# include "emul/fnmatch.h"
+#endif /* HAVE_FNMATCH */
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: testsudoers.c,v 1.76 2002/03/16 00:44:48 millert Exp $";
+#endif /* lint */
+
+
+/*
+ * Prototypes
+ */
+void init_parser       __P((void));
+void dumpaliases       __P((void));
+void set_perms_dummy   __P((int, int));
+
+/*
+ * Globals
+ */
+char **Argv, **NewArgv;
+int  Argc, NewArgc;
+int parse_error = FALSE;
+int num_interfaces;
+struct interface *interfaces;
+struct sudo_user sudo_user;
+void (*set_perms) __P((int, int)) = set_perms_dummy;
+extern int clearaliases;
+extern int pedantic;
+
+/*
+ * Returns TRUE if "s" has shell meta characters in it,
+ * else returns FALSE.
+ */
+int
+has_meta(s)
+    char *s;
+{
+    char *t;
+    
+    for (t = s; *t; t++) {
+       if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']')
+           return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*
+ * Returns TRUE if cmnd matches, in the sudo sense,
+ * the pathname in path; otherwise, return FALSE
+ */
+int
+command_matches(cmnd, cmnd_args, path, sudoers_args)
+    char *cmnd;
+    char *cmnd_args;
+    char *path;
+    char *sudoers_args;
+{
+    int clen, plen;
+    char *args;
+
+    if (cmnd == NULL)
+       return(FALSE);
+
+    if ((args = strchr(path, ' ')))  
+       *args++ = '\0';
+
+    if (has_meta(path)) {
+       if (fnmatch(path, cmnd, FNM_PATHNAME))
+           return(FALSE);
+       if (!sudoers_args)
+           return(TRUE);
+       else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args))
+           return(TRUE);
+       else if (sudoers_args)
+           return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0));
+       else
+           return(FALSE);
+    } else {
+       plen = strlen(path);
+       if (path[plen - 1] != '/') {
+           if (strcmp(cmnd, path))
+               return(FALSE);
+           if (!sudoers_args)
+               return(TRUE);
+           else if (!cmnd_args && sudoers_args && !strcmp("\"\"", sudoers_args))
+               return(TRUE);
+           else if (sudoers_args)
+               return((fnmatch(sudoers_args, cmnd_args ? cmnd_args : "", 0) == 0));
+           else
+               return(FALSE);
+       }
+
+       clen = strlen(cmnd);
+       if (clen < plen + 1)
+           /* path cannot be the parent dir of cmnd */
+           return(FALSE);
+
+       if (strchr(cmnd + plen + 1, '/') != NULL)
+           /* path could only be an anscestor of cmnd -- */
+           /* ignoring, of course, things like // & /./  */
+           return(FALSE);
+
+       /* see whether path is the prefix of cmnd */
+       return((strncmp(cmnd, path, plen) == 0));
+    }
+}
+
+int
+addr_matches(n)
+    char *n;
+{
+    int i;
+    char *m;
+    struct in_addr addr, mask;
+
+    /* If there's an explicit netmask, use it. */
+    if ((m = strchr(n, '/'))) {
+       *m++ = '\0';
+       addr.s_addr = inet_addr(n);
+       if (strchr(m, '.'))
+           mask.s_addr = inet_addr(m);
+       else {
+           i = 32 - atoi(m);
+           mask.s_addr = 0xffffffff;
+           mask.s_addr >>= i;
+           mask.s_addr <<= i;
+           mask.s_addr = htonl(mask.s_addr);
+       }
+       *(m - 1) = '/';               
+
+       for (i = 0; i < num_interfaces; i++)
+           if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr)
+               return(TRUE);
+    } else {
+       addr.s_addr = inet_addr(n);
+
+       for (i = 0; i < num_interfaces; i++)
+           if (interfaces[i].addr.s_addr == addr.s_addr ||
+               (interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr)
+               == addr.s_addr)
+               return(TRUE);
+    }
+
+    return(FALSE);
+}
+
+int
+hostname_matches(shost, lhost, pattern)
+    char *shost;
+    char *lhost;
+    char *pattern;
+{
+    if (has_meta(pattern)) {  
+        if (strchr(pattern, '.'))   
+            return(fnmatch(pattern, lhost, FNM_CASEFOLD));
+        else
+            return(fnmatch(pattern, shost, FNM_CASEFOLD));
+    } else {
+        if (strchr(pattern, '.'))
+            return(strcasecmp(lhost, pattern));
+        else
+            return(strcasecmp(shost, pattern));
+    }
+}
+
+int
+usergr_matches(group, user)
+    char *group;
+    char *user;
+{
+    struct group *grp;
+    char **cur;
+
+    /* Make sure we have a valid usergroup, sudo style. */
+    if (*group++ != '%')
+       return(FALSE);
+
+    if ((grp = getgrnam(group)) == NULL) 
+       return(FALSE);
+
+    /*
+     * Check against user's real gid as well as group's user list
+     */
+    if (getgid() == grp->gr_gid)
+       return(TRUE);
+
+    for (cur=grp->gr_mem; *cur; cur++) {
+       if (strcmp(*cur, user) == 0)
+           return(TRUE);
+    }
+
+    return(FALSE);
+}
+
+int
+netgr_matches(netgr, host, shost, user)
+    char *netgr;
+    char *host;
+    char *shost;
+    char *user;
+{
+#ifdef HAVE_GETDOMAINNAME
+    static char *domain = (char *) -1;
+#else
+    static char *domain = NULL;
+#endif /* HAVE_GETDOMAINNAME */
+
+    /* Make sure we have a valid netgroup, sudo style. */
+    if (*netgr++ != '+')
+       return(FALSE);
+
+#ifdef HAVE_GETDOMAINNAME
+    /* Get the domain name (if any). */
+    if (domain == (char *) -1) {
+       domain = (char *) emalloc(MAXHOSTNAMELEN);
+
+       if (getdomainname(domain, MAXHOSTNAMELEN) != 0 || *domain == '\0') {
+           free(domain);
+           domain = NULL;
+       }
+    }
+#endif /* HAVE_GETDOMAINNAME */
+
+#ifdef HAVE_INNETGR
+    if (innetgr(netgr, host, user, domain))
+       return(TRUE);
+    else if (host != shost && innetgr(netgr, shost, user, domain))
+       return(TRUE);
+#endif /* HAVE_INNETGR */
+
+    return(FALSE);
+}
+
+void
+set_perms_dummy(i, j)
+    int i, j;
+{
+    return;
+}
+
+void
+set_fqdn()
+{
+    return;
+}
+
+void
+init_envtables()
+{
+    return;
+}
+
+int
+main(argc, argv)
+    int argc;
+    char **argv;
+{
+    struct passwd pw;
+    char *p;
+#ifdef YYDEBUG
+    extern int yydebug;
+    yydebug = 1;
+#endif
+
+    Argv = argv;
+    Argc = argc;
+
+    if (Argc >= 6 && strcmp(Argv[1], "-u") == 0) {
+       user_runas = &Argv[2];
+       pw.pw_name = Argv[3];
+       user_host = Argv[4];
+       user_cmnd = Argv[5];
+
+       NewArgv = &Argv[5];
+       NewArgc = Argc - 5;
+    } else if (Argc >= 4) {
+       pw.pw_name = Argv[1];
+       user_host = Argv[2];
+       user_cmnd = Argv[3];
+
+       NewArgv = &Argv[3];
+       NewArgc = Argc - 3;
+    } else {
+       (void) fprintf(stderr,
+           "usage: %s [-u user] <user> <host> <command> [args]\n", Argv[0]);
+       exit(1);
+    }
+
+    sudo_user.pw = &pw;                /* user_name needs to be defined */
+
+    if ((p = strchr(user_host, '.'))) {
+       *p = '\0';
+       user_shost = estrdup(user_host);
+       *p = '.';
+    } else {
+       user_shost = user_host;
+    }
+
+    /* Fill in cmnd_args from NewArgv. */
+    if (NewArgc > 1) {
+       size_t size;
+       char *to, **from;
+
+       size = (size_t) NewArgv[NewArgc-1] + strlen(NewArgv[NewArgc-1]) -
+              (size_t) NewArgv[1] + 1;
+       user_args = (char *) emalloc(size);
+       for (to = user_args, from = &NewArgv[1]; *from; from++) {
+           *to++ = ' ';
+           (void) strcpy(to, *from);
+           to += strlen(*from);
+       }
+    }
+
+    /* Initialize default values. */
+    init_defaults();
+
+    /* Warn about aliases that are used before being defined. */
+    pedantic = TRUE;
+
+    /* Need to keep aliases around for dumpaliases(). */
+    clearaliases = FALSE;
+
+    /* Load ip addr/mask for each interface. */
+    load_interfaces();
+
+    /* Allocate space for data structures in the parser. */
+    init_parser();
+
+    if (yyparse() || parse_error) {
+       (void) printf("doesn't parse.\n");
+    } else {
+       (void) printf("parses OK.\n\n");
+       if (top == 0)
+           (void) printf("User %s not found\n", pw.pw_name);
+       else while (top) {
+           (void) printf("[%d]\n", top-1);
+           (void) printf("user_match : %d\n", user_matches);
+           (void) printf("host_match : %d\n", host_matches);
+           (void) printf("cmnd_match : %d\n", cmnd_matches);
+           (void) printf("no_passwd  : %d\n", no_passwd);
+           (void) printf("runas_match: %d\n", runas_matches);
+           (void) printf("runas      : %s\n", *user_runas);
+           top--;
+       }
+    }
+
+    /* Dump aliases. */
+    (void) printf("Matching Aliases --\n");
+    dumpaliases();
+
+    exit(0);
+}
diff --git a/tgetpass.c b/tgetpass.c
new file mode 100644 (file)
index 0000000..62f73da
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef HAVE_SYS_BSDTYPES_H
+# include <sys/bsdtypes.h>
+#endif /* HAVE_SYS_BSDTYPES_H */
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+#include <sys/time.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#else
+# ifdef HAVE_TERMIO_H
+#  include <termio.h>
+# else
+#  include <sgtty.h>
+#  include <sys/ioctl.h>
+# endif /* HAVE_TERMIO_H */
+#endif /* HAVE_TERMIOS_H */
+
+#include "sudo.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: tgetpass.c,v 1.103 2001/12/17 23:56:47 millert Exp $";
+#endif /* lint */
+
+#ifndef TCSASOFT
+# define TCSASOFT      0
+#endif
+#ifndef ECHONL
+# define ECHONL        0
+#endif
+
+#ifndef _POSIX_VDISABLE
+# ifdef VDISABLE
+#  define _POSIX_VDISABLE      VDISABLE
+# else
+#  define _POSIX_VDISABLE      0
+# endif
+#endif
+
+/*
+ * Abstract method of getting at the term flags.
+ */
+#undef TERM
+#undef tflags
+#ifdef HAVE_TERMIOS_H
+# define TERM                  termios
+# define tflags                        c_lflag
+# define term_getattr(f, t)    tcgetattr(f, t)
+# define term_setattr(f, t)    tcsetattr(f, TCSAFLUSH|TCSASOFT, t)
+#else
+# ifdef HAVE_TERMIO_H
+# define TERM                  termio
+# define tflags                        c_lflag
+# define term_getattr(f, t)    ioctl(f, TCGETA, t)
+# define term_setattr(f, t)    ioctl(f, TCSETAF, t)
+# else
+#  define TERM                 sgttyb
+#  define tflags               sg_flags
+#  define term_getattr(f, t)   ioctl(f, TIOCGETP, t)
+#  define term_setattr(f, t)   ioctl(f, TIOCSETP, t)
+# endif /* HAVE_TERMIO_H */
+#endif /* HAVE_TERMIOS_H */
+
+static volatile sig_atomic_t signo;
+
+static char *tgetline __P((int, char *, size_t, int));
+static void handler __P((int));
+
+/*
+ * Like getpass(3) but with timeout and echo flags.
+ */
+char *
+tgetpass(prompt, timeout, flags)
+    const char *prompt;
+    int timeout;
+    int flags;
+{
+    sigaction_t sa, saveint, savehup, savequit, saveterm;
+    sigaction_t savetstp, savettin, savettou;
+    static char buf[SUDO_PASS_MAX + 1];
+    int input, output, save_errno;
+    struct TERM term, oterm;
+    char *pass;
+
+restart:
+    /* Open /dev/tty for reading/writing if possible else use stdin/stderr. */
+    if ((flags & TGP_STDIN) ||
+       (input = output = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) {
+       input = STDIN_FILENO;
+       output = STDERR_FILENO;
+    }
+
+    if (prompt)
+       (void) write(output, prompt, strlen(prompt));
+
+    /*
+     * Catch signals that would otherwise cause the user to end
+     * up with echo turned off in the shell.  Don't worry about
+     * things like SIGALRM and SIGPIPE for now.
+     */
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;           /* don't restart system calls */
+    sa.sa_handler = handler;
+    (void) sigaction(SIGINT, &sa, &saveint);
+    (void) sigaction(SIGHUP, &sa, &savehup);
+    (void) sigaction(SIGQUIT, &sa, &savequit);
+    (void) sigaction(SIGTERM, &sa, &saveterm);
+    (void) sigaction(SIGTSTP, &sa, &savetstp);
+    (void) sigaction(SIGTTIN, &sa, &savettin);
+    (void) sigaction(SIGTTOU, &sa, &savettou);
+
+    /* Turn echo off/on as specified by flags.  */
+    if (term_getattr(input, &oterm) == 0) {
+       (void) memcpy(&term, &oterm, sizeof(term));
+       if (!(flags & TGP_ECHO))
+           term.tflags &= ~(ECHO | ECHONL);
+#ifdef VSTATUS
+       term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+#endif
+       (void) term_setattr(input, &term);
+    } else {
+       memset(&term, 0, sizeof(term));
+       memset(&oterm, 0, sizeof(oterm));
+    }
+
+    pass = tgetline(input, buf, sizeof(buf), timeout);
+    save_errno = errno;
+
+    if (!(term.tflags & ECHO))
+       (void) write(output, "\n", 1);
+
+    /* Restore old tty settings and signals. */
+    if (memcmp(&term, &oterm, sizeof(term)) != 0)
+       (void) term_setattr(input, &oterm);
+    (void) sigaction(SIGINT, &saveint, NULL);
+    (void) sigaction(SIGHUP, &savehup, NULL);
+    (void) sigaction(SIGQUIT, &savequit, NULL);
+    (void) sigaction(SIGTERM, &saveterm, NULL);
+    (void) sigaction(SIGTSTP, &savetstp, NULL);
+    (void) sigaction(SIGTTIN, &savettin, NULL);
+    (void) sigaction(SIGTTOU, &savettou, NULL);
+    if (input != STDIN_FILENO)
+       (void) close(input);
+
+    /*
+     * If we were interrupted by a signal, resend it to ourselves
+     * now that we have restored the signal handlers.
+     */
+    if (signo) {
+       kill(getpid(), signo); 
+       switch (signo) {
+           case SIGTSTP:
+           case SIGTTIN:
+           case SIGTTOU:
+               signo = 0;
+               goto restart;
+       }
+    }
+
+    errno = save_errno;
+    return(pass);
+}
+
+/*
+ * Get a line of input (optionally timing out) and place it in buf.
+ */
+static char *
+tgetline(fd, buf, bufsiz, timeout)
+    int fd;
+    char *buf;
+    size_t bufsiz;
+    int timeout;
+{
+    fd_set *readfds = NULL;
+    struct timeval tv;
+    size_t left;
+    char *cp;
+    char c;
+    int n;
+
+    if (bufsiz == 0) {
+       errno = EINVAL;
+       return(NULL);                   /* sanity */
+    }
+
+    cp = buf;
+    left = bufsiz;
+
+    /*
+     * Timeout of <= 0 means no timeout.
+     */
+    if (timeout > 0) {
+       /* Setup for select(2) */
+       n = howmany(fd + 1, NFDBITS) * sizeof(fd_mask);
+       readfds = (fd_set *) emalloc(n);
+       (void) memset((VOID *)readfds, 0, n);
+
+       /* Set timeout for select */
+       tv.tv_sec = timeout;
+       tv.tv_usec = 0;
+
+       while (--left) {
+           FD_SET(fd, readfds);
+
+           /* Make sure there is something to read (or timeout) */
+           while ((n = select(fd + 1, readfds, 0, 0, &tv)) == -1 &&
+               errno == EAGAIN)
+               ;
+           if (n <= 0) {
+               free(readfds);
+               return(NULL);           /* timeout or interrupt */
+           }
+
+           /* Read a character, exit loop on error, EOF or EOL */
+           n = read(fd, &c, 1);
+           if (n != 1 || c == '\n' || c == '\r')
+               break;
+           *cp++ = c;
+       }
+       free(readfds);
+    } else {
+       /* Keep reading until out of space, EOF, error, or newline */
+       n = -1;
+       while (--left && (n = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r')
+           *cp++ = c;
+    }
+    *cp = '\0';
+
+    return(n == -1 ? NULL : buf);
+}
+
+static void handler(s)
+    int s;
+{
+    signo = s;
+}
diff --git a/utime.c b/utime.c
new file mode 100644 (file)
index 0000000..1730081
--- /dev/null
+++ b/utime.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2001
+ *     Todd C. Miller <Todd.Miller@courtesan.com>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "compat.h"
+#include "emul/utime.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: utime.c,v 1.35 2001/12/14 19:52:48 millert Exp $";
+#endif /* lint */
+
+
+/*
+ * Emulate utime(3) via utimes(2).
+ * utime(3) sets the access and mod times of the named file.
+ */
+int
+utime(file, tvp)
+    const char *file;
+    const struct utimbuf *utp;
+{
+    if (upt) {
+       struct timeval tv[2];
+
+       tv[0].tv_sec = ut.actime;
+       tv[0].tv_usec = 0;
+
+       tv[1].tv_sec = ut.modtime;
+       tv[1].tv_usec = 0;
+
+       return(utimes(file, tv);
+    } else {
+       return(utimes(file, NULL);
+    }
+}
diff --git a/version.h b/version.h
new file mode 100644 (file)
index 0000000..bc7b7c6
--- /dev/null
+++ b/version.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1996, 1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: version.h,v 1.61 2002/04/18 15:41:30 millert Exp $
+ */
+
+#ifndef _SUDO_VERSION_H
+#define _SUDO_VERSION_H
+
+static const char version[] = "1.6.6";
+
+#endif /* _SUDO_VERSION_H */
diff --git a/visudo.c b/visudo.c
new file mode 100644 (file)
index 0000000..c3a1c59
--- /dev/null
+++ b/visudo.c
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Lock the sudoers file for safe editing (ala vipw) and check for parse errors.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+#include <pwd.h>
+#include <time.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "sudo.h"
+#include "version.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: visudo.c,v 1.146 2002/01/17 15:35:54 millert Exp $";
+#endif /* lint */
+
+/*
+ * Function prototypes
+ */
+static void usage              __P((void));
+static char whatnow            __P((void));
+static RETSIGTYPE Exit         __P((int));
+static void setup_signals      __P((void));
+static int run_command         __P((char *, char **));
+static int check_syntax                __P((int));
+int command_matches            __P((char *, char *, char *, char *));
+int addr_matches               __P((char *));
+int hostname_matches           __P((char *, char *, char *));
+int netgr_matches              __P((char *, char *, char *, char *));
+int usergr_matches             __P((char *, char *));
+void init_parser               __P((void));
+void yyrestart                 __P((FILE *));
+
+/*
+ * External globals exported by the parser
+ */
+extern FILE *yyin, *yyout;
+extern int errorlineno;
+extern int pedantic;
+extern int quiet;
+
+/* For getopt(3) */
+extern char *optarg;
+extern int optind;
+
+/*
+ * Globals
+ */
+char **Argv;
+char *sudoers = _PATH_SUDOERS;
+char *stmp = _PATH_SUDOERS_TMP;
+struct sudo_user sudo_user;
+int parse_error = FALSE;
+
+int
+main(argc, argv)
+    int argc;
+    char **argv;
+{
+    char buf[MAXPATHLEN*2];            /* buffer used for copying files */
+    char *Editor;                      /* editor to use */
+    char *UserEditor;                  /* editor user wants to use */
+    char *EditorPath;                  /* colon-separated list of editors */
+    char *av[4];                       /* argument vector for run_command */
+    int checkonly;                     /* only check existing file? */
+    int sudoers_fd;                    /* sudoers file descriptor */
+    int stmp_fd;                       /* stmp file descriptor */
+    int n;                             /* length parameter */
+    int ch;                            /* getopt char */
+    time_t now;                                /* time now */
+    struct stat stmp_sb, sudoers_sb;   /* to check for changes */
+
+    /* Warn about aliases that are used before being defined. */
+    pedantic = 1;
+
+    /*
+     * Parse command line options
+     */
+    Argv = argv;
+
+    /*
+     * Arg handling.
+     */
+    checkonly = 0;
+    while ((ch = getopt(argc, argv, "Vcf:sq")) != -1) {
+       switch (ch) {
+           case 'V':
+               (void) printf("visudo version %s\n", version);
+               exit(0);
+           case 'c':
+               checkonly++;            /* check mode */
+               break;
+           case 'f':
+               sudoers = optarg;       /* sudoers file path */
+               easprintf(&stmp, "%s.tmp", optarg);
+               break;
+           case 's':
+               pedantic++;             /* strict mode */
+               break;
+           case 'q':
+               quiet++;                /* quiet mode */
+               break;
+           default:
+               usage();
+       }
+    }
+    argc -= optind;
+    argv += optind;
+    if (argc)
+       usage();
+
+    /* Mock up a fake sudo_user struct. */
+    user_host = user_shost = user_cmnd = "";
+    if ((sudo_user.pw = getpwuid(getuid())) == NULL) {
+       (void) fprintf(stderr, "%s: Can't find you in the passwd database.\n",
+           Argv[0]);
+       exit(1);
+    }
+
+    /* Setup defaults data structures. */
+    init_defaults();
+
+    if (checkonly)
+       exit(check_syntax(quiet));
+
+    /*
+     * Open sudoers, lock it and stat it.  
+     * sudoers_fd must remain open throughout in order to hold the lock.
+     */
+    sudoers_fd = open(sudoers, O_RDWR | O_CREAT, SUDOERS_MODE);
+    if (sudoers_fd == -1) {
+       (void) fprintf(stderr, "%s: %s: %s\n", Argv[0], sudoers,
+           strerror(errno));
+       exit(1);
+    }
+    if (!lock_file(sudoers_fd, SUDO_TLOCK)) {
+       (void) fprintf(stderr, "%s: sudoers file busy, try again later.\n",
+           Argv[0]);
+       exit(1);
+    }
+#ifdef HAVE_FSTAT
+    if (fstat(sudoers_fd, &sudoers_sb) == -1) {
+#else
+    if (stat(sudoers, &sudoers_sb) == -1) {
+#endif
+       (void) fprintf(stderr, "%s: can't stat %s: %s\n",
+           Argv[0], sudoers, strerror(errno));
+       exit(1);
+    }
+
+    /*
+     * Open sudoers temp file.
+     */
+    stmp_fd = open(stmp, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    if (stmp_fd < 0) {
+       (void) fprintf(stderr, "%s: %s: %s\n", Argv[0], stmp, strerror(errno));
+       exit(1);
+    }
+
+    /* Install signal handlers to clean up stmp if we are killed. */
+    setup_signals();
+
+    /* Copy sudoers -> stmp and reset the mtime */
+    if (sudoers_sb.st_size) {
+       while ((n = read(sudoers_fd, buf, sizeof(buf))) > 0)
+           if (write(stmp_fd, buf, n) != n) {
+               (void) fprintf(stderr, "%s: Write failed: %s\n", Argv[0],
+               strerror(errno));
+               Exit(-1);
+           }
+
+       (void) close(stmp_fd);
+       (void) touch(stmp, sudoers_sb.st_mtime);
+
+       /* Parse sudoers to pull in editor and env_editor conf values. */
+       if ((yyin = fopen(stmp, "r"))) {
+           yyout = stdout;
+           init_parser();
+           yyparse();
+           parse_error = FALSE;
+           yyrestart(yyin);
+           fclose(yyin);
+       }
+    } else
+       (void) close(stmp_fd);
+
+    /*
+     * Check EDITOR and VISUAL environment variables to see which editor
+     * the user wants to use (we may not end up using it though).
+     * If the path is not fully-qualified, make it so and check that
+     * the specified executable actually exists.
+     */
+    if ((UserEditor = getenv("EDITOR")) == NULL || *UserEditor == '\0')
+       UserEditor = getenv("VISUAL");
+    if (UserEditor && *UserEditor == '\0')
+       UserEditor = NULL;
+    else if (UserEditor) {
+       if (find_path(UserEditor, &Editor, getenv("PATH")) == FOUND) {
+           UserEditor = Editor;
+       } else {
+           if (def_flag(I_ENV_EDITOR)) {
+               /* If we are honoring $EDITOR this is a fatal error. */
+               (void) fprintf(stderr,
+                   "%s: specified editor (%s) doesn't exist!\n",
+                   Argv[0], UserEditor);
+               Exit(-1);
+           } else {
+               /* Otherwise, just ignore $EDITOR. */
+               UserEditor = NULL;
+           }
+       }
+    }
+
+    /*
+     * See if we can use the user's choice of editors either because
+     * we allow any $EDITOR or because $EDITOR is in the allowable list.
+     */
+    Editor = EditorPath = NULL;
+    if (def_flag(I_ENV_EDITOR) && UserEditor)
+       Editor = UserEditor;
+    else if (UserEditor) {
+       struct stat editor_sb;
+       struct stat user_editor_sb;
+       char *base, *userbase;
+
+       if (stat(UserEditor, &user_editor_sb) != 0) {
+           /* Should never happen since we already checked above. */
+           (void) fprintf(stderr, "%s: unable to stat editor (%s): %s\n",
+               Argv[0], UserEditor, strerror(errno));
+           Exit(-1);
+       }
+       EditorPath = estrdup(def_str(I_EDITOR));
+       Editor = strtok(EditorPath, ":");
+       do {
+           /*
+            * Both Editor and UserEditor should be fully qualified but
+            * check anyway...
+            */
+           if ((base = strrchr(Editor, '/')) == NULL)
+               continue;
+           if ((userbase = strrchr(UserEditor, '/')) == NULL) {
+               Editor = NULL;
+               break;
+           }
+           base++, userbase++;
+
+           /*
+            * We compare the basenames first and then use stat to match
+            * for sure.
+            */
+           if (strcmp(base, userbase) == 0) {
+               if (stat(Editor, &editor_sb) == 0 && S_ISREG(editor_sb.st_mode)
+                   && (editor_sb.st_mode & 0000111) &&
+                   editor_sb.st_dev == user_editor_sb.st_dev &&
+                   editor_sb.st_ino == user_editor_sb.st_ino)
+                   break;
+           }
+       } while ((Editor = strtok(NULL, ":")));
+    }
+
+    /*
+     * Can't use $EDITOR, try each element of I_EDITOR until we
+     * find one that exists, is regular, and is executable.
+     */
+    if (Editor == NULL || *Editor == '\0') {
+       if (EditorPath != NULL)
+           free(EditorPath);
+       EditorPath = estrdup(def_str(I_EDITOR));
+       Editor = strtok(EditorPath, ":");
+       do {
+           if (sudo_goodpath(Editor))
+               break;
+       } while ((Editor = strtok(NULL, ":")));
+
+       /* Bleah, none of the editors existed! */
+       if (Editor == NULL || *Editor == '\0') {
+           (void) fprintf(stderr, "%s: no editor found (editor path = %s)\n",
+               Argv[0], def_str(I_EDITOR));
+           Exit(-1);
+       }
+    }
+
+    /*
+     * Edit the temp file and parse it (for sanity checking)
+     */
+    do {
+       char linestr[64];
+
+       /* Build up argument vector for the command */
+       if ((av[0] = strrchr(Editor, '/')) != NULL)
+           av[0]++;
+       else
+           av[0] = Editor;
+       n = 1;
+       if (parse_error == TRUE) {
+           (void) snprintf(linestr, sizeof(linestr), "+%d", errorlineno);
+           av[n++] = linestr;
+       }
+       av[n++] = stmp;
+       av[n++] = NULL;
+
+       /*
+        * Do the edit:
+        *  We cannot check the editor's exit value against 0 since
+        *  XPG4 specifies that vi's exit value is a function of the
+        *  number of errors during editing (?!?!).
+        */
+       now = time(NULL);
+       if (run_command(Editor, av) != -1) {
+           /*
+            * Sanity checks.
+            */
+           if (stat(stmp, &stmp_sb) < 0) {
+               (void) fprintf(stderr,
+                   "%s: Can't stat temporary file (%s), %s unchanged.\n",
+                   Argv[0], stmp, sudoers);
+               Exit(-1);
+           }
+           if (stmp_sb.st_size == 0) {
+               (void) fprintf(stderr,
+                   "%s: Zero length temporary file (%s), %s unchanged.\n",
+                   Argv[0], stmp, sudoers);
+               Exit(-1);
+           }
+
+           /*
+            * Passed sanity checks so reopen stmp file and check
+            * for parse errors.
+            */
+           yyout = stdout;
+           if (parse_error)
+               yyin = freopen(stmp, "r", yyin);
+           else
+               yyin = fopen(stmp, "r");
+           if (yyin == NULL) {
+               (void) fprintf(stderr,
+                   "%s: Can't re-open temporary file (%s), %s unchanged.\n",
+                   Argv[0], stmp, sudoers);
+               Exit(-1);
+           }
+
+           /* Clean slate for each parse */
+           user_runas = NULL;
+           init_defaults();
+           init_parser();
+
+           /* Parse the sudoers file */
+           if (yyparse() && parse_error != TRUE) {
+               (void) fprintf(stderr,
+                   "%s: Failed to parse temporary file (%s), unknown error.\n",
+                   Argv[0], stmp);
+               parse_error = TRUE;
+           }
+       } else {
+           (void) fprintf(stderr,
+               "%s: Editor (%s) failed, %s unchanged.\n", Argv[0],
+                   Editor, sudoers);
+           Exit(-1);
+       }
+
+       /*
+        * Got an error, prompt the user for what to do now
+        */
+       if (parse_error == TRUE) {
+           switch (whatnow()) {
+               case 'Q' :      parse_error = FALSE;    /* ignore parse error */
+                               break;
+               case 'x' :      if (sudoers_sb.st_size == 0)
+                                   unlink(sudoers);
+                               Exit(0);
+                               break;
+           }
+           yyrestart(yyin);    /* reset lexer */
+       }
+    } while (parse_error == TRUE);
+
+    /*
+     * If the user didn't change the temp file, just unlink it.
+     */
+    if (sudoers_sb.st_mtime != now && sudoers_sb.st_mtime == stmp_sb.st_mtime &&
+       sudoers_sb.st_size == stmp_sb.st_size) {
+       (void) fprintf(stderr, "%s: sudoers file unchanged.\n", Argv[0]);
+       Exit(0);
+    }
+
+    /*
+     * Change mode and ownership of temp file so when
+     * we move it to sudoers things are kosher.
+     */
+    if (chown(stmp, SUDOERS_UID, SUDOERS_GID)) {
+       (void) fprintf(stderr,
+           "%s: Unable to set (uid, gid) of %s to (%d, %d): %s\n",
+           Argv[0], stmp, SUDOERS_UID, SUDOERS_GID, strerror(errno));
+       Exit(-1);
+    }
+    if (chmod(stmp, SUDOERS_MODE)) {
+       (void) fprintf(stderr,
+           "%s: Unable to change mode of %s to %o: %s\n",
+           Argv[0], stmp, SUDOERS_MODE, strerror(errno));
+       Exit(-1);
+    }
+
+    /*
+     * Now that we have a sane stmp file (parses ok) it needs to be
+     * rename(2)'d to sudoers.  If the rename(2) fails we try using
+     * mv(1) in case stmp and sudoers are on different filesystems.
+     */
+    if (rename(stmp, sudoers)) {
+       if (errno == EXDEV) {
+           (void) fprintf(stderr,
+             "%s: %s and %s not on the same filesystem, using mv to rename.\n",
+             Argv[0], stmp, sudoers);
+
+           /* Build up argument vector for the command */
+           if ((av[0] = strrchr(_PATH_MV, '/')) != NULL)
+               av[0]++;
+           else
+               av[0] = _PATH_MV;
+           av[1] = stmp;
+           av[2] = sudoers;
+           av[3] = NULL;
+
+           /* And run it... */
+           if (run_command(_PATH_MV, av)) {
+               (void) fprintf(stderr,
+                              "%s: Command failed: '%s %s %s', %s unchanged.\n",
+                              Argv[0], _PATH_MV, stmp, sudoers, sudoers);
+               Exit(-1);
+           }
+       } else {
+           (void) fprintf(stderr, "%s: Error renaming %s, %s unchanged: %s\n",
+                                  Argv[0], stmp, sudoers, strerror(errno));
+           Exit(-1);
+       }
+    }
+
+    exit(0);
+}
+
+/*
+ * Dummy *_matches routines.
+ * These exist to allow us to use the same parser as sudo(8).
+ */
+int
+command_matches(cmnd, cmnd_args, path, sudoers_args)
+    char *cmnd;
+    char *cmnd_args;
+    char *path;
+    char *sudoers_args;
+{
+    return(TRUE);
+}
+
+int
+addr_matches(n)
+    char *n;
+{
+    return(TRUE);
+}
+
+int
+hostname_matches(s, l, p)
+    char *s, *l, *p;
+{
+    return(TRUE);
+}
+
+int
+usergr_matches(g, u)
+    char *g, *u;
+{
+    return(TRUE);
+}
+
+int
+netgr_matches(n, h, sh, u)
+    char *n, *h, *sh, *u;
+{
+    return(TRUE);
+}
+
+void
+set_fqdn()
+{
+    return;
+}
+
+int
+user_is_exempt()
+{
+    return(TRUE);
+}
+
+void
+init_envtables()
+{
+    return;
+}
+
+/*
+ * Assuming a parse error occurred, prompt the user for what they want
+ * to do now.  Returns the first letter of their choice.
+ */
+static char
+whatnow()
+{
+    int choice, c;
+
+    for (;;) {
+       (void) fputs("What now? ", stdout);
+       choice = getchar();
+       for (c = choice; c != '\n' && c != EOF;)
+           c = getchar();
+
+       switch (choice) {
+           case EOF:
+               choice = 'x';
+               /* FALLTHROUGH */
+           case 'e':
+           case 'x':
+           case 'Q':
+               return(choice);
+           default:
+               (void) puts("Options are:");
+               (void) puts("  (e)dit sudoers file again");
+               (void) puts("  e(x)it without saving changes to sudoers file");
+               (void) puts("  (Q)uit and save changes to sudoers file (DANGER!)\n");
+       }
+    }
+}
+
+/*
+ * Install signal handlers for visudo.
+ */
+static void
+setup_signals()
+{
+       sigaction_t sa;
+
+       /*
+        * Setup signal handlers to cleanup nicely.
+        */
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_RESTART;
+       sa.sa_handler = Exit;
+       (void) sigaction(SIGTERM, &sa, NULL);
+       (void) sigaction(SIGHUP, &sa, NULL);
+       (void) sigaction(SIGINT, &sa, NULL);
+       (void) sigaction(SIGQUIT, &sa, NULL);
+}
+
+static int
+run_command(path, argv)
+    char *path;
+    char **argv;
+{
+    int status;
+    pid_t pid;
+    sigset_t set, oset;
+
+    (void) sigemptyset(&set);
+    (void) sigaddset(&set, SIGCHLD);
+    (void) sigprocmask(SIG_BLOCK, &set, &oset);
+
+    switch (pid = fork()) {
+       case -1:
+           (void) fprintf(stderr,
+               "%s: unable to run %s: %s\n", Argv[0], path, strerror(errno));
+           Exit(-1);
+           break;      /* NOTREACHED */
+       case 0:
+           (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+           execv(path, argv);
+           (void) fprintf(stderr,
+               "%s: unable to run %s: %s\n", Argv[0], path, strerror(errno));
+           _exit(127);
+           break;      /* NOTREACHED */
+    }
+
+#ifdef sudo_waitpid
+    pid = sudo_waitpid(pid, &status, 0);
+#else
+    pid = wait(&status);
+#endif
+
+    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+
+    /* XXX - should use WEXITSTATUS() */
+    return(pid == -1 ? -1 : (status >> 8));
+}
+
+static int
+check_syntax(quiet)
+    int quiet;
+{
+
+    if ((yyin = fopen(sudoers, "r")) == NULL) {
+       if (!quiet)
+           (void) fprintf(stderr, "%s: unable to open %s: %s\n", Argv[0],
+               sudoers, strerror(errno));
+       exit(1);
+    }
+    yyout = stdout;
+    init_parser();
+    if (yyparse() && parse_error != TRUE) {
+       if (!quiet)
+           (void) fprintf(stderr,
+               "%s: failed to parse %s file, unknown error.\n",
+               Argv[0], sudoers);
+       parse_error = TRUE;
+    }
+    if (!quiet){
+       if (parse_error)
+           (void) printf("parse error in %s near line %d\n", sudoers,
+               errorlineno);
+       else
+           (void) printf("%s file parsed OK\n", sudoers);
+    }
+
+    return(parse_error == TRUE);
+}
+
+/*
+ * Unlink the sudoers temp file (if it exists) and exit.
+ * Used in place of a normal exit() and as a signal handler.
+ * A positive parameter indicates we were called as a signal handler.
+ */
+static RETSIGTYPE
+Exit(sig)
+    int sig;
+{
+    char *emsg = " exiting due to signal.\n";
+
+    (void) unlink(stmp);
+
+    if (sig > 0) {
+       write(STDERR_FILENO, Argv[0], strlen(Argv[0]));
+       write(STDERR_FILENO, emsg, sizeof(emsg) - 1);
+       _exit(-sig);
+    }
+    exit(-sig);
+}
+
+static void
+usage()
+{
+    (void) fprintf(stderr, "usage: %s [-c] [-f sudoers] [-q] [-s] [-V]\n",
+       Argv[0]);
+    exit(1);
+}
diff --git a/visudo.cat b/visudo.cat
new file mode 100644 (file)
index 0000000..4c82169
--- /dev/null
@@ -0,0 +1,198 @@
+
+
+
+visudo(1m)             MAINTENANCE COMMANDS            visudo(1m)
+
+
+N\bN\bN\bNA\bA\bA\bAM\bM\bM\bME\bE\bE\bE
+       visudo - edit the sudoers file
+
+S\bS\bS\bSY\bY\bY\bYN\bN\bN\bNO\bO\bO\bOP\bP\bP\bPS\bS\bS\bSI\bI\bI\bIS\bS\bS\bS
+       v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo [ -\b-\b-\b-c\bc\bc\bc ] [ -\b-\b-\b-f\bf\bf\bf _\bs_\bu_\bd_\bo_\be_\br_\bs ] [ -\b-\b-\b-q\bq\bq\bq ] [ -\b-\b-\b-s\bs\bs\bs ] [ -\b-\b-\b-V\bV\bV\bV ]
+
+D\bD\bD\bDE\bE\bE\bES\bS\bS\bSC\bC\bC\bCR\bR\bR\bRI\bI\bI\bIP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bN
+       v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo edits the _\bs_\bu_\bd_\bo_\be_\br_\bs file in a safe fashion, analogous
+       to _\bv_\bi_\bp_\bw(1m).  v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo locks the _\bs_\bu_\bd_\bo_\be_\br_\bs file against multi­
+       ple simultaneous edits, provides basic sanity checks, and
+       checks for parse errors.  If the _\bs_\bu_\bd_\bo_\be_\br_\bs file is currently
+       being edited you will receive a message to try again
+       later.
+
+       There is a hard-coded list of editors that v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will use
+       set at compile-time that may be overridden via the _\be_\bd_\bi_\bt_\bo_\br
+       _\bs_\bu_\bd_\bo_\be_\br_\bs Default variable.  This list defaults to the path
+       to _\bv_\bi(1) on your system, as determined by the _\bc_\bo_\bn_\bf_\bi_\bg_\bu_\br_\be
+       script.  Normally, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo does not honor the EDITOR or
+       VISUAL environment variables unless they contain an editor
+       in the aforementioned editors list.  However, if v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is
+       configured with the _\b-_\b-_\bw_\bi_\bt_\bh_\b-_\be_\bn_\bv_\be_\bd_\bi_\bt_\bo_\br flag or the _\be_\bn_\bv_\be_\bd_\bi_\bt_\bo_\br
+       Default variable is set in _\bs_\bu_\bd_\bo_\be_\br_\bs, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will use any
+       the editor defines by EDITOR or VISUAL.  Note that this
+       can be a security hole since it allows the user to execute
+       any program they wish simply by setting EDITOR or VISUAL.
+
+       v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo parses the _\bs_\bu_\bd_\bo_\be_\br_\bs file after the edit and will not
+       save the changes if there is a syntax error.  Upon finding
+       an error, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will print a message stating the line
+       _\bn_\bu_\bm_\bb_\be_\br(s) where the error occurred and the user will
+       receive the "What now?" prompt.  At this point the user
+       may enter "e" to re-edit the _\bs_\bu_\bd_\bo_\be_\br_\bs file, "x" to exit
+       without saving the changes, or "Q" to quit and save
+       changes.  The "Q" option should be used with extreme care
+       because if v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo believes there to be a parse error, so
+       will s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo and no one will be able to s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo again until the
+       error is fixed.  If "e" is typed to edit the  _\bs_\bu_\bd_\bo_\be_\br_\bs file
+       after a parse error has been detected, the cursor will be
+       placed on the line where the error occurred (if the editor
+       supports this feature).
+
+O\bO\bO\bOP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bNS\bS\bS\bS
+       v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo accepts the following command line options:
+
+       -c  Enable c\bc\bc\bch\bh\bh\bhe\be\be\bec\bc\bc\bck\bk\bk\bk-\b-\b-\b-o\bo\bo\bon\bn\bn\bnl\bl\bl\bly\by\by\by mode.  The existing _\bs_\bu_\bd_\bo_\be_\br_\bs file
+           will be checked for syntax and a message will be
+           printed to the standard output detailing the status of
+           _\bs_\bu_\bd_\bo_\be_\br_\bs.  If the syntax check completes successfully,
+           v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will exit with a value of 0.  If a syntax error
+           is encountered, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will exit with a value of 1.
+
+       -f  Specify and alternate _\bs_\bu_\bd_\bo_\be_\br_\bs file location.  With
+           this option v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will edit (or check) the _\bs_\bu_\bd_\bo_\be_\br_\bs
+
+
+
+April 25, 2002                1.6.6                             1
+
+
+
+
+
+visudo(1m)             MAINTENANCE COMMANDS            visudo(1m)
+
+
+           file of your choice, instead of the default,
+           @sysconfdir@/sudoers.  The lock file used is the spec­
+           ified _\bs_\bu_\bd_\bo_\be_\br_\bs file with ".tmp" appended to it.
+
+       -q  Enable q\bq\bq\bqu\bu\bu\bui\bi\bi\bie\be\be\bet\bt\bt\bt mode.  In this mode details about syntax
+           errors are not printed.  This option is only useful
+           when combined with the -\b-\b-\b-c\bc\bc\bc flag.
+
+       -s  Enable s\bs\bs\bst\bt\bt\btr\br\br\bri\bi\bi\bic\bc\bc\bct\bt\bt\bt checking of the _\bs_\bu_\bd_\bo_\be_\br_\bs file.  If an
+           alias is used before it is defined, v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will con­
+           sider this a parse error.  Note that it is not possi­
+           ble to differentiate between an alias and a hostname
+           or username that consists solely of uppercase letters,
+           digits, and the underscore ('_') character.
+
+       -V  The -\b-\b-\b-V\bV\bV\bV (version) option causes v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo to print its
+           version number and exit.
+
+E\bE\bE\bER\bR\bR\bRR\bR\bR\bRO\bO\bO\bOR\bR\bR\bRS\bS\bS\bS
+       sudoers file busy, try again later.
+           Someone else is currently editing the _\bs_\bu_\bd_\bo_\be_\br_\bs file.
+
+       /etc/sudoers.tmp: Permission denied
+           You didn't run v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo as root.
+
+       Can't find you in the passwd database
+           Your userid does not appear in the system passwd file.
+
+       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, dig­
+           its, and the underscore ('_') character.  If the lat­
+           ter, you can ignore the warnings (s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo will not com­
+           plain).  In -\b-\b-\b-s\bs\bs\bs (strict) mode these are errors, not
+           warnings.
+
+E\bE\bE\bEN\bN\bN\bNV\bV\bV\bVI\bI\bI\bIR\bR\bR\bRO\bO\bO\bON\bN\bN\bNM\bM\bM\bME\bE\bE\bEN\bN\bN\bNT\bT\bT\bT
+       The following environment variables are used only if
+       v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo was configured with the _\b-_\b-_\bw_\bi_\bt_\bh_\b-_\be_\bn_\bv_\b-_\be_\bd_\bi_\bt_\bo_\br option:
+
+        EDITOR                 Invoked by visudo as the editor to use
+        VISUAL                 Used Invoked visudo if EDITOR is not set
+
+
+F\bF\bF\bFI\bI\bI\bIL\bL\bL\bLE\bE\bE\bES\bS\bS\bS
+        /etc/sudoers           List of who can run what
+        /etc/sudoers.tmp       Lock file for visudo
+
+
+A\bA\bA\bAU\bU\bU\bUT\bT\bT\bTH\bH\bH\bHO\bO\bO\bOR\bR\bR\bR
+       Many people have worked on _\bs_\bu_\bd_\bo over the years; this ver­
+       sion of v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo was written by:
+
+
+
+
+April 25, 2002                1.6.6                             2
+
+
+
+
+
+visudo(1m)             MAINTENANCE COMMANDS            visudo(1m)
+
+
+        Todd Miller            <Todd.Miller@courtesan.com>
+
+       See the HISTORY file in the sudo distribution or visit
+       http://www.sudo.ws/sudo/history.html for more details.
+
+B\bB\bB\bBU\bU\bU\bUG\bG\bG\bGS\bS\bS\bS
+       If you feel you have found a bug in sudo, please submit a
+       bug report at http://www.sudo.ws/sudo/bugs/
+
+D\bD\bD\bDI\bI\bI\bIS\bS\bS\bSC\bC\bC\bCL\bL\bL\bLA\bA\bA\bAI\bI\bI\bIM\bM\bM\bME\bE\bE\bER\bR\bR\bR
+       V\bV\bV\bVi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo is provided ``AS IS'' and any express or implied
+       warranties, including, but not limited to, the implied
+       warranties of merchantability and fitness for a particular
+       purpose are disclaimed.  See the LICENSE file distributed
+       with s\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo for complete details.
+
+C\bC\bC\bCA\bA\bA\bAV\bV\bV\bVE\bE\bE\bEA\bA\bA\bAT\bT\bT\bTS\bS\bS\bS
+       There is no easy way to prevent a user from gaining a root
+       shell if the editor used by v\bv\bv\bvi\bi\bi\bis\bs\bs\bsu\bu\bu\bud\bd\bd\bdo\bo\bo\bo allows shell escapes.
+
+S\bS\bS\bSE\bE\bE\bEE\bE\bE\bE A\bA\bA\bAL\bL\bL\bLS\bS\bS\bSO\bO\bO\bO
+       _\bv_\bi(1), _\bs_\bu_\bd_\bo(1m), _\bv_\bi_\bp_\bw(8).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+April 25, 2002                1.6.6                             3
+
+
diff --git a/visudo.man.in b/visudo.man.in
new file mode 100644 (file)
index 0000000..cfcfa23
--- /dev/null
@@ -0,0 +1,274 @@
+.\" Automatically generated by Pod::Man version 1.15
+.\" Thu Apr 25 09:34:54 2002
+.\"
+.\" Standard preamble:
+.\" ======================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+
+.fi
+..
+.\" 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
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` 
+.    ds C' 
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" 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 \{\
+.    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
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.bd B 3
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ======================================================================
+.\"
+.IX Title "visudo @mansectsu@"
+.TH visudo @mansectsu@ "1.6.6" "April 25, 2002" "MAINTENANCE COMMANDS"
+.UC
+.SH "NAME"
+visudo \- edit the sudoers file
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBvisudo\fR [ \fB\-c\fR ] [ \fB\-f\fR \fIsudoers\fR ] [ \fB\-q\fR ] [ \fB\-s\fR ] [ \fB\-V\fR ]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBvisudo\fR edits the \fIsudoers\fR file in a safe fashion, analogous to
+\&\fIvipw\fR\|(@mansectsu@).  \fBvisudo\fR locks the \fIsudoers\fR file against multiple
+simultaneous edits, provides basic sanity checks, and checks
+for parse errors.  If the \fIsudoers\fR file is currently being
+edited you will receive a message to try again later.
+.PP
+There is a hard-coded list of editors that \fBvisudo\fR will use set
+at compile-time that may be overridden via the \fIeditor\fR \fIsudoers\fR
+\&\f(CW\*(C`Default\*(C'\fR variable.  This list defaults to the path to \fIvi\fR\|(1) on
+your system, as determined by the \fIconfigure\fR script.  Normally,
+\&\fBvisudo\fR does not honor the \f(CW\*(C`EDITOR\*(C'\fR or \f(CW\*(C`VISUAL\*(C'\fR environment
+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 \fIenveditor\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`EDITOR\*(C'\fR or \f(CW\*(C`VISUAL\*(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`EDITOR\*(C'\fR or \f(CW\*(C`VISUAL\*(C'\fR.
+.PP
+\&\fBvisudo\fR parses the \fIsudoers\fR file after the edit and will
+not save the changes if there is a syntax error.  Upon finding
+an error, \fBvisudo\fR will print a message stating the line \fInumber\fR\|(s)
+where the error occurred and the user will receive the
+\&\*(L"What now?\*(R" prompt.  At this point the user may enter \*(L"e\*(R"
+to re-edit the \fIsudoers\fR file, \*(L"x\*(R" to exit without
+saving the changes, or \*(L"Q\*(R" to quit and save changes.  The
+\&\*(L"Q\*(R" option should be used with extreme care because if \fBvisudo\fR
+believes there to be a parse error, so will \fBsudo\fR and no one
+will be able to \fBsudo\fR again until the error is fixed.
+If \*(L"e\*(R" is typed to edit the  \fIsudoers\fR file after a parse error
+has been detected, the cursor will be placed on the line where the
+error occurred (if the editor supports this feature).
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBvisudo\fR accepts the following command line options:
+.Ip "\-c" 4
+.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
+standard output detailing the status of \fIsudoers\fR.
+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"
+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, \f(CW@sysconfdir\fR@/sudoers.  The lock file used
+is the specified \fIsudoers\fR file with \*(L".tmp\*(R" appended to it.
+.Ip "\-q" 4
+.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
+.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
+.IX Item "-V"
+The \fB\-V\fR (version) option causes \fBvisudo\fR to print its version number
+and exit.
+.SH "ERRORS"
+.IX Header "ERRORS"
+.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
+.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.
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+The following environment variables are used only if \fBvisudo\fR
+was configured with the \fI\*(--with-env-editor\fR option:
+.PP
+.Vb 2
+\& EDITOR                 Invoked by visudo as the editor to use
+\& VISUAL                 Used Invoked visudo if EDITOR is not set
+.Ve
+.SH "FILES"
+.IX Header "FILES"
+.Vb 2
+\& @sysconfdir@/sudoers           List of who can run what
+\& @sysconfdir@/sudoers.tmp       Lock file for visudo
+.Ve
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Many people have worked on \fIsudo\fR over the years; this version of
+\&\fBvisudo\fR was written by:
+.PP
+.Vb 1
+\& Todd Miller            <Todd.Miller@courtesan.com>
+.Ve
+See the \s-1HISTORY\s0 file in the sudo distribution or visit
+http://www.sudo.ws/sudo/history.html for more details.
+.SH "BUGS"
+.IX Header "BUGS"
+If you feel you have found a bug in sudo, please submit a bug report
+at http://www.sudo.ws/sudo/bugs/
+.SH "DISCLAIMER"
+.IX Header "DISCLAIMER"
+\&\fBVisudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties,
+including, but not limited to, the implied warranties of merchantability
+and fitness for a particular purpose are disclaimed.
+See the \s-1LICENSE\s0 file distributed with \fBsudo\fR for complete details.
+.SH "CAVEATS"
+.IX Header "CAVEATS"
+There is no easy way to prevent a user from gaining a root shell if 
+the editor used by \fBvisudo\fR allows shell escapes.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIvi\fR\|(1), \fIsudo\fR\|(@mansectsu@), \fIvipw\fR\|(8).
diff --git a/visudo.pod b/visudo.pod
new file mode 100644 (file)
index 0000000..3e7a41f
--- /dev/null
@@ -0,0 +1,192 @@
+=cut
+Copyright (c) 1996,1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission
+   from the author.
+
+4. Products derived from this software may not be called "Sudo" nor
+   may "Sudo" appear in their names without specific prior written
+   permission from the author.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$Sudo: visudo.pod,v 1.28 2002/01/12 22:55:01 millert Exp $
+=pod
+
+=head1 NAME
+
+visudo - edit the sudoers file
+
+=head1 SYNOPSIS
+
+B<visudo> [ B<-c> ] [ B<-f> I<sudoers> ] [ B<-q> ] [ B<-s> ] [ B<-V> ]
+
+=head1 DESCRIPTION
+
+B<visudo> edits the I<sudoers> file in a safe fashion, analogous to
+vipw(8).  B<visudo> locks the I<sudoers> file against multiple
+simultaneous edits, provides basic sanity checks, and checks
+for parse errors.  If the I<sudoers> file is currently being
+edited you will receive a message to try again later.
+
+There is a hard-coded list of editors that B<visudo> will use set
+at compile-time that may be overridden via the I<editor> I<sudoers>
+C<Default> variable.  This list defaults to the path to vi(1) on
+your system, as determined by the I<configure> script.  Normally,
+B<visudo> does not honor the C<EDITOR> or C<VISUAL> environment
+variables unless they contain an editor in the aforementioned editors
+list.  However, if B<visudo> is configured with the I<--with-enveditor>
+flag or the I<enveditor> C<Default> variable is set in I<sudoers>,
+B<visudo> will use any the editor defines by C<EDITOR> or C<VISUAL>.
+Note that this can be a security hole since it allows the user to
+execute any program they wish simply by setting C<EDITOR> or C<VISUAL>.
+
+B<visudo> parses the I<sudoers> file after the edit and will
+not save the changes if there is a syntax error.  Upon finding
+an error, B<visudo> will print a message stating the line number(s)
+where the error occurred and the user will receive the
+"What now?" prompt.  At this point the user may enter "e"
+to re-edit the I<sudoers> file, "x" to exit without
+saving the changes, or "Q" to quit and save changes.  The
+"Q" option should be used with extreme care because if B<visudo>
+believes there to be a parse error, so will B<sudo> and no one
+will be able to B<sudo> again until the error is fixed.
+If "e" is typed to edit the  I<sudoers> file after a parse error
+has been detected, the cursor will be placed on the line where the
+error occurred (if the editor supports this feature).
+
+=head1 OPTIONS
+
+B<visudo> accepts the following command line options:
+
+=over 4
+
+=item -c
+
+Enable B<check-only> mode.  The existing I<sudoers> file will be
+checked for syntax and a message will be printed to the
+standard output detailing the status of I<sudoers>.
+If the syntax check completes successfully, B<visudo> will
+exit with a value of 0.  If a syntax error is encountered,
+B<visudo> will exit with a value of 1.
+
+=item -f
+
+Specify and alternate I<sudoers> file location.  With this option
+B<visudo> will edit (or check) the I<sudoers> file of your choice,
+instead of the default, @sysconfdir@/sudoers.  The lock file used
+is the specified I<sudoers> file with ".tmp" appended to it.
+
+=item -q
+
+Enable B<quiet> mode.  In this mode details about syntax errors
+are not printed.  This option is only useful when combined with
+the B<-c> flag.
+
+=item -s
+
+Enable B<strict> checking of the I<sudoers> file.  If an alias is
+used before it is defined, B<visudo> 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.
+
+=item -V
+
+The B<-V> (version) option causes B<visudo> to print its version number
+and exit.
+
+=back
+
+=head1 ERRORS
+
+=over 4
+
+=item sudoers file busy, try again later.
+
+Someone else is currently editing the I<sudoers> file.
+
+=item @sysconfdir@/sudoers.tmp: Permission denied
+
+You didn't run B<visudo> as root.
+
+=item Can't find you in the passwd database
+
+Your userid does not appear in the system passwd file.
+
+=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 (B<sudo> will not complain).  In B<-s> (strict)
+mode these are errors, not warnings.
+
+=back
+
+=head1 ENVIRONMENT
+
+The following environment variables are used only if B<visudo>
+was configured with the I<--with-env-editor> option:
+
+ EDITOR                        Invoked by visudo as the editor to use
+ VISUAL                        Used Invoked visudo if EDITOR is not set
+
+=head1 FILES
+
+ @sysconfdir@/sudoers          List of who can run what
+ @sysconfdir@/sudoers.tmp      Lock file for visudo
+
+=head1 AUTHOR
+
+Many people have worked on I<sudo> over the years; this version of
+B<visudo> was written by:
+
+ Todd Miller           <Todd.Miller@courtesan.com>
+
+See the HISTORY file in the sudo distribution or visit
+http://www.sudo.ws/sudo/history.html for more details.
+
+=head1 BUGS
+
+If you feel you have found a bug in sudo, please submit a bug report
+at http://www.sudo.ws/sudo/bugs/
+
+=head1 DISCLAIMER
+
+B<Visudo> is provided ``AS IS'' and any express or implied warranties,
+including, but not limited to, the implied warranties of merchantability
+and fitness for a particular purpose are disclaimed.
+See the LICENSE file distributed with B<sudo> for complete details.
+
+=head1 CAVEATS
+
+There is no easy way to prevent a user from gaining a root shell if 
+the editor used by B<visudo> allows shell escapes.
+
+=head1 SEE ALSO
+
+vi(1), sudo(8), vipw(8).