From ca3ab12a66fc683cabf546fd405cfbf39ef9fb6f Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 14 May 2008 12:03:12 -0600 Subject: [PATCH] Imported Upstream version 1.6.6 --- BUGS | 25 + CHANGES | 1531 ++++++ HISTORY | 36 + INSTALL | 642 +++ INSTALL.configure | 181 + LICENSE | 65 + Makefile.in | 368 ++ PORTING | 91 + README | 100 + RUNSON | 158 + TODO | 114 + TROUBLESHOOTING | 175 + UPGRADE | 60 + aclocal.m4 | 346 ++ aixcrypt.exp | 4 + alloc.c | 171 + alloca.c | 457 ++ auth/API | 128 + auth/afs.c | 105 + auth/aix_auth.c | 84 + auth/bsdauth.c | 187 + auth/dce.c | 220 + auth/fwtk.c | 178 + auth/kerb4.c | 125 + auth/kerb5.c | 318 ++ auth/pam.c | 261 + auth/passwd.c | 123 + auth/rfc1938.c | 156 + auth/secureware.c | 116 + auth/securid.c | 125 + auth/sia.c | 153 + auth/sudo_auth.c | 271 + auth/sudo_auth.h | 131 + check.c | 498 ++ compat.h | 256 + config.guess | 1298 +++++ config.h.in | 535 ++ config.sub | 1379 +++++ configure | 11640 +++++++++++++++++++++++++++++++++++++++++++ configure.in | 1952 ++++++++ def_data.c | 179 + def_data.h | 58 + def_data.in | 182 + defaults.c | 785 +++ defaults.h | 124 + emul/fnmatch.h | 52 + emul/search.h | 45 + emul/utime.h | 45 + env.c | 487 ++ fileops.c | 152 + find_path.c | 158 + fnmatch.3 | 148 + fnmatch.c | 232 + getcwd.c | 275 + getspwuid.c | 260 + goodpath.c | 82 + indent.pro | 35 + ins_2001.h | 53 + ins_classic.h | 53 + ins_csops.h | 54 + ins_goons.h | 68 + install-sh | 227 + insults.h | 80 + interfaces.c | 325 ++ interfaces.h | 62 + lex.yy.c | 2556 ++++++++++ logging.c | 634 +++ logging.h | 70 + lsearch.c | 102 + mkdefaults | 81 + mkinstalldirs | 75 + parse.c | 527 ++ parse.h | 116 + parse.lex | 443 ++ parse.yacc | 1193 +++++ pathnames.h.in | 107 + sample.pam | 8 + sample.sudoers | 129 + sample.syslog.conf | 25 + set_perms.c | 344 ++ sigaction.c | 155 + snprintf.c | 775 +++ strcasecmp.c | 112 + strerror.c | 56 + sudo.c | 1035 ++++ sudo.cat | 462 ++ sudo.h | 243 + sudo.man.in | 456 ++ sudo.pod | 376 ++ sudo.tab.c | 1898 +++++++ sudo.tab.h | 27 + sudoers | 28 + sudoers.cat | 1188 +++++ sudoers.man.in | 1090 ++++ sudoers.pod | 1048 ++++ testsudoers.c | 431 ++ tgetpass.c | 300 ++ utime.c | 74 + version.h | 42 + visudo.c | 712 +++ visudo.cat | 198 + visudo.man.in | 274 + visudo.pod | 192 + 103 files changed, 46566 insertions(+) create mode 100644 BUGS create mode 100644 CHANGES create mode 100644 HISTORY create mode 100644 INSTALL create mode 100644 INSTALL.configure create mode 100644 LICENSE create mode 100644 Makefile.in create mode 100644 PORTING create mode 100644 README create mode 100644 RUNSON create mode 100644 TODO create mode 100644 TROUBLESHOOTING create mode 100644 UPGRADE create mode 100644 aclocal.m4 create mode 100644 aixcrypt.exp create mode 100644 alloc.c create mode 100644 alloca.c create mode 100644 auth/API create mode 100644 auth/afs.c create mode 100644 auth/aix_auth.c create mode 100644 auth/bsdauth.c create mode 100644 auth/dce.c create mode 100644 auth/fwtk.c create mode 100644 auth/kerb4.c create mode 100644 auth/kerb5.c create mode 100644 auth/pam.c create mode 100644 auth/passwd.c create mode 100644 auth/rfc1938.c create mode 100644 auth/secureware.c create mode 100644 auth/securid.c create mode 100644 auth/sia.c create mode 100644 auth/sudo_auth.c create mode 100644 auth/sudo_auth.h create mode 100644 check.c create mode 100644 compat.h create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 def_data.c create mode 100644 def_data.h create mode 100644 def_data.in create mode 100644 defaults.c create mode 100644 defaults.h create mode 100644 emul/fnmatch.h create mode 100644 emul/search.h create mode 100644 emul/utime.h create mode 100644 env.c create mode 100644 fileops.c create mode 100644 find_path.c create mode 100644 fnmatch.3 create mode 100644 fnmatch.c create mode 100644 getcwd.c create mode 100644 getspwuid.c create mode 100644 goodpath.c create mode 100644 indent.pro create mode 100644 ins_2001.h create mode 100644 ins_classic.h create mode 100644 ins_csops.h create mode 100644 ins_goons.h create mode 100755 install-sh create mode 100644 insults.h create mode 100644 interfaces.c create mode 100644 interfaces.h create mode 100644 lex.yy.c create mode 100644 logging.c create mode 100644 logging.h create mode 100644 lsearch.c create mode 100755 mkdefaults create mode 100755 mkinstalldirs create mode 100644 parse.c create mode 100644 parse.h create mode 100644 parse.lex create mode 100644 parse.yacc create mode 100644 pathnames.h.in create mode 100644 sample.pam create mode 100644 sample.sudoers create mode 100644 sample.syslog.conf create mode 100644 set_perms.c create mode 100644 sigaction.c create mode 100644 snprintf.c create mode 100644 strcasecmp.c create mode 100644 strerror.c create mode 100644 sudo.c create mode 100644 sudo.cat create mode 100644 sudo.h create mode 100644 sudo.man.in create mode 100644 sudo.pod create mode 100644 sudo.tab.c create mode 100644 sudo.tab.h create mode 100644 sudoers create mode 100644 sudoers.cat create mode 100644 sudoers.man.in create mode 100644 sudoers.pod create mode 100644 testsudoers.c create mode 100644 tgetpass.c create mode 100644 utime.c create mode 100644 version.h create mode 100644 visudo.c create mode 100644 visudo.cat create mode 100644 visudo.man.in create mode 100644 visudo.pod diff --git a/BUGS b/BUGS new file mode 100644 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 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" + +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 + (. + +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 ) + +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 . + +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 . + 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 . + +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 . + +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 . + +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 ) + +101) Merged in changes for Interactive Unix and RISCos. + (from Andy Smith ) + +102) Added testsudoers (from Chris Jepeway ). + +103) Added fix for parse.yacc to avoid the kludge I was doing. + (from Chris Jepeway ) + +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 . + +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" . + +112) Added an option to run the command in the background (-b) as + suggested by Jonathan Adams + +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" + +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 + and Navjot Singh . + +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 and + Navjot Singh . + +126) A timeout of 0 will now cause a password to be entered every + time. Based on a suggestion by Larry Auton + and Navjot Singh . + +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 . + +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 . + +139) Updated testsudoers.c to grok netgroups. + +CHANGES from sudo 1.3.4 BETA + +140) Added SecurID support from Giles Todd . + +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" + +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" + +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 + . + +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 . + +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 + +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 . + +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 . + +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 + + +201) Only link with -lshadow for Linux if libc lacks getspnam(). Problem + pointed out by Michael Meskes . + +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 . + +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 . + +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 and + Klee Dienes (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 . + +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 . + +277) Fixed an off by one error in the parser. Found by + Piete Brooks + +278) Change NewArgv size computation to work on UNICOS. + From Mike Kienenberger + +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 + +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" . + +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 + +290) RedHat Linux pam support, from Gary Calvin . + 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 + +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 . + +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 . + +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 . + +306) Set USER environment variable to target user. + Suggested by Ray Bellis . + +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 . + +313) Missing pieces from change #308; from Mike Kienenberger. + +314) Real Kerberos 5 support from Frank Cusack . + +315) FWTK 'authsrv' support from Kevin Kadow . + +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 . + +324) Fixed a parse bug wrt the ! operator and runas specs. Noted by + David A Beck . + +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 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 continues to enhance sudo and fix bugs. diff --git a/INSTALL b/INSTALL new file mode 100644 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 index 0000000..a2c8722 --- /dev/null +++ b/INSTALL.configure @@ -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 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 + 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 index 0000000..1a5f76f --- /dev/null +++ b/Makefile.in @@ -0,0 +1,368 @@ +# +# Copyright (c) 1996, 1998-2002 Todd C. Miller +# 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 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 . + +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 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 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 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 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 index 0000000..6e54d78 --- /dev/null +++ b/TROUBLESHOOTING @@ -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 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 index 0000000..8a156b0 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,346 @@ +dnl Local m4 macors for autoconf (used by sudo) +dnl +dnl Copyright (c) 1994-1996,1998-2002 Todd C. Miller +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 +#include +#if STDC_HEADERS +#include +#endif +#if HAVE_UNISTD_H +#include +#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 +#include +#include +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 +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 ], [(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 +#include +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 +#include +#include +#include +#include +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 < + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#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 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 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 +#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 +#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 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 index 0000000..e00e690 --- /dev/null +++ b/auth/afs.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#include "sudo.h" +#include "sudo_auth.h" + +#undef VOID +#include +#include + +#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 index 0000000..4ae2f5a --- /dev/null +++ b/auth/aix_auth.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#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 index 0000000..2bfc6f0 --- /dev/null +++ b/auth/bsdauth.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2000-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include + +#include +#include + +#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 index 0000000..8d4115b --- /dev/null +++ b/auth/dce.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 1996, 1998, 1999, 2001 + * Todd C. Miller . All rights reserved. + * + * This code is derived from software contributed by Jeff Earickson + * of Colby College, Waterville, ME + * + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#include +#include +#include /* 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 index 0000000..9eedda4 --- /dev/null +++ b/auth/fwtk.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#include +#include + +#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 index 0000000..fd64aab --- /dev/null +++ b/auth/kerb4.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include + +#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 index 0000000..1992c1d --- /dev/null +++ b/auth/kerb5.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * All rights reserved. + * + * This code is derived from software contributed by Frank Cusack + * . + * + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include + +#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/ 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/ 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 index 0000000..28603f5 --- /dev/null +++ b/auth/pam.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#include + +#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 index 0000000..98a9fdb --- /dev/null +++ b/auth/passwd.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#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 index 0000000..0ad125d --- /dev/null +++ b/auth/rfc1938.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1994-1996, 1998-1999, 2001 + * Todd C. Miller . 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#if defined(HAVE_SKEY) +#include +#define RFC1938 skey +#define rfc1938challenge skeychallenge +#define rfc1938verify skeyverify +#elif defined(HAVE_OPIE) +#include +#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 index 0000000..4ed7297 --- /dev/null +++ b/auth/secureware.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1998, 1999, 2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#ifdef __hpux +# undef MAXINT +# include +#else +# include +#endif /* __hpux */ +#include + +#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 index 0000000..9da4d5e --- /dev/null +++ b/auth/securid.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * All rights reserved. + * + * This code is derived from software contributed by Giles Todd + * . + * + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#include +#include +#include + +#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 index 0000000..09b67e2 --- /dev/null +++ b/auth/sia.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include + +#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 index 0000000..eb4c3c4 --- /dev/null +++ b/auth/sudo_auth.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include + +#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 index 0000000..f2db87d --- /dev/null +++ b/auth/sudo_auth.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 index 0000000..242aa00 --- /dev/null +++ b/check.c @@ -0,0 +1,498 @@ +/* + * Copyright (c) 1993-1996,1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include +#include +#include + +#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(×tampdir, ×tampfile); + 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(×tampdir, ×tampfile); + 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 index 0000000..09f95e3 --- /dev/null +++ b/compat.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 1996, 1998-2002 Todd C. Miller + * 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 or + */ +#ifndef howmany +# define howmany(x, y) (((x) + ((y) - 1)) / (y)) +#endif + +/* + * These should be defined in 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 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 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 index 0000000..6012b39 --- /dev/null +++ b/config.guess @@ -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 . +# Please send patches to . +# +# 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 ." + +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 <$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 /* 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 + + 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 + #include + + 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 + 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 < +#ifdef __cplusplus +#include /* 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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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 index 0000000..281fc13 --- /dev/null +++ b/config.h.in @@ -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 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 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 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 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 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 header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define if you have the 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 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 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 header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the 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 header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the 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 header file. */ +#undef HAVE_SYS_BSDTYPES_H + +/* Define if you have the header file, and it defines `DIR'. */ +#undef HAVE_SYS_DIR_H + +/* Define if you have the header file, and it defines `DIR'. */ +#undef HAVE_SYS_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have the header file and the `tcgetattr' + function. */ +#undef HAVE_TERMIOS_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the `tzset' function. */ +#undef HAVE_TZSET + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the `utime' function. */ +#undef HAVE_UTIME + +/* Define if you have the 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 doesn't define. */ +#undef gid_t + +/* Define if your system lacks the ino_t type. */ +#undef ino_t + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to `int' if 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 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 index 0000000..31600b0 --- /dev/null +++ b/config.sub @@ -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 . +# +# 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 ." + +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 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 +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#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 < if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + 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 </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 <\?\"\']*) + 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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:3183: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:3185: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:3188: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:3190: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &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 ' \ + '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 +$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 +#include +#include +#include +/* 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 + 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 +_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 + 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 +_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 +/* 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 <>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 +/* 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 <>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 +/* 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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +#include +#include + +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:::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 +/* 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 <&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 +/* 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 <&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 +/* 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 +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 +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 +#include +#include +#include + +_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 + +_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 + +_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 +#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 +#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 <&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 <&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 +#include +#include +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 <&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 <&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 +_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 <&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 <&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 + +_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 +#include + +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 <>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 +#include + +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 <>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 +#include +#if STDC_HEADERS +#include +#endif +#if HAVE_UNISTD_H +#include +#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 +#include +#if STDC_HEADERS +#include +#endif +#if HAVE_UNISTD_H +#include +#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 +#include +#if STDC_HEADERS +#include +#endif +#if HAVE_UNISTD_H +#include +#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 +#include +#if STDC_HEADERS +#include +#endif +#if HAVE_UNISTD_H +#include +#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 +#include +#include +#include +#include +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 <&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 +#include +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 +#include +#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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +/* 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 <&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 +_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 +/* 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 <&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 +#include +#include +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 +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 +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 +/* 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 <&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 +/* 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 <&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 +/* 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 +/* 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 +/* 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 +/* 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 +/* 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 +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 +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include +# 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 +/* 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 <&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 <>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 <&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 <&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 ." +EOF + +cat >>$CONFIG_STATUS <>$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 <>$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 <\$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 <>$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 <>$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 <>$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 index 0000000..9a818ff --- /dev/null +++ b/configure.in @@ -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 +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 +#include +#include + ], [exit(0);], AC_MSG_RESULT(no), + [AC_MSG_RESULT([yes, fixing locally]) + sed 's:::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 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 does not define.])], [#include +#include ]) +AC_CHECK_TYPES([sigaction_t], [AC_DEFINE(HAVE_SIGACTION_T, 1, [Define if has the sigaction_t typedef.])], ,[#include +#include ]) +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 index 0000000..ec02d88 --- /dev/null +++ b/def_data.c @@ -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 index 0000000..dcf2cc8 --- /dev/null +++ b/def_data.h @@ -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 index 0000000..3fac373 --- /dev/null +++ b/def_data.in @@ -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 index 0000000..4621bbe --- /dev/null +++ b/defaults.c @@ -0,0 +1,785 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +# ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include + +#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 + +/* + * 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 index 0000000..9d69a47 --- /dev/null +++ b/defaults.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1999-2001 Todd C. Miller + * 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 +#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 index 0000000..7a66a46 --- /dev/null +++ b/emul/fnmatch.h @@ -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 / 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 index 0000000..2ca992c --- /dev/null +++ b/emul/search.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1999 Todd C. Miller + * 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 index 0000000..be03349 --- /dev/null +++ b/emul/utime.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller + * 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 index 0000000..f49e51e --- /dev/null +++ b/env.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2000, 2001 Todd C. Miller + * 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 +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include + +#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 index 0000000..a3dd56d --- /dev/null +++ b/fileops.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * 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 +#include +#ifdef HAVE_FLOCK +# include +#endif /* HAVE_FLOCK */ +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#ifdef HAVE_UTIME +# ifdef HAVE_UTIME_H +# include +# 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 index 0000000..b4282cf --- /dev/null +++ b/find_path.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#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 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 +.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 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 +#include +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# 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 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 +#include + +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# 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 index 0000000..8b328c7 --- /dev/null +++ b/getspwuid.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#ifdef HAVE_GETSPNAM +# include +#endif /* HAVE_GETSPNAM */ +#ifdef HAVE_GETPRPWNAM +# ifdef __hpux +# undef MAXINT +# include +# else +# include +# endif /* __hpux */ +# include +#endif /* HAVE_GETPRPWNAM */ +#ifdef HAVE_GETPWANAM +# include +# include +# include +#endif /* HAVE_GETPWANAM */ +#ifdef HAVE_GETAUTHUID +# include +#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 index 0000000..96b8bd5 --- /dev/null +++ b/goodpath.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1996, 1998, 1999, 2001 + * Todd C. Miller . 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 +#include +#include +#include +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include + +#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 index 0000000..b8269d8 --- /dev/null +++ b/indent.pro @@ -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 index 0000000..bd29863 --- /dev/null +++ b/ins_2001.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller + * 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 index 0000000..975f381 --- /dev/null +++ b/ins_classic.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller + * 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 index 0000000..3baac82 --- /dev/null +++ b/ins_csops.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller + * 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 index 0000000..4cf6462 --- /dev/null +++ b/ins_goons.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller + * 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 index 0000000..5a6d399 --- /dev/null +++ b/install-sh @@ -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 index 0000000..69271a6 --- /dev/null +++ b/insults.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller + * 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 index 0000000..eda0d60 --- /dev/null +++ b/interfaces.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#include +#if defined(HAVE_SYS_SOCKIO_H) && !defined(SIOCGIFCONF) +# include +#endif +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#ifdef _ISC +# include +# include +# include +# include +# 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 +#endif /* _MIPS */ +#include +#include +#include +#ifdef HAVE_GETIFADDRS +# include +#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 index 0000000..e04809e --- /dev/null +++ b/interfaces.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 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 +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* 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 +#include +#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 + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include +#include "sudo.h" +#include "parse.h" +#include + +#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 +#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 index 0000000..723d19e --- /dev/null +++ b/logging.c @@ -0,0 +1,634 @@ +/* + * Copyright (c) 1994-1996,1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include + +#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 index 0000000..da4b02a --- /dev/null +++ b/logging.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999 Todd C. Miller + * 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 +#ifdef __STDC__ +# include +#else +# include +#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 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 +#include +#ifdef HAVE_UNISTD_H +# include +#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 index 0000000..82ef6bd --- /dev/null +++ b/mkdefaults @@ -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() { + 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 index 0000000..935edea --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,75 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# 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 index 0000000..97c0306 --- /dev/null +++ b/parse.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 1996, 1998-2002 Todd C. Miller + * 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 +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_FNMATCH +# include +#endif /* HAVE_FNMATCH_H */ +#ifdef HAVE_NETGROUP_H +# include +#endif /* HAVE_NETGROUP_H */ +#include +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# 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 index 0000000..939f403 --- /dev/null +++ b/parse.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1996, 1998-2000 Todd C. Miller + * 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 index 0000000..773be1b --- /dev/null +++ b/parse.lex @@ -0,0 +1,443 @@ +%{ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include +#include "sudo.h" +#include "parse.h" +#include + +#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 + +%% +[[:blank:]]+ BEGIN STARTDEFS; + +{DEFVAR} { + BEGIN INDEFS; + LEXTRACE("DEFVAR "); + fill(yytext, yyleng); + return(DEFVAR); + } + +{ + , { + 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); + } +} + +{ + \\[:\\,= \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 */ +} + +^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); + } + } + +^(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); + } + +\( { + 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); + } + } + +(#[0-9-]+|{WORD}) { + /* username/uid that user can run command as */ + fill(yytext, yyleng); + LEXTRACE("WORD(3) "); + return(WORD); + } + +\) { + 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 */ + +{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 \ */ + +#.*\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 index 0000000..7a6fb4e --- /dev/null +++ b/parse.yacc @@ -0,0 +1,1193 @@ +%{ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +# include +#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */ +#ifdef HAVE_LSEARCH +# include +#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 /* absolute pathname w/ optional args */ +%token ALIAS /* an UPPERCASE alias name */ +%token DEFVAR /* a Defaults variable name */ +%token NTWKADDR /* w.x.y.z */ +%token NETGROUP /* a netgroup (+NAME) */ +%token USERGROUP /* a usergroup (%NAME) */ +%token WORD /* a word */ +%token DEFAULTS /* Defaults entry */ +%token DEFAULTS_HOST /* Host-specific defaults entry */ +%token DEFAULTS_USER /* User-specific defaults entry */ +%token RUNAS /* ( runas_list ) */ +%token NOPASSWD /* no passwd req for command */ +%token PASSWD /* passwd req for command (default) */ +%token ALL /* ALL keyword */ +%token COMMENT /* comment and/or carriage return */ +%token HOSTALIAS /* Host_Alias keyword */ +%token CMNDALIAS /* Cmnd_Alias keyword */ +%token USERALIAS /* User_Alias keyword */ +%token RUNASALIAS /* Runas_Alias keyword */ +%token ':' '=' ',' '!' '+' '-' /* union member tokens */ +%token 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 cmnd +%type host +%type runasuser +%type oprunasuser +%type runaslist +%type 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 index 0000000..984a835 --- /dev/null +++ b/pathnames.h.in @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1996, 1998, 1999, 2001 + * Todd C. Miller . 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 +#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 index 0000000..b2efeab --- /dev/null +++ b/sample.pam @@ -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 index 0000000..f4b471a --- /dev/null +++ b/sample.sudoers @@ -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 index 0000000..2effbab --- /dev/null +++ b/sample.syslog.conf @@ -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 +# 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 index 0000000..300f5b3 --- /dev/null +++ b/set_perms.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 1994-1996,1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#ifdef HAVE_LOGIN_CAP_H +# include +#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 index 0000000..41d1476 --- /dev/null +++ b/sigaction.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2001 Todd C. Miller + * 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 +#include + +#include + +#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 index 0000000..9acc488 --- /dev/null +++ b/snprintf.c @@ -0,0 +1,775 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * 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 +#include + +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include + +#ifdef __STDC__ +# include +#else +# include +#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 + */ +#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 index 0000000..f0a4b3c --- /dev/null +++ b/strcasecmp.c @@ -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 + +#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 index 0000000..0a06e33 --- /dev/null +++ b/strerror.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1999, 2001 Todd C. Miller + * 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 +#include + +#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 index 0000000..7c6f532 --- /dev/null +++ b/sudo.c @@ -0,0 +1,1035 @@ +/* + * Copyright (c) 1993-1996,1998-2002 Todd C. Miller + * 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 +#include +#include +#include +#ifdef HAVE_SETRLIMIT +# include +# include +#endif +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) +# ifdef __hpux +# undef MAXINT +# include +# else +# include +# endif /* __hpux */ +# include +#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ +#ifdef HAVE_LOGIN_CAP_H +# include +# 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 | \n"); + exit(exit_val); +} diff --git a/sudo.cat b/sudo.cat new file mode 100644 index 0000000..062410d --- /dev/null +++ b/sudo.cat @@ -0,0 +1,462 @@ + + + +sudo(1m) MAINTENANCE COMMANDS sudo(1m) + + +NNNNAAAAMMMMEEEE + sudo - execute a command as another user + +SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + ssssuuuuddddoooo ----VVVV | ----hhhh | ----llll | ----LLLL | ----vvvv | ----kkkk | ----KKKK | ----ssss | [ ----HHHH ] [----PPPP ] + [----SSSS ] [ ----bbbb ] | [ ----pppp _p_r_o_m_p_t ] [ ----cccc _c_l_a_s_s|_- ] [ ----aaaa _a_u_t_h___t_y_p_e + ] [ ----uuuu _u_s_e_r_n_a_m_e|_#_u_i_d ] _c_o_m_m_a_n_d + +DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + ssssuuuuddddoooo allows a permitted user to execute a _c_o_m_m_a_n_d as the + superuser or another user, as specified in the _s_u_d_o_e_r_s + 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, ssssuuuuddddoooo 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 _s_u_d_o_e_r_s). + + ssssuuuuddddoooo determines who is an authorized user by consulting + the file _/_e_t_c_/_s_u_d_o_e_r_s. By giving ssssuuuuddddoooo the ----vvvv flag a user + can update the time stamp without running a _c_o_m_m_a_n_d_. The + password prompt itself will also time out if the user's + password is not entered within 5 minutes (unless overrid­ + den via _s_u_d_o_e_r_s). + + If a user who is not listed in the _s_u_d_o_e_r_s file tries to + run a command via ssssuuuuddddoooo, mail is sent to the proper author­ + ities, as defined at configure time or the _s_u_d_o_e_r_s file + (defaults to root). Note that the mail will not be sent + if an unauthorized user tries to run sudo with the ----llll or + ----vvvv flags. This allows users to determine for themselves + whether or not they are allowed to use ssssuuuuddddoooo. + + ssssuuuuddddoooo can log both successful and unsuccessful attempts (as + well as errors) to _s_y_s_l_o_g(3), a log file, or both. By + default ssssuuuuddddoooo will log via _s_y_s_l_o_g(3) but this is changeable + at configure time or via the _s_u_d_o_e_r_s file. + +OOOOPPPPTTTTIIIIOOOONNNNSSSS + ssssuuuuddddoooo accepts the following command line options: + + -V The ----VVVV (_v_e_r_s_i_o_n) option causes ssssuuuuddddoooo to print the ver­ + sion number and exit. If the invoking user is already + root the ----VVVV option will print out a list of the + defaults ssssuuuuddddoooo was compiled with as well as the + machine's local network addresses. + + -l The ----llll (_l_i_s_t) 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 ----LLLL (_l_i_s_t defaults) option will list out the param­ + eters that may be set in a _D_e_f_a_u_l_t_s line along with a + short description for each. This option is useful in + conjunction with _g_r_e_p(1). + + -h The ----hhhh (_h_e_l_p) option causes ssssuuuuddddoooo to print a usage mes­ + sage and exit. + + -v If given the ----vvvv (_v_a_l_i_d_a_t_e) option, ssssuuuuddddoooo will update + the user's timestamp, prompting for the user's pass­ + word if necessary. This extends the ssssuuuuddddoooo timeout for + another 5 minutes (or whatever the timeout is set to + in _s_u_d_o_e_r_s) but does not run a command. + + -k The ----kkkk (_k_i_l_l) option to ssssuuuuddddoooo invalidates the user's + timestamp by setting the time on it to the epoch. The + next time ssssuuuuddddoooo is run a password will be required. + This option does not require a password and was added + to allow a user to revoke ssssuuuuddddoooo permissions from a + .logout file. + + -K The ----KKKK (sure _k_i_l_l) option to ssssuuuuddddoooo removes the user's + timestamp entirely. Likewise, this option does not + require a password. + + -b The ----bbbb (_b_a_c_k_g_r_o_u_n_d) option tells ssssuuuuddddoooo to run the given + command in the background. Note that if you use the + ----bbbb option you cannot use shell job control to manipu­ + late the process. + + -p The ----pppp (_p_r_o_m_p_t) 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 ----cccc (_c_l_a_s_s) option causes ssssuuuuddddoooo to run the specified + command with resources limited by the specified login + class. The _c_l_a_s_s argument can be either a class name + as defined in /etc/login.conf, or a single '-' charac­ + ter. Specifying a _c_l_a_s_s 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 _c_l_a_s_s argument specifies an existing user class, + the command must be run as root, or the ssssuuuuddddoooo command + must be run from a shell that is already root. This + option is only available on systems with BSD login + classes where ssssuuuuddddoooo has been configured with the + --with-logincap option. + + -a The ----aaaa (_a_u_t_h_e_n_t_i_c_a_t_i_o_n _t_y_p_e) option causes ssssuuuuddddoooo 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 ssssuuuuddddoooo has + been configured with the --with-bsdauth option. + + -u The ----uuuu (_u_s_e_r) option causes ssssuuuuddddoooo to run the specified + command as a user other than _r_o_o_t. To specify a _u_i_d + instead of a _u_s_e_r_n_a_m_e, use _#_u_i_d. + + -s The ----ssss (_s_h_e_l_l) option runs the shell specified by the + _S_H_E_L_L environment variable if it is set or the shell + as specified in _p_a_s_s_w_d(4). + + -H The ----HHHH (_H_O_M_E) option sets the HOME environment vari­ + able to the homedir of the target user (root by + default) as specified in _p_a_s_s_w_d(4). By default, ssssuuuuddddoooo + does not modify HOME. + + -P The ----PPPP (_p_r_e_s_e_r_v_e _g_r_o_u_p _v_e_c_t_o_r) option causes ssssuuuuddddoooo to + preserve the user's group vector unaltered. By + default, ssssuuuuddddoooo 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 ----SSSS (_s_t_d_i_n) option causes ssssuuuuddddoooo to read the password + from standard input instead of the terminal device. + + -- The -------- flag indicates that ssssuuuuddddoooo should stop processing + command line arguments. It is most useful in conjunc­ + tion with the ----ssss flag. + +RRRREEEETTTTUUUURRRRNNNN VVVVAAAALLLLUUUUEEEESSSS + Upon successful execution of a program, the return value + from ssssuuuuddddoooo will simply be the return value of the program + that was executed. + + Otherwise, ssssuuuuddddoooo quits with an exit value of 1 if there is + a configuration/permission problem or if ssssuuuuddddoooo cannot exe­ + cute the given command. In the latter case the error + string is printed to stderr. If ssssuuuuddddoooo cannot _s_t_a_t(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 _s_t_a_t(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. + +SSSSEEEECCCCUUUURRRRIIIITTTTYYYY NNNNOOOOTTTTEEEESSSS + ssssuuuuddddoooo 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 ssssuuuuddddoooo 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. + ssssuuuuddddoooo 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 ssssuuuuddddoooo 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 ssssuuuuddddoooo clears + is contained in the output of sudo -V when run as root. + + To prevent command spoofing, ssssuuuuddddoooo checks "." and "" (both + denoting current directory) last when searching for a com­ + mand in the user's PATH (if one or both are in the PATH). + Note, however, that the actual PATH environment variable + is _n_o_t modified and is passed unchanged to the program + that ssssuuuuddddoooo executes. + + 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 ssssuuuuddddoooo stati­ + cally. + + ssssuuuuddddoooo will check the ownership of its timestamp directory + (_/_v_a_r_/_r_u_n_/_s_u_d_o 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 _c_h_o_w_n(2), if the timestamp directory is located + in a directory writable by anyone (e.g.: _/_t_m_p), it is pos­ + sible for a user to create the timestamp directory before + ssssuuuuddddoooo is run. However, because ssssuuuuddddoooo checks the ownership + and mode of the directory and its contents, the only dam­ + age that can be done is to "hide" files by putting them in + 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 + (_/_v_a_r_/_a_d_m_/_s_u_d_o for instance) or create _/_v_a_r_/_r_u_n_/_s_u_d_o with + the appropriate owner (root) and permissions (0700) in the + system startup files. + + ssssuuuuddddoooo 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 ssssuuuuddddoooo 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 _n_o_t + be logged, nor will ssssuuuuddddoooo'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 ssssuuuuddddoooo to + verify that the command does not inadvertantly give the + user an effective root shell. + +EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS + Note: the following examples assume suitable _s_u_d_o_e_r_s(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 _i_n_d_e_x_._h_t_m_l file as user www: + + % sudo -u www vi ~www/htdocs/index.html + + To shutdown a machine: + + % sudo shutdown -r +15 "quick reboot" + + To make a usage listing of the directories in the /home + 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" + + +EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT + ssssuuuuddddoooo 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 + + +FFFFIIIILLLLEEEESSSS + /etc/sudoers List of who can run what + /var/run/sudo Directory containing timestamps + + +AAAAUUUUTTTTHHHHOOOORRRRSSSS + Many people have worked on ssssuuuuddddoooo over the years; this ver­ + sion consists of code written primarily by: + + Todd Miller + Chris Jepeway + + See the HISTORY file in the ssssuuuuddddoooo distribution or visit + http://www.sudo.ws/sudo/history.html for a short history + of ssssuuuuddddoooo. + +BBBBUUUUGGGGSSSS + If you feel you have found a bug in sudo, please submit a + bug report at http://www.sudo.ws/sudo/bugs/ + +DDDDIIIISSSSCCCCLLLLAAAAIIIIMMMMEEEERRRR + SSSSuuuuddddoooo is provided ``AS IS'' and any express or implied war­ + ranties, including, but not limited to, the implied war­ + ranties of merchantability and fitness for a particular + purpose are disclaimed. See the LICENSE file distributed + with ssssuuuuddddoooo for complete details. + +CCCCAAAAVVVVEEEEAAAATTTTSSSS + 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 ssssuuuuddddoooo 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). + +SSSSEEEEEEEE AAAALLLLSSSSOOOO + _s_t_a_t(2), _l_o_g_i_n___c_a_p(3), _s_u_d_o_e_r_s(4), _p_a_s_s_w_d(5), _v_i_s_u_d_o(1m), + _g_r_e_p(1), _s_u(1). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +April 25, 2002 1.6.6 7 + + diff --git a/sudo.h b/sudo.h new file mode 100644 index 0000000..44a1ede --- /dev/null +++ b/sudo.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 1993-1996,1998-2001 Todd C. Miller + * 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 +#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 index 0000000..838af38 --- /dev/null +++ b/sudo.man.in @@ -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 index 0000000..2a05698 --- /dev/null +++ b/sudo.pod @@ -0,0 +1,376 @@ +=cut +Copyright (c) 1994-1996,1998-2002 Todd C. Miller +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 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 ] +[ B<-c> I|I<-> ] [ B<-a> I ] +[ B<-u> I|I<#uid> ] I + +=head1 DESCRIPTION + +B allows a permitted user to execute a I as the +superuser or another user, as specified in the I 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 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). + +B determines who is an authorized user by consulting the file +F<@sysconfdir@/sudoers>. By giving B the B<-v> flag a user +can update the time stamp without running a I 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). + +If a user who is not listed in the I file tries to run a +command via B, mail is sent to the proper authorities, as +defined at configure time or the I 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. + +B can log both successful and unsuccessful attempts (as well +as errors) to syslog(3), a log file, or both. By default B +will log via syslog(3) but this is changeable at configure time +or via the I file. + +=head1 OPTIONS + +B accepts the following command line options: + +=over 4 + +=item -V + +The B<-V> (I) option causes B 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 +was compiled with as well as the machine's local network addresses. + +=item -l + +The B<-l> (I) option will list out the allowed (and +forbidden) commands for the user on the current host. + +=item -L + +The B<-L> (I defaults) option will list out the parameters +that may be set in a I line along with a short description +for each. This option is useful in conjunction with grep(1). + +=item -h + +The B<-h> (I) option causes B to print a usage message and exit. + +=item -v + +If given the B<-v> (I) option, B will update the +user's timestamp, prompting for the user's password if necessary. +This extends the B timeout for another C<@timeout@> minutes +(or whatever the timeout is set to in I) but does not run +a command. + +=item -k + +The B<-k> (I) option to B invalidates the user's timestamp +by setting the time on it to the epoch. The next time B is +run a password will be required. This option does not require a password +and was added to allow a user to revoke B permissions from a .logout +file. + +=item -K + +The B<-K> (sure I) option to B removes the user's timestamp +entirely. Likewise, this option does not require a password. + +=item -b + +The B<-b> (I) option tells B 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) 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) option causes B to run the specified command +with resources limited by the specified login class. The I +argument can be either a class name as defined in /etc/login.conf, +or a single '-' character. Specifying a I 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 +argument specifies an existing user class, the command must be run +as root, or the B command must be run from a shell that is already +root. This option is only available on systems with BSD login classes +where B has been configured with the --with-logincap option. + +=item -a + +The B<-a> (I) option causes B 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 has been configured +with the --with-bsdauth option. + +=item -u + +The B<-u> (I) option causes B to run the specified command +as a user other than I. To specify a I instead of a +I, use I<#uid>. + +=item -s + +The B<-s> (I) option runs the shell specified by the I +environment variable if it is set or the shell as specified +in passwd(5). + +=item -H + +The B<-H> (I) option sets the C environment variable +to the homedir of the target user (root by default) as specified +in passwd(5). By default, B does not modify C. + +=item -P + +The B<-P> (I) option causes B to preserve +the user's group vector unaltered. By default, B 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) option causes B to read the password from +standard input instead of the terminal device. + +=item -- + +The B<--> flag indicates that B 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 +will simply be the return value of the program that was executed. + +Otherwise, B quits with an exit value of 1 if there is a +configuration/permission problem or if B cannot execute the +given command. In the latter case the error string is printed to +stderr. If B cannot stat(2) one or more entries in the user's +C 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 is on a machine that is currently +unreachable. + +=head1 SECURITY NOTES + +B 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 runs. To combat this the +C, C<_RLD_*>, C (HP-UX only), and C (AIX +only) environment variables are removed from the environment passed +on to all commands executed. B will also remove the C, +C, C, C, C, C, +C, C, C, C, +C, C, C, C and +C variables as they too can pose a threat. If the +C variable is set and is a pathname, it too is ignored. +Additionally, if the C or C variables contain the +C or C<%> characters, they are ignored. If B has been +compiled with SecurID support, the C, C and +C variables are cleared as well. The list of environment +variables that B clears is contained in the output of +C when run as root. + +To prevent command spoofing, B 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 environment variable is I modified and is passed +unchanged to the program that B 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 statically. + +B 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), +it is possible for a user to create the timestamp directory before +B is run. However, because B 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 for instance) or create F<@timedir@> +with the appropriate owner (root) and permissions (0700) in the +system startup files. + +B will not honor timestamps set far in the future. +Timestamps with a date greater than current_time + 2 * C +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 will only log the command it explicitly +runs. If a user runs a command such as C or C, +subsequent commands run from that shell will I be logged, nor +will B'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 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 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 and file redirection work. + + % sudo sh -c "cd /home ; du -s * | sort -rn > USAGE" + +=head1 ENVIRONMENT + +B 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 over the years; this +version consists of code written primarily by: + + Todd Miller + Chris Jepeway + +See the HISTORY file in the B distribution or visit +http://www.sudo.ws/sudo/history.html for a short history +of B. + +=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 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 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 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 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 index 0000000..db81c13 --- /dev/null +++ b/sudo.tab.c @@ -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 +#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 + * 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 +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +# include +#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */ +#ifdef HAVE_LSEARCH +# include +#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 index 0000000..71b1255 --- /dev/null +++ b/sudo.tab.h @@ -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 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 index 0000000..a78c030 --- /dev/null +++ b/sudoers.cat @@ -0,0 +1,1188 @@ + + + +sudoers(4) MAINTENANCE COMMANDS sudoers(4) + + +NNNNAAAAMMMMEEEE + sudoers - list of which users may execute what + +DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + The _s_u_d_o_e_r_s file is composed of two types of entries: + aliases (basically variables) and user specifications + (which specify who may run what). The grammar of _s_u_d_o_e_r_s + 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. + + QQQQuuuuiiiicccckkkk gggguuuuiiiiddddeeee ttttoooo EEEEBBBBNNNNFFFF + + EBNF is a concise and exact way of describing the grammar + of a language. Each EBNF definition is made up of _p_r_o_d_u_c_­ + _t_i_o_n _r_u_l_e_s. E.g., + + symbol ::= definition | alternate1 | alternate2 ... + + Each _p_r_o_d_u_c_t_i_o_n _r_u_l_e 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). + + AAAAlllliiiiaaaasssseeeessss + + 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 _a_l_i_a_s definition is of the form + + Alias_Type NAME = item1, item2, ... + + where _A_l_i_a_s___T_y_p_e 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 mmmmuuuusssstttt 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 _a_l_i_a_s 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 _i_n_t_e_r_f_a_c_e(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 _f_q_d_n 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 wwwwiiiitttthhhhoooouuuutttt + 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) + + + DDDDeeeeffffaaaauuuullllttttssss + + 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 ffffllllaaaaggggssss, iiiinnnntttteeeeggggeeeerrrr values, ssssttttrrrriiiinnnnggggssss, or + lllliiiissssttttssss. 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 _s_u_d_o_e_r_s 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. + + FFFFllllaaaaggggssss: + + long_otp_prompt + When validating with a One Time Password + scheme (SSSS////KKKKeeeeyyyy or OOOOPPPPIIIIEEEE), 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 _o_f_f by default. + + ignore_dot If set, ssssuuuuddddoooo will ignore '.' or '' (current + dir) in the PATH environment variable; the + PATH itself is not modified. This flag is _o_f_f + by default. + + + + + +April 25, 2002 1.6.6 4 + + + + + +sudoers(4) MAINTENANCE COMMANDS sudoers(4) + + + mail_always Send mail to the _m_a_i_l_t_o user every time a + users runs ssssuuuuddddoooo. This flag is _o_f_f by default. + + mail_badpass + Send mail to the _m_a_i_l_t_o user if the user run­ + ning sudo does not enter the correct password. + This flag is _o_f_f by default. + + mail_no_user + If set, mail will be sent to the _m_a_i_l_t_o user + if the invoking user is not in the _s_u_d_o_e_r_s + file. This flag is _o_n by default. + + mail_no_host + If set, mail will be sent to the _m_a_i_l_t_o user + if the invoking user exists in the _s_u_d_o_e_r_s + file, but is not allowed to run commands on + the current host. This flag is _o_f_f by + default. + + mail_no_perms + If set, mail will be sent to the _m_a_i_l_t_o user + if the invoking user allowed to use ssssuuuuddddoooo but + the command they are trying is not listed in + their _s_u_d_o_e_r_s file entry. This flag is _o_f_f by + default. + + tty_tickets If set, users must authenticate on a per-tty + basis. Normally, ssssuuuuddddoooo uses a directory in the + ticket dir with the same name as the user run­ + ning it. With this flag enabled, ssssuuuuddddoooo will + use a file named for the tty the user is + logged in on in that directory. This flag is + _o_f_f by default. + + lecture If set, a user will receive a short lecture + the first time he/she runs ssssuuuuddddoooo. This flag is + _o_n 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 _o_n by default. + + root_sudo If set, root is allowed to run ssssuuuuddddoooo too. Dis­ + abling this prevents users from "chaining" + ssssuuuuddddoooo commands to get a root shell by doing + something like "sudo sudo /bin/sh". This flag + is _o_n by default. + + log_host If set, the hostname will be logged in the + (non-syslog) ssssuuuuddddoooo log file. This flag is _o_f_f + + + +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) ssssuuuuddddoooo log file. This flag is + _o_f_f by default. + + shell_noargs + If set and ssssuuuuddddoooo is invoked with no arguments + it acts as if the ----ssss 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 _o_f_f by default. + + set_home If set and ssssuuuuddddoooo is invoked with the ----ssss flag + the HOME environment variable will be set to + the home directory of the target user (which + is root unless the ----uuuu option is used). This + effectively makes the ----ssss flag imply ----HHHH. This + flag is _o_f_f by default. + + always_set_home + If set, ssssuuuuddddoooo will set the HOME environment + variable to the home directory of the target + user (which is root unless the ----uuuu option is + used). This effectively means that the ----HHHH + flag is always implied. This flag is _o_f_f by + default. + + path_info Normally, ssssuuuuddddoooo 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, ssssuuuuddddoooo will tell the user + that they are not allowed to run it, which can + be confusing. This flag is _o_f_f by default. + + preserve_groups + By default ssssuuuuddddoooo will initialize the group vec­ + tor to the list of groups the target user is + in. When _p_r_e_s_e_r_v_e___g_r_o_u_p_s 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 _o_f_f by default. + + fqdn Set this flag if you want to put fully quali­ + fied hostnames in the _s_u_d_o_e_r_s 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 _f_q_d_n requires ssssuuuuddddoooo to make DNS + lookups which may make ssssuuuuddddoooo 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 _f_q_d_n. This flag is _o_f_f by default. + + insults If set, ssssuuuuddddoooo will insult users when they enter + an incorrect password. This flag is _o_f_f by + default. + + requiretty If set, ssssuuuuddddoooo will only run when the user is + logged in to a real tty. This will disallow + things like "rsh somehost sudo ls" since + _r_s_h(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 _o_f_f by default. + + env_editor If set, vvvviiiissssuuuuddddoooo 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. vvvviiiissssuuuuddddoooo 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, ssssuuuuddddoooo will prompt for the root password + instead of the password of the invoking user. + This flag is _o_f_f by default. + + runaspw If set, ssssuuuuddddoooo will prompt for the password of + the user defined by the _r_u_n_a_s___d_e_f_a_u_l_t option + (defaults to root) instead of the password of + the invoking user. This flag is _o_f_f by + default. + + targetpw If set, ssssuuuuddddoooo will prompt for the password of + the user specified by the ----uuuu flag (defaults to + root) instead of the password of the invoking + user. This flag is _o_f_f by default. + + + + +April 25, 2002 1.6.6 7 + + + + + +sudoers(4) MAINTENANCE COMMANDS sudoers(4) + + + set_logname Normally, ssssuuuuddddoooo will set the LOGNAME and USER + environment variables to the name of the tar­ + get user (usually root unless the ----uuuu 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 ssssuuuuddddoooo executes a command the + real and effective UIDs are set to the target + user (root by default). This option changes + that behavior such that the real UID is left + as the invoking user's UID. In other words, + this makes ssssuuuuddddoooo act as a setuid wrapper. This + can be useful on systems that disable some + potentially dangerous functionality when a + program is run setuid. Note, however, that + this means that sudo will run with the real + uid of the invoking user which may allow that + user to kill ssssuuuuddddoooo before it can log a failure, + depending on how your OS defines the interac­ + tion between signals and setuid processes. + + env_reset If set, ssssuuuuddddoooo 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 + _s_e_t___l_o_g_n_a_m_e option). If ssssuuuuddddoooo was compiled + with the SECURE_PATH option, its value will be + used for the PATH environment variable. Other + variables may be preserved with the _e_n_v___k_e_e_p + option. + + use_loginclass + If set, ssssuuuuddddoooo will apply the defaults specified + for the target user's login class if one + exists. Only available if ssssuuuuddddoooo is configured + with the --with-logincap option. This flag is + _o_f_f by default. + + IIIInnnntttteeeeggggeeeerrrrssss: + + passwd_tries + The number of tries a user gets to enter + his/her password before ssssuuuuddddoooo logs the failure + and exits. The default is 3. + + IIIInnnntttteeeeggggeeeerrrrssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt: + + + + +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 ssssuuuuddddoooo + 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 ssssuuuuddddoooo 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. + + SSSSttttrrrriiiinnnnggggssss: + + mailsub Subject of the mail sent to the _m_a_i_l_t_o 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 ssssuuuuddddoooo stores its times­ + tamp files. The default is _/_v_a_r_/_r_u_n_/_s_u_d_o. + + passprompt The default prompt to use when asking for a + password; can be overridden via the ----pppp 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 ----uuuu + 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 vvvviiiissssuuuuddddoooo. vvvviiiissssuuuuddddoooo 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. + + SSSSttttrrrriiiinnnnggggssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt: + + logfile Path to the ssssuuuuddddoooo 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 + ----tttt. + + 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 ssssuuuuddddoooo with the ----vvvv + flag. It has the following possible values: + + all All the user's _s_u_d_o_e_r_s entries for the + current host must have the NOPASSWD + flag set to avoid entering a password. + + any At least one of the user's _s_u_d_o_e_r_s + 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 ----vvvv flag. + + always The user must always enter a password + to use the ----vvvv flag. + + The default value is `all'. + + listpw This option controls when a password will be + required when a user runs ssssuuuuddddoooo with the ----llll. + It has the following possible values: + + all All the user's _s_u_d_o_e_r_s entries for the + current host must have the NOPASSWD + flag set to avoid entering a password. + + any At least one of the user's _s_u_d_o_e_r_s + 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 ----llll flag. + + always The user must always enter a password + to use the ----llll flag. + + The default value is `any'. + + LLLLiiiissssttttssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt: + + 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 + ssssuuuuddddoooo is run by root with the _-_V 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 ssssuuuuddddoooo is run + + + +April 25, 2002 1.6.6 11 + + + + + +sudoers(4) MAINTENANCE COMMANDS sudoers(4) + + + by root with the _-_V option. + + env_keep Environment variables to be preserved in the + user's environment when the _e_n_v___r_e_s_e_t option + is in effect. This allows fine-grained con­ + trol over the environment ssssuuuuddddoooo-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 _s_y_s_l_o_g(3), ssssuuuuddddoooo accepts the following + values for the syslog facility (the value of the ssssyyyysssslllloooogggg + Parameter): aaaauuuutttthhhhpppprrrriiiivvvv (if your OS supports it), aaaauuuutttthhhh, ddddaaaaeeee­­­­ + mmmmoooonnnn, uuuusssseeeerrrr, llllooooccccaaaallll0000, llllooooccccaaaallll1111, llllooooccccaaaallll2222, llllooooccccaaaallll3333, llllooooccccaaaallll4444, llllooooccccaaaallll5555, + llllooooccccaaaallll6666, and llllooooccccaaaallll7777. The following syslog priorities are + supported: aaaalllleeeerrrrtttt, ccccrrrriiiitttt, ddddeeeebbbbuuuugggg, eeeemmmmeeeerrrrgggg, eeeerrrrrrrr, iiiinnnnffffoooo, nnnnoooottttiiiicccceeee, + and wwwwaaaarrrrnnnniiiinnnngggg. + + UUUUsssseeeerrrr SSSSppppeeeecccciiiiffffiiiiccccaaaattttiiiioooonnnn + + 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 uuuusssseeeerrrr ssssppppeeeecccciiiiffffiiiiccccaaaattttiiiioooonnnn determines which commands a user may + run (and as what user) on specified hosts. By default, + commands are run as rrrrooooooootttt, but this can be changed on a + per-command basis. + + Let's break that down into its constituent parts: + + RRRRuuuunnnnaaaassss____SSSSppppeeeecccc + + 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 rrrrooooooootttt 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 ddddggggbbbb may run _/_b_i_n_/_l_s, _/_b_i_n_/_k_i_l_l, and _/_u_s_r_/_b_i_n_/_l_p_r_m + -- but only as ooooppppeeeerrrraaaattttoooorrrr. 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 ddddggggbbbb is now allowed to run _/_b_i_n_/_l_s as ooooppppeeeerrrraaaattttoooorrrr, + but _/_b_i_n_/_k_i_l_l and _/_u_s_r_/_b_i_n_/_l_p_r_m as rrrrooooooootttt. + + NNNNOOOOPPPPAAAASSSSSSSSWWWWDDDD aaaannnndddd PPPPAAAASSSSSSSSWWWWDDDD + + By default, ssssuuuuddddoooo 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 rrrraaaayyyy to run _/_b_i_n_/_k_i_l_l, _/_b_i_n_/_l_s, and + _/_u_s_r_/_b_i_n_/_l_p_r_m as root on the machine rushmore as rrrrooooooootttt + without authenticating himself. If we only want rrrraaaayyyy to be + able to run _/_b_i_n_/_k_i_l_l 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. + + WWWWiiiillllddddccccaaaarrrrddddssss ((((aaaakkkkaaaa mmmmeeeettttaaaa cccchhhhaaaarrrraaaacccctttteeeerrrrssss)))):::: + + ssssuuuuddddoooo allows shell-style _w_i_l_d_c_a_r_d_s to be used in pathnames + as well as command line arguments in the _s_u_d_o_e_r_s file. + Wildcard matching is done via the PPPPOOOOSSSSIIIIXXXX fnmatch(3) rou­ + tine. Note that these are _n_o_t 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 nnnnooootttt 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 nnnnooootttt be matched by + wildcards used in the pathname. When matching the command + line arguments, however, as slash ddddooooeeeessss get matched by + wildcards. This is to make a path like: + + /usr/bin/* + + match /usr/bin/who but not /usr/bin/X11/xterm. + + EEEExxxxcccceeeeppppttttiiiioooonnnnssss ttttoooo wwwwiiiillllddddccccaaaarrrrdddd rrrruuuulllleeeessss:::: + + The following exceptions apply to the above rules: + + """" If the empty string "" is the only command line + argument in the _s_u_d_o_e_r_s entry it means that com­ + mand is not allowed to be run with aaaannnnyyyy arguments. + + OOOOtttthhhheeeerrrr ssssppppeeeecccciiiiaaaallll cccchhhhaaaarrrraaaacccctttteeeerrrrssss aaaannnndddd rrrreeeesssseeeerrrrvvvveeeedddd wwwwoooorrrrddddssss:::: + + 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 AAAALLLLLLLL is a built in _a_l_i_a_s 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 + _a_l_i_a_s called AAAALLLLLLLL as the built in alias will be used in + preference to your own. Please note that using AAAALLLLLLLL can be + dangerous since in a command context, it allows the user + to run aaaannnnyyyy command on the system. + + An exclamation point ('!') can be used as a logical _n_o_t + operator both in an _a_l_i_a_s 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 _U_s_e_r _S_p_e_c_i_f_i_c_a_t_i_o_n ('=', ':', + '(', ')') 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): '@', '!', '=', ':', ',', '(', ')', '\'. + +EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS + Below are example _s_u_d_o_e_r_s entries. Admittedly, some of + these are a bit contrived. First, we define our _a_l_i_a_s_e_s: + + # 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 ssssuuuuddddoooo to log via _s_y_s_l_o_g(3) using the _a_u_t_h facility + in all cases. We don't want to subject the full time + staff to the ssssuuuuddddoooo lecture, and user mmmmiiiilllllllleeeerrrrtttt need not give + a password. In addition, on the machines in the _S_E_R_V_E_R_S + 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 _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually deter­ + mines who may run what. + + root ALL = (ALL) ALL + %wheel ALL = (ALL) ALL + + We let rrrrooooooootttt and any user in group wwwwhhhheeeeeeeellll run any command on + any host as any user. + + FULLTIMERS ALL = NOPASSWD: ALL + + Full time sysadmins (mmmmiiiilllllllleeeerrrrtttt, mmmmiiiikkkkeeeeffff, and ddddoooowwwwddddyyyy) may run + any command on any host without authenticating themselves. + + PARTTIMERS ALL = ALL + + Part time sysadmins (bbbboooossssttttlllleeeeyyyy, jjjjwwwwffffooooxxxx, and ccccrrrraaaawwwwllll) 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 jjjjaaaacccckkkk may run any command on the machines in the + _C_S_N_E_T_S alias (the networks 128.138.243.0, 128.138.204.0, + and 128.138.242.0). Of those networks, only 128.138.204.0 + has an explicit netmask (in CIDR notation) indicating it + is a class C network. For the other networks in _C_S_N_E_T_S, + the local machine's netmask will be used during matching. + + lisa CUNETS = ALL + + The user lllliiiissssaaaa may run any command on any host in the + _C_U_N_E_T_S alias (the class B network 128.138.0.0). + + operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\ + /usr/oper/bin/ + + The ooooppppeeeerrrraaaattttoooorrrr 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 _/_u_s_r_/_o_p_e_r_/_b_i_n_/. + + joe ALL = /usr/bin/su operator + + The user jjjjooooeeee may only _s_u(1) to operator. + + pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root + + The user ppppeeeetttteeee is allowed to change anyone's password + except for root on the _H_P_P_A machines. Note that this + assumes _p_a_s_s_w_d(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 bbbboooobbbb may run anything on the _S_P_A_R_C and _S_G_I + machines as any user listed in the _O_P Runas_Alias (rrrrooooooootttt + and ooooppppeeeerrrraaaattttoooorrrr). + + jim +biglab = ALL + + The user jjjjiiiimmmm may run any command on machines in the _b_i_g_l_a_b + netgroup. SSSSuuuuddddoooo knows that "biglab" is a netgroup due to + the '+' prefix. + + +secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser + + Users in the sssseeeeccccrrrreeeettttaaaarrrriiiieeeessss 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 ffffrrrreeeedddd can run commands as any user in the _D_B + Runas_Alias (oooorrrraaaacccclllleeee or ssssyyyybbbbaaaasssseeee) without giving a password. + + john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root* + + On the _A_L_P_H_A machines, user jjjjoooohhhhnnnn may su to anyone except + root but he is not allowed to give _s_u(1) any flags. + + jen ALL, !SERVERS = ALL + + The user jjjjeeeennnn may run any command on any machine except for + those in the _S_E_R_V_E_R_S Host_Alias (master, mail, www and + ns). + + jill SERVERS = /usr/bin/, !SU, !SHELLS + + For any machine in the _S_E_R_V_E_R_S Host_Alias, jjjjiiiillllllll may run + any commands in the directory /usr/bin/ except for those + commands belonging to the _S_U and _S_H_E_L_L_S Cmnd_Aliases. + + steve CSNETS = (operator) /usr/local/op_commands/ + + The user sssstttteeeevvvveeee may run any command in the directory + /usr/local/op_commands/ but only as user operator. + + matt valkyrie = KILL + + On his personal workstation, valkyrie, mmmmaaaatttttttt 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 _W_E_B_M_A_S_T_E_R_S User_Alias + (will, wendy, and wim), may run any command as user www + (which owns the web pages) or simply _s_u(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. + +SSSSEEEECCCCUUUURRRRIIIITTTTYYYY NNNNOOOOTTTTEEEESSSS + 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 bbbbiiiillllllll from running the commands + listed in _S_U or _S_H_E_L_L_S 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). + +CCCCAAAAVVVVEEEEAAAATTTTSSSS + The _s_u_d_o_e_r_s file should aaaallllwwwwaaaayyyyssss be edited by the vvvviiiissssuuuuddddoooo + command which locks the file and does grammatical check­ + ing. It is imperative that _s_u_d_o_e_r_s be free of syntax + errors since ssssuuuuddddoooo will not run with a syntactically incor­ + rect _s_u_d_o_e_r_s 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 _f_q_d_n option in _s_u_d_o_e_r_s. + +FFFFIIIILLLLEEEESSSS + /etc/sudoers List of who can run what + /etc/group Local groups file + /etc/netgroup List of network groups + + +SSSSEEEEEEEE AAAALLLLSSSSOOOO + _r_s_h(1), _s_u_d_o(1m), _v_i_s_u_d_o(8), _s_u(1), _f_n_m_a_t_c_h(3). + + + + + + + + + + + + +April 25, 2002 1.6.6 18 + + diff --git a/sudoers.man.in b/sudoers.man.in new file mode 100644 index 0000000..e75ab0e --- /dev/null +++ b/sudoers.man.in @@ -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 index 0000000..80fd724 --- /dev/null +++ b/sudoers.pod @@ -0,0 +1,1048 @@ +=cut +Copyright (c) 1994-1996,1998-2001 Todd C. Miller +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 file is composed of two types of entries: +aliases (basically variables) and user specifications +(which specify who may run what). The grammar of I +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. E.g., + + symbol ::= definition | alternate1 | alternate2 ... + +Each I 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, C, +C and C. + + 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 definition is of the form + + Alias_Type NAME = item1, item2, ... + +where I is one of C, C, C, +or C. A C is a string of uppercase letters, numbers, +and the underscore characters ('_'). A C B 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 member follow. + + User_List ::= User | + User ',' User_List + + User ::= '!'* username | + '!'* '%'group | + '!'* '+'netgroup | + '!'* User_Alias + +A C 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 is similar to a C except that it can +also contain uids (prefixed with '#') and instead of Ces +it can contain Ces. + + Host_List ::= Host | + Host ',' Host_List + + Host ::= '!'* hostname | + '!'* ip_addr | + '!'* network(/netmask)? | + '!'* '+'netgroup | + '!'* Host_Alias + +A C 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 command on your machine returns the fully +qualified hostname, you'll need to use the I option for wildcards +to be useful. + + Cmnd_List ::= Cmnd | + Cmnd ',' Cmnd_List + + commandname ::= filename | + filename args | + filename '""' + + Cmnd ::= '!'* commandname | + '!'* directory | + '!'* Cmnd_Alias + +A C 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 command line arguments. A directory is a +fully qualified pathname ending in a '/'. When you specify a directory +in a C, the user will be able to run any file within that directory +(but not in any subdirectories therein). + +If a C has associated command line arguments, then the arguments +in the C 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 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, B values, B, or B. +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 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: + +=over 12 + +=item long_otp_prompt + +When validating with a One Time Password scheme (B or B), +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 will ignore '.' or '' (current dir) in the C +environment variable; the C itself is not modified. This +flag is I<@ignore_dot@> by default. + +=item mail_always + +Send mail to the I user every time a users runs B. +This flag is I by default. + +=item mail_badpass + +Send mail to the I user if the user running sudo does not +enter the correct password. This flag is I by default. + +=item mail_no_user + +If set, mail will be sent to the I user if the invoking +user is not in the I file. This flag is I<@mail_no_user@> +by default. + +=item mail_no_host + +If set, mail will be sent to the I user if the invoking +user exists in the I 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 user if the invoking +user allowed to use B but the command they are trying is not +listed in their I 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 uses a directory in the ticket dir with the same name as +the user running it. With this flag enabled, B 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. 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 and C tags. +This flag is I by default. + +=item root_sudo + +If set, root is allowed to run B too. Disabling this prevents users +from "chaining" B commands to get a root shell by doing something +like C<"sudo sudo /bin/sh">. +This flag is I by default. + +=item log_host + +If set, the hostname will be logged in the (non-syslog) B log file. +This flag is I by default. + +=item log_year + +If set, the four-digit year will be logged in the (non-syslog) B log file. +This flag is I by default. + +=item shell_noargs + +If set and B 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 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 by default. + +=item set_home + +If set and B is invoked with the B<-s> flag the C +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 by default. + +=item always_set_home + +If set, B will set the C 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 by default. + +=item path_info + +Normally, B will tell the user when a command could not be +found in their C 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, B will tell the user that they are not +allowed to run it, which can be confusing. This flag is I by +default. + +=item preserve_groups + +By default B will initialize the group vector to the list of +groups the target user is in. When I 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 by default. + +=item fqdn + +Set this flag if you want to put fully qualified hostnames in the +I 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 requires B to make DNS lookups +which may make B 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 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 +command) is already fully qualified you shouldn't need to set +I. This flag is I<@fqdn@> by default. + +=item insults + +If set, B will insult users when they enter an incorrect +password. This flag is I<@insults@> by default. + +=item requiretty + +If set, B 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 by default. + +=item env_editor + +If set, B 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 +variable. B will then only use the EDITOR or VISUAL if +they match a value specified in C. This flag is C<@env_editor@> by +default. + +=item rootpw + +If set, B will prompt for the root password instead of the password +of the invoking user. This flag is I by default. + +=item runaspw + +If set, B will prompt for the password of the user defined by the +I option (defaults to C) instead of the password +of the invoking user. This flag is I by default. + +=item targetpw + +If set, B will prompt for the password of the user specified by +the B<-u> flag (defaults to C) instead of the password of the +invoking user. This flag is I by default. + +=item set_logname + +Normally, B will set the C and C 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 to determine the real identity of the user, it may be desirable +to change this behavior. This can be done by negating the set_logname option. + +=item stay_setuid + +Normally, when B executes a command the real and effective +UIDs are set to the target user (root by default). This option +changes that behavior such that the real UID is left as the invoking +user's UID. In other words, this makes B act as a setuid +wrapper. This can be useful on systems that disable some potentially +dangerous functionality when a program is run setuid. 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 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 will reset the environment to only contain the +following variables: C, C, C, C, C, +and C (in addition to the C variables). +Of these, only C is copied unaltered from the old environment. +The other variables are set to default values (possibly modified +by the value of the I option). If B was compiled +with the C option, its value will be used for the C +environment variable. +Other variables may be preserved with the I option. + +=item use_loginclass + +If set, B will apply the defaults specified for the target user's +login class if one exists. Only available if B is configured with +the --with-logincap option. This flag is I by default. + +=back + +B: + +=over 12 + +=item passwd_tries + +The number of tries a user gets to enter his/her password before +B logs the failure and exits. The default is C<@passwd_tries@>. + +=back + +B: + +=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 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 and C respectively. + +=item passwd_timeout + +Number of minutes before the B 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: + +=over 12 + +=item mailsub + +Subject of the mail sent to the I 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 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 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. B 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: + +=over 12 + +=item logfile + +Path to the B 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 with the B<-v> flag. It has the following possible values: + +=over 8 + +=item all + +All the user's I entries for the current host must have +the C flag set to avoid entering a password. + +=item any + +At least one of the user's I entries for the current host +must have the C 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 with the B<-l>. It has the following possible values: + +=over 8 + +=item all + +All the user's I entries for the current host must have +the C flag set to avoid entering a password. + +=item any + +At least one of the user's I entries for the current host +must have the C 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: + +=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 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 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 option is in effect. This allows fine-grained +control over the environment B-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 accepts the following values for the syslog +facility (the value of the B Parameter): B (if your OS +supports it), B, B, B, B, B, B, +B, B, B, B, and B. The following +syslog priorities are supported: B, B, B, B, +B, B, B, and B. + +=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 determines which commands a user may run +(and as what user) on specified hosts. By default, commands are +run as B, but this can be changed on a per-command basis. + +Let's break that down into its constituent parts: + +=head2 Runas_Spec + +A C is simply a C (as defined above) +enclosed in a set of parentheses. If you do not specify a +C in the user specification, a default C +of B will be used. A C 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 may run F, F, and +F -- but only as B. E.g., + + sudo -u operator /bin/ls. + +It is also possible to override a C 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 is now allowed to run F as B, +but F and F as B. + +=head2 NOPASSWD and PASSWD + +By default, B requires that a user authenticate him or herself +before running a command. This behavior can be modified via the +C tag. Like a C, the C tag sets +a default for the commands that follow it in the C. +Conversely, the C tag can be used to reverse things. +For example: + + ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm + +would allow the user B to run F, F, and +F as root on the machine rushmore as B without +authenticating himself. If we only want B to be able to +run F without a password the entry would be: + + ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm + +Note, however, that the C tag has no effect on users who are +in the group specified by the exempt_group option. + +By default, if the C tag is applied to any of the entries +for a user on the current host, he or she will be able to run +C without a password. Additionally, a user may only run +C without a password if the C 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 allows shell-style I to be used in pathnames +as well as command line arguments in the I file. Wildcard +matching is done via the B C routine. Note that +these are I 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 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 be matched by +wildcards used in the pathname. When matching the command +line arguments, however, as slash B get matched by +wildcards. This is to make a path like: + + /usr/bin/* + +match C but not C. + +=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 entry it means that command is not allowed to be run +with B 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 is a built in I that always causes +a match to succeed. It can be used wherever one might otherwise +use a C, C, C, or C. +You should not try to define your own I called B as the +built in alias will be used in preference to your own. Please note +that using B can be dangerous since in a command context, it +allows the user to run B command on the system. + +An exclamation point ('!') can be used as a logical I operator +both in an I and in front of a C. This allows one to +exclude certain values. Note, however, that using a C in +conjunction with the built in C 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 ('=', ':', '(', ')') 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 entries. Admittedly, some of +these are a bit contrived. First, we define our I: + + # 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 to log via syslog(3) using the I facility in all cases. +We don't want to subject the full time staff to the B lecture, +and user B need not give a password. In addition, on the +machines in the I C, we keep an additional +local log file and make sure we log the year in each log line since +the log entries will be kept around for several years. + + # Override built in defaults + Defaults syslog=auth + Defaults:FULLTIMERS !lecture + Defaults:millert !authenticate + Defaults@SERVERS log_year, logfile=/var/log/sudo.log + +The I is the part that actually determines who may +run what. + + root ALL = (ALL) ALL + %wheel ALL = (ALL) ALL + +We let B and any user in group B run any command on any +host as any user. + + FULLTIMERS ALL = NOPASSWD: ALL + +Full time sysadmins (B, B, and B) may run any +command on any host without authenticating themselves. + + PARTTIMERS ALL = ALL + +Part time sysadmins (B, B, and B) may run any +command on any host but they must authenticate themselves first +(since the entry lacks the C tag). + + jack CSNETS = ALL + +The user B may run any command on the machines in the I 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, the local machine's netmask will be used +during matching. + + lisa CUNETS = ALL + +The user B may run any command on any host in the I alias +(the class B network C<128.138.0.0>). + + operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\ + /usr/oper/bin/ + +The B 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. + + joe ALL = /usr/bin/su operator + +The user B may only su(1) to operator. + + pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root + +The user B is allowed to change anyone's password except for +root on the I 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 may run anything on the I and I machines +as any user listed in the I C (B and B). + + jim +biglab = ALL + +The user B may run any command on machines in the I netgroup. +B knows that "biglab" is a netgroup due to the '+' prefix. + + +secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser + +Users in the B 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 can run commands as any user in the I C +(B or B) without giving a password. + + john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root* + +On the I machines, user B may su to anyone except root +but he is not allowed to give su(1) any flags. + + jen ALL, !SERVERS = ALL + +The user B may run any command on any machine except for those +in the I C (master, mail, www and ns). + + jill SERVERS = /usr/bin/, !SU, !SHELLS + +For any machine in the I C, B may run +any commands in the directory /usr/bin/ except for those commands +belonging to the I and I C. + + steve CSNETS = (operator) /usr/local/op_commands/ + +The user B 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 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 C (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 (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 +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 from running the commands listed in +I or I 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 file should B be edited by the B +command which locks the file and does grammatical checking. It is +imperative that I be free of syntax errors since B +will not run with a syntactically incorrect I 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 command or use the I option in +I. + +=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 index 0000000..88fc2af --- /dev/null +++ b/testsudoers.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_FNMATCH +# include +#endif /* HAVE_FNMATCH_H */ +#ifdef HAVE_NETGROUP_H +# include +#endif /* HAVE_NETGROUP_H */ +#include +#include +#include +#include +#include +#include +#include + +#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] [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 index 0000000..62f73da --- /dev/null +++ b/tgetpass.c @@ -0,0 +1,300 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#ifdef HAVE_SYS_BSDTYPES_H +# include +#endif /* HAVE_SYS_BSDTYPES_H */ +#ifdef HAVE_SYS_SELECT_H +# include +#endif /* HAVE_SYS_SELECT_H */ +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include +#ifdef HAVE_TERMIOS_H +# include +#else +# ifdef HAVE_TERMIO_H +# include +# else +# include +# include +# 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 index 0000000..1730081 --- /dev/null +++ b/utime.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1996, 1998, 1999, 2001 + * Todd C. Miller . 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 +#include +#include +#ifdef HAVE_UNISTD_H +# include +#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 index 0000000..bc7b7c6 --- /dev/null +++ b/version.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1996, 1998-2002 Todd C. Miller + * 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 index 0000000..c3a1c59 --- /dev/null +++ b/visudo.c @@ -0,0 +1,712 @@ +/* + * Copyright (c) 1996, 1998-2001 Todd C. Miller + * 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 +#include +#include +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include +#include +#include + +#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 index 0000000..4c82169 --- /dev/null +++ b/visudo.cat @@ -0,0 +1,198 @@ + + + +visudo(1m) MAINTENANCE COMMANDS visudo(1m) + + +NNNNAAAAMMMMEEEE + visudo - edit the sudoers file + +SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + vvvviiiissssuuuuddddoooo [ ----cccc ] [ ----ffff _s_u_d_o_e_r_s ] [ ----qqqq ] [ ----ssss ] [ ----VVVV ] + +DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + vvvviiiissssuuuuddddoooo edits the _s_u_d_o_e_r_s file in a safe fashion, analogous + to _v_i_p_w(1m). vvvviiiissssuuuuddddoooo locks the _s_u_d_o_e_r_s file against multi­ + ple simultaneous edits, provides basic sanity checks, and + checks for parse errors. If the _s_u_d_o_e_r_s file is currently + being edited you will receive a message to try again + later. + + There is a hard-coded list of editors that vvvviiiissssuuuuddddoooo will use + set at compile-time that may be overridden via the _e_d_i_t_o_r + _s_u_d_o_e_r_s Default variable. This list defaults to the path + to _v_i(1) on your system, as determined by the _c_o_n_f_i_g_u_r_e + script. Normally, vvvviiiissssuuuuddddoooo does not honor the EDITOR or + VISUAL environment variables unless they contain an editor + in the aforementioned editors list. However, if vvvviiiissssuuuuddddoooo is + configured with the _-_-_w_i_t_h_-_e_n_v_e_d_i_t_o_r flag or the _e_n_v_e_d_i_t_o_r + Default variable is set in _s_u_d_o_e_r_s, vvvviiiissssuuuuddddoooo 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. + + vvvviiiissssuuuuddddoooo parses the _s_u_d_o_e_r_s file after the edit and will not + save the changes if there is a syntax error. Upon finding + an error, vvvviiiissssuuuuddddoooo will print a message stating the line + _n_u_m_b_e_r(s) where the error occurred and the user will + receive the "What now?" prompt. At this point the user + may enter "e" to re-edit the _s_u_d_o_e_r_s file, "x" to exit + without saving the changes, or "Q" to quit and save + changes. The "Q" option should be used with extreme care + because if vvvviiiissssuuuuddddoooo believes there to be a parse error, so + will ssssuuuuddddoooo and no one will be able to ssssuuuuddddoooo again until the + error is fixed. If "e" is typed to edit the _s_u_d_o_e_r_s file + after a parse error has been detected, the cursor will be + placed on the line where the error occurred (if the editor + supports this feature). + +OOOOPPPPTTTTIIIIOOOONNNNSSSS + vvvviiiissssuuuuddddoooo accepts the following command line options: + + -c Enable cccchhhheeeecccckkkk----oooonnnnllllyyyy mode. The existing _s_u_d_o_e_r_s file + will be checked for syntax and a message will be + printed to the standard output detailing the status of + _s_u_d_o_e_r_s. If the syntax check completes successfully, + vvvviiiissssuuuuddddoooo will exit with a value of 0. If a syntax error + is encountered, vvvviiiissssuuuuddddoooo will exit with a value of 1. + + -f Specify and alternate _s_u_d_o_e_r_s file location. With + this option vvvviiiissssuuuuddddoooo will edit (or check) the _s_u_d_o_e_r_s + + + +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 _s_u_d_o_e_r_s file with ".tmp" appended to it. + + -q Enable qqqquuuuiiiieeeetttt mode. In this mode details about syntax + errors are not printed. This option is only useful + when combined with the ----cccc flag. + + -s Enable ssssttttrrrriiiicccctttt checking of the _s_u_d_o_e_r_s file. If an + alias is used before it is defined, vvvviiiissssuuuuddddoooo will con­ + 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 ----VVVV (version) option causes vvvviiiissssuuuuddddoooo to print its + version number and exit. + +EEEERRRRRRRROOOORRRRSSSS + sudoers file busy, try again later. + Someone else is currently editing the _s_u_d_o_e_r_s file. + + /etc/sudoers.tmp: Permission denied + You didn't run vvvviiiissssuuuuddddoooo 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 (ssssuuuuddddoooo will not com­ + plain). In ----ssss (strict) mode these are errors, not + warnings. + +EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT + The following environment variables are used only if + vvvviiiissssuuuuddddoooo was configured with the _-_-_w_i_t_h_-_e_n_v_-_e_d_i_t_o_r option: + + EDITOR Invoked by visudo as the editor to use + VISUAL Used Invoked visudo if EDITOR is not set + + +FFFFIIIILLLLEEEESSSS + /etc/sudoers List of who can run what + /etc/sudoers.tmp Lock file for visudo + + +AAAAUUUUTTTTHHHHOOOORRRR + Many people have worked on _s_u_d_o over the years; this ver­ + sion of vvvviiiissssuuuuddddoooo was written by: + + + + +April 25, 2002 1.6.6 2 + + + + + +visudo(1m) MAINTENANCE COMMANDS visudo(1m) + + + Todd Miller + + See the HISTORY file in the sudo distribution or visit + http://www.sudo.ws/sudo/history.html for more details. + +BBBBUUUUGGGGSSSS + If you feel you have found a bug in sudo, please submit a + bug report at http://www.sudo.ws/sudo/bugs/ + +DDDDIIIISSSSCCCCLLLLAAAAIIIIMMMMEEEERRRR + VVVViiiissssuuuuddddoooo 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 ssssuuuuddddoooo for complete details. + +CCCCAAAAVVVVEEEEAAAATTTTSSSS + There is no easy way to prevent a user from gaining a root + shell if the editor used by vvvviiiissssuuuuddddoooo allows shell escapes. + +SSSSEEEEEEEE AAAALLLLSSSSOOOO + _v_i(1), _s_u_d_o(1m), _v_i_p_w(8). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +April 25, 2002 1.6.6 3 + + diff --git a/visudo.man.in b/visudo.man.in new file mode 100644 index 0000000..cfcfa23 --- /dev/null +++ b/visudo.man.in @@ -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 +.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 index 0000000..3e7a41f --- /dev/null +++ b/visudo.pod @@ -0,0 +1,192 @@ +=cut +Copyright (c) 1996,1998-2002 Todd C. Miller +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 [ B<-c> ] [ B<-f> I ] [ B<-q> ] [ B<-s> ] [ B<-V> ] + +=head1 DESCRIPTION + +B edits the I file in a safe fashion, analogous to +vipw(8). B locks the I file against multiple +simultaneous edits, provides basic sanity checks, and checks +for parse errors. If the I file is currently being +edited you will receive a message to try again later. + +There is a hard-coded list of editors that B will use set +at compile-time that may be overridden via the I I +C variable. This list defaults to the path to vi(1) on +your system, as determined by the I script. Normally, +B does not honor the C or C environment +variables unless they contain an editor in the aforementioned editors +list. However, if B is configured with the I<--with-enveditor> +flag or the I C variable is set in I, +B will use any the editor defines by C or C. +Note that this can be a security hole since it allows the user to +execute any program they wish simply by setting C or C. + +B parses the I file after the edit and will +not save the changes if there is a syntax error. Upon finding +an error, B 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 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 +believes there to be a parse error, so will B and no one +will be able to B again until the error is fixed. +If "e" is typed to edit the I 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 accepts the following command line options: + +=over 4 + +=item -c + +Enable B mode. The existing I file will be +checked for syntax and a message will be printed to the +standard output detailing the status of I. +If the syntax check completes successfully, B will +exit with a value of 0. If a syntax error is encountered, +B will exit with a value of 1. + +=item -f + +Specify and alternate I file location. With this option +B will edit (or check) the I file of your choice, +instead of the default, @sysconfdir@/sudoers. The lock file used +is the specified I file with ".tmp" appended to it. + +=item -q + +Enable B 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 checking of the I file. If an alias is +used before it is defined, B 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 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 file. + +=item @sysconfdir@/sudoers.tmp: Permission denied + +You didn't run B 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 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 +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 over the years; this version of +B was written by: + + Todd Miller + +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 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 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 allows shell escapes. + +=head1 SEE ALSO + +vi(1), sudo(8), vipw(8). -- 2.30.2