From: Bdale Garbee Date: Wed, 14 May 2008 18:03:12 +0000 (-0600) Subject: Imported Upstream version 1.6.6 X-Git-Tag: upstream/1.6.6^0 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ca3ab12a66fc683cabf546fd405cfbf39ef9fb6f;p=debian%2Fsudo Imported Upstream version 1.6.6 --- ca3ab12a66fc683cabf546fd405cfbf39ef9fb6f 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).