diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1999-11-18 16:29:02 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1999-11-18 16:29:02 +0000 |
commit | fb80ef71abd0dd6084c3019b48dac8f8875e56c0 (patch) | |
tree | 4539c778e73c91703e2f3f76360d2533b49f5ac6 | |
parent | 0c0a1b78c4dcea75d3af81ff0cfc60a948a7ef39 (diff) |
sudo 1.6, now with a BSD license
74 files changed, 28121 insertions, 0 deletions
diff --git a/usr.bin/sudo/BUGS b/usr.bin/sudo/BUGS new file mode 100644 index 00000000000..a7c381f4f16 --- /dev/null +++ b/usr.bin/sudo/BUGS @@ -0,0 +1,17 @@ +Known bugs in sudo version 1.6 +============================== + +1) "make install-man" should substitute correct paths into the + man pages themselves. + +2) Sudo should log when removing "dangerous" envariables. + +3) configure variables that have been cached cannot be overridden + in subsequent configure runs, even if other --with-* options are + given. This is a flaw in GNU autoconf. + +4) On DUNIX in sia mode, hitting return at the prompt does not quit. + +5) In parse.lex, '@" should not need to be a special character. + For some reason, if it is not excluded from WORD, Defaults@ doesn't + match. diff --git a/usr.bin/sudo/CHANGES b/usr.bin/sudo/CHANGES new file mode 100644 index 00000000000..2eb7756f800 --- /dev/null +++ b/usr.bin/sudo/CHANGES @@ -0,0 +1,1186 @@ +CHANGES since sudo 1.2 + +01) sudo now works under hpux, aix, sunos, bsd43, ultrix, linux, osf and irix. + +02) Files w/o the executable bit will be ignored if they are in your PATH. + +03) If execv() fails, perror is called (which prints out an error based on + errno) and sudo exits with -1. + +04) Included in this shar should also be a version of getpass() derived from + the bsd net-2 source which works on bsd, ultrix, hpux, aix, and irix + at least. The latter three unixes have what i consider to be a broken + getpass() in that if /dev/tty can't be opened it doesn't just use stdin + like bsd getpass(). This means you cannot do: rsh host "sudo command" + and have it work if your ticket has expired. + +05) The Makefile has changed significantly. It now has defines for all + supported architectures. + +06) Changed MAXCOMMANDLENGTH from 48 bytes to MAXPATHLEN and included + sys/param.h where appropriate. + +07) Rewrote the code that expands links & paths. It now works correctly. + (rewrote find_path.c) + +08) Added a define NEED_STRDUP so we don't conflict with the system's strdup(3) + +09) Now does *not* pass LD_* environmental vars on to programs that get + exec'd. Also removes SHLIB_PATH for hpux and _RLD_* for dec osf. + +10) Now searches current dir last if '.' or '' are in PATH. Misses braindeath + like './' but if that's in your path you deserve all the trojans you get. + +11) Added in linux patches from drew + flex support. + +12) Added insults back in from original sudo(8) (define USE_INSULTS). + +13) visudo now uses EDITOR envar (from John_Rouillard@dl5000.bc.edu) + +14) you can now specify a dir containing commands that a sudoer can do. + (from John_Rouillard@dl5000.bc.edu) + +15) Ported to Solaris 2.x (based on a port of sudo 1.1 done by UnixOps). + +16) Took out setuid(0); setruid(uid); pairs that bracketed calls to + update_timestamp() since they are unnecessary and setruid() is + broken on systems without a setreuid(2) or setresuid(2) system call. + (Ie: AIX and Solaris 2.x). + +17) The bulk of sudo now runs with the caller's real uid. Grep for + be_root() to find the exceptions. + +CHANGES from sudo 1.3 + +18) Added SECURE_PATH as suggested by russells@ccu1.auckland.ac.nz. + +19) Reworked clean_envp() to modify environ (not envp) so we can use + execvp() safely. + +20) Now use execvp() instead of execve() so sudo /bin/kill works under + broken solaris. This also fixed sudo /etc/fastboot under stock + 4.3 BSD. Basically, this means that any executable shell script that + lacks a '#!/bin/sh' magic number will now work with sudo. Personally + I think that the broken scripts should be fixed rather than changing + sudo, but vendors will be broken. Sigh. + +21) Added USE_EXECV define so you can make sudo use execv() if you + want. Using execvp() shouldn't be a problem since it is always + handed a non-relative path that begins with '/' but some people + may not trust execvp(). + +22) Log file lines will no longer get truncated. Syslog entries that + would overrun the syslog(3) line limit are continued on another entry. + +23) When logging to a log file, long entries are indented to improve + readability. + +24) Whenever the umask is changed, it is changed back to what it was + before. + +25) Log file is written as mode 600 instead of 644 + +26) Umask that sudo runs with may now be specified. + +27) There is now a "configure" script. + +28) Sudo will use ultra fast crypt (ufc) if it finds it for systems w/o + a real crypt(3) (non-US ConvexOS/Secure for instance). + +29) _BSD_COMPAT is now defined for Irix. + +30) The global variable uid is now initialized to -2 because I'm paranoid. + +31) Native Solaris 2 port from Matthew.Stier@aisg.com + +32) Now use sysconf(2) instead of getdtablesize(2) if it is available + (see change #31). Because of the the getdtablesize() emulation for + hpux is no longer necessary. + +33) Now only do a getcwd(3) or getwd(3) once and do it as the real user. + Sudo should no longer complain that it can't get the cwd unless + there is a real problem. + +34) Changed some malloc'd globals of fixed length to be allocated from + the stack instead as there was no win in allocating them from the + heap. + +35) Fixed AIX STATIC_FLAGS as per the AIX faq. + +36) Added -V flag to sudo and visudo (for version) + +37) Now treat EACCESS like EPERM when doing stat(2) in find_path.c + +38) Added prototypes for sudo functions (via __P macro) + +39) configure now uses uname(1) if it exists + +40) gethostbyname(3) is now only called if you define FQDN. There's really + no reason to not trust gethostname(2) and this way if name service is + hosed sudo isn't... + +41) added -v (validate) flag to sudo to update a timestamp w/o running + a command + +42) now use tgetpass() (getpass with a timeout) + +43) find_path() now uses realpath(3) + +44) wrote versions of realpath(3) and getcwd(3) for those without + +45) wrote tgetpass()--a getpass() that times out via select(2) + +46) sudo now uses posix signals if available + +47) Finally added ConvexOS C2 security support from + "Peter A. Nikitser, Systems Software Support, QUT" <P.NIKITSER@qut.edu.au> + +48) You can now #undef MAILER if you don't run sendmail or the equivalent. + +49) AFS support from adamh@austin.ibm.com + +50) If you define BOTH_LOGS in sudo.h you can log both via syslog(3) *ans* + to a log file. + +51) Added ultrix /etc/auth (enhanced security) support. + +52) Sudo now will work with a 4.2BSD syslog (SunOS < 4 && ultrix). + Personally, I'd say you are better off logging to a file if + your syslog is this ancient. + +53) Changed realpath(3) to sudo_realpath() since we need to do the + chdir(2) with the invoking uid. sudo_realpath() should be + faster than vendor-supplied realpath(3)'s anyway... + +54) No longer create a static binary on AIX since it reportedly + causes problem on newer versions on AIX 3.x. + +55) If sudo_realpath cannot chdir() back to cwd sudo will print + and error and exit. Previously it would either fail silently + or print an incorrect error message. + +56) Moved code to send error mail to be after the log message. + From rouilj@cs.umb.edu. + +57) Added SUDO_USER and SUDO_UID envars. Suggested by John P. Rouillard + (<rouilj@cs.umb.edu). + +58) Added -k and -h options and rearranged some of the code to be + more modular and less braindamaged. This introduces the concept + of "run modes" to sudo. + +59) Fixed visudo and flex. visudo now calls yyrestart() if you are using + flex instead of lex. From bostley@cs.colorado.edu. + +60) Added a "cat page" for systems w/o nroff. + +61) Fixed a bug whereby only the last directory specified in a Cmnd_Alias + was checked. Reported by "James R. Hendrick" <hendrick@ctron.com>. + +62) All .{c,lex,yacc} files now include both sys/types.h and unistd.h so + we are sure to get the typedef of uid_t. + +CHANGES from sudo 1.3.1 + +63) Added preliminary support for DEC OSF/1 protected passwords + (shadow passwords). + +CHANGES from sudo 1.3.1pl1 + +64) More support for DEC OSF/1 protected passwords (shadow passwords). + +CHANGES from sudo 1.3.1pl2 + +65) Fixed mail logging to include the username as it should have. + +66) Added hostname to log message in error mail. + +67) Added -l flag to sudo to list the allowed/forbidden commands. + Suggested by matthew@gateway.bsis.com (Matthew Stier) + +68) Fixed bison warnings for parse.yacc and visudo.yacc. + Pointed out by alfie@dcs.warwick.ac.uk (Nick Holloway). + +CHANGES from sudo 1.3.1pl3 + +69) Sudo will now exit with an error if the command to be run is > MAXPATHLEN. + +70) Test in configure for termios support was insufficient. It thought + Nextstep 3.2 had termios just because it as termios.h (need to link + with -posix for termios on NeXT's) + +CHANGES from sudo 1.3.1pl4 + +71) First stab at Skey support. + +72) Sudo now sets IFS to be SPACE, TAB, NEWLINE. + +73) Sudo now sets the real and effective gid to root's group + (based on passwd file). + +74) Sudo now checks that the sudoers file is owned by a certain user + and not readable or writable by anyone else. + (based on a suggestion by Joerg Schumacher <schuma@ips.cs.tu-bs.de>) + +75) Visudo now sets the owner on the new sudoers file based on #74 + +76) Sudo and visudo will now compile with byacc (Berkeley yacc). + +77) If the rename(2) of stmp -> sudoers fails /bin/mv is executed before + bailing. Based on code from Case Larsen <clarsen@mh1.lbl.gov>. + +78) User-level configuration is now done in options.h. + +79) Moved all compatibility #defines to compat.h + +80) Incorporated new parsing code from Chris Jepeway <jepeway@cs.utk.edu>. + This is much better than the previous parser. + +81) Rewrote visudo.c and tickled parse.yacc to work with it. Visudo + now gives you options if a parse error occurs rather than blindly + dumping you back in the editor. + +82) Took out all references to realpath since we are now checking based + in inode and device (with Chris' new parser). The upshot of this + is that path matches are done safely and the symlink problem has + gone away. + +83) Fixed bison warnings from new parse.yacc. + +84) Added a default case to parse.lex to error on unmatched tokens as Chris + suggested. + +85) Converted configure.in and acsite.m4 to autoconf 2.1. + +86) Added lsearch.c and search.h for os's w/o lsearch()/lfind(). + +87) Sudo now checks to see that the file it is executing is a regular file + (was just checking the execute bit so dirs slipped through). + Pointed out by Barb Dijker <barb@labyrinth.com>. + +88) Fixed a problem on HP-UX trusted systems with getpwuid() returning "*" + unless the real uid is 0. Reported by Brian Cunnie (cunnie@nyc.hp.com). + +89) configure now checks for size_t and ssize_t in unistd.h as well + as sys/types.h. + +90) configure now checks for egrep before actually using it. + +91) configure now checks for a working void implementation (ie: void * as + a generic pointer) and sets VOID to void or char accordingly. + +92) Added support for SunOS 4.x C2 security (shadow passwords) from + Kendall Libby (fubar@shore.net) + +93) Changed all occurrences of bzero() to memset() and bcopy() to + memmove(). + +94) Fixed a bug in sudo.c. If a user has no passwd entry sudo would + dump core (writing to a garbage pointer). Pointed out by + Stephen Schaefer <sps@gateway.bsis.com>. + +95) Worked around a bug in AIX's lex in parse.c. AIX lex doesn't seem + to handle {x,y} range notation correctly. Bleah. + +96) Sudo would not report a failed attempt if the user entered <return> + at the 2nd password: prompt so someone trying to guess a password + could just invoked sudo multiple times and try one passwd at a time. + Reported by Jonathan Adams <jonathan@smada.com>. + +97) Added User_Alias facility. + +98) Rewrote most of the ip address / network support. Now works on all + systems sudo has currently been tested on. + +99) Sudo now sets SUDO_COMMAND and SUDO_GID envariables in addition to + SUDO_USER and SUDO_UID. + +100) Added changes to configure.in for UnixWare. + (from John Warburton <jwarb@SACBH.com.au>) + +101) Merged in changes for Interactive Unix and RISCos. + (from Andy Smith <abs@maunsell.co.uk>) + +102) Added testsudoers (from Chris Jepeway <jepeway@cs.utk.edu>). + +103) Added fix for parse.yacc to avoid the kludge I was doing. + (from Chris Jepeway <jepeway@cs.utk.edu>) + +104) Now remove the IFS envar if set instead of setting it to a "safe" + value to avoid problems with make and others. + +105) Added FAST_MATCH option to check basenames of sudo command and + paths listed in sudoers file. If the basename doesn't match + then it is not a match. If the basename matches, then do + a stat to make sure it is a valid match. + +106) Now only stat(2) cmnd once in path_matches() (in parse.c). Sudo + was stating cmnd for *every* attempted match. Now the stat struct + is cached (ie: the var is a static). + +107) Signal handlers in visudo are now only installed after the stmp + file is opened. Previously, it was possible to erase an open + stmp file by sending visudo a signal within a small window. + +108) Added Goon Show insults from Russell Street <r.street@auckland.ac.nz>. + +109) Broke out the insults into separate include files (insults.h + is the master and includes the appropriate one). + +110) Now use getwd() instead of getcwd() and provide emulation for + OS's w/o it. This was done since some OS's with getwd() + implement getcwd() via a pipe to pwd(1). By emulating getwd() + by calling getcwd() on OS's w/o getwd() we lose nothing since + the compiler should optimize away the extra function call. + +111) Added crypt() for DEC OSF/1 3.x enhanced security. + From "Richard L Jackson Jr" <rjackson@osf1.gmu.edu>. + +112) Added an option to run the command in the background (-b) as + suggested by Jonathan Adams <jonathan@smada.com> + +113) First stab at kerberos support. I'm not really sure it is + possible to do this in a sane manor. Sigh. + +114) Better kerberos support. Had to use setreuid(2) but falls + back on a kludge if that does not exist or is broken. + +115) Added -p (password prompt) support. + Suggested by "David W. Cooley" <dwcooley@COLBY.EDU> + +116) Added partial implementation of -l (list) flag. + This is probably as good as it will get until sudo:tng. + +117) Added anti-spoofing code to tighten up a race condition + where a user could run sudo some_link and then change + where the link pointed after the old link had been + validated but before the exec(). + +118) Now update timestamp file via utime() (and emulate via utimes() + if necessary) to eliminate a small race. Works with + both POSIX utime() as well as old utime() in BSD <= 4.3. + +119) Kerberos ticket file now lives in same dirs as sudo timestamp + files (to avoid trouncing on normal ticket file) and is removed + after validation. + +120) Now log tty user is on as well as pwd in sudo logs. + +CHANGES from sudo 1.3.2 BETA + +121) Fixed a bug in the anti-spoofing check. + +122) Fixed up ISC support so that it works and looks like non-streams + stuff in interfaces.c. + +123) Now deal correctly with ip implementations that has an sa_len + field in struct sockaddr. + +124) Check ownership and permissions on timestamp dir and ignore if + not owned by root and mode 0700. Problem pointed out by Larry Auton + <lda@research.AT&T.com> and Navjot Singh <singh@research.AT&T.com>. + +125) Ignore timestamp files with preposterous dates to keep people from + faking out sudo on OS's that allow you to give away files to root. + Problem pointed out by Larry Auton <lda@research.AT&T.com> and + Navjot Singh <singh@research.AT&T.com>. + +126) A timeout of 0 will now cause a password to be entered every + time. Based on a suggestion by Larry Auton <lda@research.AT&T.com> + and Navjot Singh <singh@research.AT&T.com>. + +CHANGES from sudo 1.3.3 BETA + +127) Cleaned up interfaces.c so that it is more readable. + +128) Added support for syslog()'s that don't guarantee delivery + of a message. HP-UX is the only known offender. + +129) No longer use memmove() since memcpy() does what we need and + configure doesn't always catch memmove() even when it is + there (may be a library problem). + +130) Updated man page to reflect two more security issues. + +131) Cleaned up shadow password support in check.c. It should now + be readable. + +132) Added SCO support. + +133) Added check to configure to find the max length of a uid_t + in characters. + +134) Removed uid2str() since we now know how big a uid_t/gid_t + can be. This elminates a few malloc()'s. + +135) Added support for multiple insult types. Based on code and + a suggestion from Dieter Dworkin Muller <dworkin@village.org>. + +136) Replaced clean_env() and rmenv() with a rewritten clean_env() + that should be a little faster. This also makes it easier to + add to the list of "dangerous" envariables. + +137) Added netgroup support. Netgroups must start with a leading + "+" to that sudo knows it is a netgroup. + +138) Split out sudoers file format into its own man page. + As suggested by Andy Smith <abs@maunsell.co.uk>. + +139) Updated testsudoers.c to grok netgroups. + +CHANGES from sudo 1.3.4 BETA + +140) Added SecurID support from Giles Todd <giles@gt.demon.co.uk>. + +141) Added -s flag to start a root shell and -- to signify end of args. + +142) Sped up logging routines by replacing strncpy()'s with strcat()'s. + This is safe because we dyanically allocate logline to be big enough. + +143) Now support command line arguments in the sudoers file. + +144) Sped up the loading on command line arguments. This fixes the + "commands with large argc's take forever to run" bug. + +145) Expanded MAXCOMMANDLEN to 8K since we now have to deal with + command line arguments. Added bounds checking in fill() and + append() so we don't drop core. + XXX - 8k makes sudo *SLOW* + +146) Added support in the lexer for "termination characters" to be + escaped. Ie: you can now use [\,:=] in command line args + as long as you escape with a \. + +147) Testsudoers can now deal with commands that have arguments. + +148) If a file is not executable or not a regular file sudo will + now give the appropriate error message instead of just + "command not found" which is misleading. + +149) Fixed a bug where if FQDN is set, load_interfaces() was never + called. + +150) tty is now a global so it can be used in the ticket file + at a later date. + +151) Strings in the parser are now allocated dynamically. This results + in a large speedup as compared to a 1K array on the stack. I + have freed the strings in the parser where appropriate but that + may not catch all instances. Even so, the average sudo now + takes up less memory than the 1K array version. + +152) Fixed a bug in tgetpass() and configure that broke termio/termios + support for some OS's. + +153) Added cheapo implementation of tty-based timestamps. The correct + way is to have username be a directory with the tty tickets + inside. However, the current code does not take to that very + well, and it does not allow the two systems to coexist. Therefore, + instead of timestampdir/user/tty it is timestampdir/user.tty. + +154) Added support for building in other than the source directory. + Based on changes from "Simon J. Gerraty" <sjg@frodo.dn.itg.telecom.com.au> + +155) options.h and pathnames.h are now included via angle brackets + (<>) so as to use the -I include path. This way, those using + a shadow build tree may have local copies of these headers + w/o clobbering the distribution ones. + +156) EXEMPTGROUP is now a string (group name) and user_is_exempt() + is now less of a hack. It uses getgrnam(EXEMPTGROUP) to + get a list of users in the exempted group. + +157) --prefix and --exe_prefix are now honored in the Makefile. + +158) Sudo will now behave reasonably in the case where the sudoers + file location is mounted via NFS and the client does not + have "root" NFS privs. + +159) _PATH_SUDO_SUDOERS, _PATH_SUDO_STMP, and SUDOERS_OWNER are + now set via the Makefile since that appears to be what + most people expect... + +160) Now include a pre-generated version of parse.lex since so many + versions of lex are brain damaged. If parse.lex is changed + a new lex.yy.c will be generated. The distribution copy is + sudo-lex.yy.c. + +161) Upgraded to GNU autoconf version 1.5. There are now even + *more* options. + +CHANGES from sudo 1.3.5 BETA + +162) Fixed S/Key support. + +163) Cleaned up shadow password support further by moving much of + it to getspwuid.c. + +164) First cut at DCE support. [needs work to be functional] + +165) New Digital UNIX C2 support based on code from + "Randy M. Hayman" <haymanr@icefog.sois.alaska.edu> + +166) S/key support now works with the generic bellcore s/key + as well as the s/key from Wietse Venema's logdaemon. + (Previously only worked with the logdaemon s/key). + As an added bonus the s/key challenge is now embedded + in the password prompt for a cleaner look. + +167) lsearch.c will now compile on a strict ANSI C compiler. + ANSI doesn't allow pointer arithmetic on a "void *" + but gcc does. + +168) Bought back latest HP-UX DCE support from Jeff Earickson + <jaearick@colby.edu>. + +169) configure now comletely groks $SUDO_LIBS and $VISUDO_LIBS. + Plain old $LIBS is no longer used. LDFLAGS has also been + split up into $SUDO_LDFLAGS and $VISUDO_LDFLAGS. + The reason for this is that sudo often needs extra libs + for alternate authentication schemes but visudo rarely does. + +170) The code to copy command arguments flaied for large values of + argc due to realloc() lossage. We now cheat and treat argv[] + as a flat string (since that's what it is) and use pointer + arithmetic to compute the length. Kind of sneaky but it + works (and is relatively fast). + +CHANGES from sudo 1.3.6 BETA + +171) Added support for UN*X groups in sudoers based on code from + Dougal Scott <dwagon@aaii.oz.au>. + +172) interfaces.c should work on ISC UN*X again. + +173) All source files are <= 14 characters for old SYSV filesystems. + +CHANGES from sudo 1.3.7 GAMMA + +174) Minor configure[.in] fixes. + +175) tgetpass.c now compiles on OS's that put the definition of + fd_set in <sys/bsdtypes.h> + +CHANGES from sudo 1.4 + +176) Command args in sudoers are now stored in an argument vector + instead of a flat string to make wildcard matching simpler. + +177) Added NewArgv and NewArgc that describe the command to be + executed. The copy of args in cmnd_args is no longer necessary + and has been removed. + +178) Using strcmp(3) for argument matching in command_matches() + (was path_matches()) is no longer sufficient since we don't + have a flat string. compare_args() is used instead which + calls either strcmp(3) or wildmat(3l) depending on whether + there are shell-style meta chars (wildcards) present. + +179) Shell-style wildcard matches are now available in the sudoers + file. Matches are done via Rich $alz's wildmat(3). + This required the tweaks described in #176-178 as well as + other, more minor, changes. + +180) Commented out rule to build lex.yy.c from parse.lex since + we ship with a pre-flex'd parser and can't rely on file + dates being set correctly. + +181) Fixed visudo and testsudoers to deal with new argument + vector handling. + +182) A null string ("") as shell in passwd file (or $SHELL) is + now treated as the bourne shell. + +183) Converted *.man to pod format for easy conversion to man, + html, latex, and just plain text. Tried to make the + sudoers manual easier to read in the process. + +184) Updated sample.sudoers and sudoers.pod to include info + on wildcards. + +CHANGES from sudo 1.4.1 + +185) compat.h now defines _PASSWD_LEN based on PASS_MAX if it + is defined (from limits.h on SYSV). + +186) Both short and long hostnames may now be used in the sudoers + file if FQDN is defined. From patches submitted by + Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>. + +187) Now use skeylookup() instead of skeychallenge(). Hopefully + this will work around a problem some people have reported + on Solaris 2.5 with sudo and logdaemon 5.0's skey. + +188) Now uses /var/run to hold timestamp files if it exists. This + is more secure. + +189) configure now puts the timestamp dir in /var/run if it exists. + Sugestion by Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>. + +190) Both short and long hostnames now exist even if FQDN is not set. + This allows machines with fully qualified hostnames set via + hostname(1) to use them in the sudoers file. + +191) sudo was not honoring "." in $PATH due to a bug in find_path(). + +192) Added IGNORE_DOT_PATH option to ignore "." in $PATH. + +193) tgetpass() now uses raw read(2) and write(2) instead of stdio. + This should make it work on more OS's. Previously, it used + stdio (buffered) fgets(3) and fputs(3) with select(2) which + may not be legal. Also got rid of the nasty goto's and + generally simplified the code. + +194) Parser now supports hostnames like UPPERCASE.foo.com. Previously, + `UPPERCASE' was interpreted as an Alias. This means that + the `fqdn' stuff has been moved to the lexer (FQHOST is used + to avoid collision with FQDN option). + +195) Reworked --with-FOO in configure.in to support --without-FOO. + Made shadow passwords the default for appropriate OS's. They + can be turned off with --without-C2. + +196) Added NO_PASSWD option for those who don't want to be bothered + by a password prompt from sudo. This is really just a hack. + +197) Added support for double quotes to mean "treat these words as one + argument". This is similar to what most shells do. + +198) Added mkinstalldirs to make install destination dirs if + they do not already exist. + +CHANGES from sudo 1.4.2 + +199) Added support for --with-CC (which C compiler to use). + +200) Added support for NOPASSWD token and running commands a + specified users (sudo -u) from Keith Garry Boyce + <garp@opustel.com> + +201) Only link with -lshadow for Linux if libc lacks getspnam(). Problem + pointed out by Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>. + +202) Replaced SUDOERS_OWNER with SUDOERS_UID and SUDOERS_GID. Added + SUDOERS_MODE and changed the default to 0440 (from 0400). + It is now possible to NFS-mount sudoers without doing anything fancy. + +202) If a runas list is specified, a user may only run commands as + "root" if "root" is a member of the runas list. The old behavior + was to always allow commands to be run as root, even if a runas + list was specified. Now you can give someone "sudo -u operator" + and not have the equivalent of "sudo -u root" as well. + +203) Added "USER=%s" to logging functions. + +204) configure will now add -lPW to (VI)?SUDO_LIBS if using bison + or DCE and alloca(3) is not in libc (or provided by gcc) but + is in libPW.a. + +205) sudo would give an incorrect error message if the sudoers file + didn't exist due to close() stomping errno if the open() failed. + +206) Fixed "shell" mode (sudo -s). When building NewArgv sudo was + not allocating space for the NULL. + +207) Added support for wildcards in the pathname. Ie: /bin/*. + +208) 'command ""' in sudoers now means no args allowed. + +209) Added command line args to SUDO_COMMAND envariable. + +210) HP-UX 10.x with C2 now uses bigcrypt(). + Changes from david_dill@Merck.Com (David Dill). + +211) lsearch.c will now compile w/o compiler warnings. + (Updated from NetBSD lsearch.c) + +212) Now uses POSIX fnmatch(3) (which uses ! instead of ^ in ranges) + +CHANGES from sudo 1.4.3 + +213) Now allows network/netmask in sudoers to override per-interface + netmask. + +214) Fixed -u support with multiple user lists on a line. + +215) Fixed a core dump problem when built with -DSHELL_IF_NO_ARGS. + +216) Fixed 2 typos in parse.yacc and removed some unnecessary if's. + +217) Now always use install-sh since SunOS install can't do uid/gid's. + Other BSD installs are probably similarly afflicted. + +218) Fixed NFS-mounted sudoers file under solaris both uid *and* gid + were being set to -2. Now set uid to 1 to avoid group being + remapped. + +219) Now includes alloca.c (from gcc) for those w/o it. Linking + against -lPW breaks visudo on HP-UX and probably others. + +220) Added --with-libpath, --with-libraries, --with-incpath options + to configure. + +221) configure now uses shicc instead of gcc on BSD/OS >= 2.0 to + generate binaries linked with shared libs. + +222) The parser was setting no_passwd even if there wasn't a + runas match. I reordered some things in parse.yacc + to fix this. + +223) `sudo -v' (validate) wasn't paying attention to NOPASSWD. + Now it does. + +224) testsudoers now groks "-u user". + +225) Updated AFS support based on what tcsh 6.06 does. + +226) Fixed a typo/thinko that broke BSD > 4.3reno wrt interfaces.c. + +227) HPUX 10.X shadow password stuff now uses SecureWare routines. + +228) SecureWare passwd checking now uses bigcrypt() if available. + Now uses AUTH_MAX_PASSWD_LENGTH if defined. + +229) configure now makes sure you don't have a config.cache file + from another OS. + +230) Added better shadow password detection. + BSD >= 4.3reno -> /etc/master.passwd + hpux9: getspwnam() -> /.secure/etc/passwd + hpux10: getspnam() or getprpwnam() -> /tcb/files/auth/*/* (link with -lsec) + SVR4: getspnam() -> /etc/shadow + solaris: getspnam() -> /etc/shadow + irix[56].x: getspnam() -> /etc/shadow + sunos 4.x: getpwanam() -> /etc/security/passwd.adjunct + DUNIX: getprpwnam() -> /tcb/files/auth/*/* (link with -lsecurity) + SecureWare: getprpwnam() -> /tcb/files/auth/*/* + ultrix 4.x: getauthuid() -> /etc/auth.{pag,dir} + +231) '(' in command args no longer are a syntax error. + +232) '!command' now works in the presence of a runas or NOPASSWD token. + Simplified parse rules wrt runas and NOPASSWD (more consistent). + +233) Command args and now compared as a flat string again. This makes + wildcard matches more consistent. + +234) DUNIX C2 support now groks AUTH_CRYPT_OLDCRYPT and AUTH_CRYPT_C1CRYPT. + +235) configure now uses config.{sub,guess} to guess OS type. + Sudo should work out of the box on more OS's now. + +236) Got rid of HAVE_C2_SECURITY, now just use SHADOW_TYPE. + +237) Fixed race in tgetpass() where echo can be turned off and + left off if sudo is used in a pipeline and a password is + required. + +CHANGES from sudo 1.4.4 + +238) `sudo -l' output now includes runas and NOPASSWD info and + asks for a password unless NOPASSWD for ALL is set. + +239) Sudo can now deal with all-caps user and host names. + +240) Sudo will now remove the "ENV" and "BASH_ENV" envariables. + From Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>. + +241) `sudo -l' will now expand Cmnd_Alias's (could be prettier). + +242) `sudo -s' will now set $HOME to root's homedir (or that of + the user specified -u) so dot files get sourced. + +CHANGES from sudo 1.4.5 + +243) $HOME was always being set, not just with `-s'. + +244) In visudo, the owner and group of the sudoers file were + being set too early; an editor could change them and change + the owner/group of the resulting sudoers file. + +CHANGES from sudo 1.5 + +245) Added SHELL_SETS_HOME option. + +246) Added NO_MESSAGE option. + +247) Added %u and %h escapes in PASSPROMPT to expand to user's name + and host. + +248) Added "SUDO_PROMPT" envariable. + +249) Usernames may now begin with a digit. Gross, but people do it. + +Sudo 1.5.1 released. + +250) Added `opie' support. + +251) Added check to make sure fnmatch() really works. + +252) Now use the prompt S/Key gives us instead of rolling our own. + +253) Added -H flag from Danny Barron <dcbarro@nppd.com>. + +254) Add SUDO_PS1 envariable support. + +255) Attempt at sequent support. + +Sudo 1.5.2 released. + +256) visudo acts sanely when there is no sudoers file. + +257) Added Runas_Alias support. + +258) Sudo will now work with SUDOERS_MODE == 400 and SUDO_UID = 0. + +259) Alias's in a runas list are now expanded. + +260) Fixed bug with > 32 saved aliases. Reported by BHH@capgroup.com. + +261) Code that uses sprintf() is now more paranoid about buffer + overflows. + +262) Whitespace is now allowed after a line continuation character before + a newline in sudoers. + +263) %h in MAILSUBJECT expands to local hostname. + +Sudo 1.5.3 released. + +264) Don't pass getdtablesize() as first arg to select(2). No need + to do this since we only select on one fd--use (fd+1) as nfds + and the old way caused problems on some systems (arguably + a bug in those OS's). From Marc Slemko marcs@znep.com. + +265) Fixed coredump when passwd file is missing or unavailable. + Reported by Jason Downs <downsj@teeny.org> and + Klee Dienes <klee@mit.edu> (via a Debian Linux bug report). + +266) Fixed bug wrt exclusion lists and relative pathnames. + Reported by osiris@COURIER.CB.LUCENT.COM. + +267) exit(1) if user doesn't enter a passwd. + Noted by Alex Parchkov <alexp@ind.tansu.com.au>. + +Sudo 1.5.4 released. + +268) Newer versions of Irix use _RLDN32_* envariables for 32-bit binaries + so ignore _RLD* instead of _RLD_*. From tarrall@bamboo.Colorado.EDU. + +269) Only open sudoers file once as opposed to once for sanity checks and + once for the parser. Also try to open ten times if we get EAGAIN. + +Sudo 1.5.5 released. + +270) Initialize group vector if we are becoming a user other than root. + For root, it is often more useful to hang on to our existing group + vector. + +271) Fix usage of select(2) to deal correctly with a high-numbered fd. + +272) Fixed a bug where sudo sometime didn't give the user a chance to + enter a password at the prompt. + +273) Use a dynamically sized buffer when reading ether interfaces. + +274) Fixed configure problems with identification of HP-UX > 10.x and + with cc being identified as a cross compiler on some platforms. + +275) Fixed a problem with HP-UX 10.x and alloca. Bison does not + include alloca.h on HP-UX 10.x even though it uses alloca() + (and thus needs the #define of alloca(x) to __builtin_alloca(x)). + To fix this we include alloca.h ourselves if using bison and not gcc. + +276) Included support for the AIX 4.x authenticate() function from + Matt Richards <v2matt@btv.ibm.com>. + +277) Fixed an off by one error in the parser. Found by + Piete Brooks <Piete.Brooks@cl.cam.ac.uk> + +278) Change NewArgv size computation to work on UNICOS. + From Mike Kienenberger <mkienenb@arsc.edu> + +279) Added --with-logfile and --with-timedir configure options. + +280) Use getcwd(3), not getwd(3) to avoid possible buffer overflow. + Use BSD getcwd(3) if system lacks one or is SunOS 4.x. + +281) Fix 'fprintf' argument mismatches in 'visudo.c'. + From ariel@oz.engr.sgi.com (Ariel Faigon) + +282) Use waitpid or wait3 to reap children in logging.c. + Pointed out by Theo de Raadt <deraadt@theos.com> + +283) Sudo should prompt for a password before telling the user that + a command could not be found. Noted by rhodie@NAC.NET. + +284) Fix OTP_ONLY for opie; "Deven T. Corzine" <deven@fuse.net>. + +285) Include pre-yacc'd parse.yacc as sudo.tab.[ch] since more and + more vendors are charging for yacc (bad vendor, no cookie). + +286) Use MAX*, not MAX*+1 + +287) Add support for Hitachi SR2201, from b-edgington@hpcc.hitachi-eu.co.uk + +288) Added RUNAS_DEFAULT option to allow one to compile sudo with a + default runas user other than root. + +289) Add options to log the hostname in the file-based log and to not + do word wrap in file-based log. From Theo Van Dinter <tvd@chrysalis.com> + +290) RedHat Linux pam support, from Gary Calvin <GCalvin@kenwoodusa.com>. + pam.sudo goes in /etc/pam.d/sudo on RedHat 5.0 and above. + +291) With sudo -s, set command the full path of the shell, not the basename. + Noted by Peter W. Osel <pwo@guug.de> + +Sudo 1.5.6 released. + +292) Pam auth now runs as root; necessary for shadow passwords. + +293) Shadow password support is now compiled in by default. You can disable + it via --disable-shadow. + +294) We now remove a timestamp file with a bogus date when it is detected. + From Steve Fobes <sfobes@uswest.com>. + +295) In tgetpass(), restart select if it is interrupted. This really fixes a + problem where a user sometimes is not given a change to enter a password. + +296) All options have moved from options.h -> configure. + +297) visudo is now installed in /usr/local/sbin where it belongs. + +298) Lots of configure changes. Instead of checking for the existence + of -lsocket, -lnsl, or -linet, we instead check them for the + functions we need only if they are not already in libc. + +299) Added DUNIX SIA (Security Integration Architecture) support from + Spider Boardman <spider@Orb.Nashua.NH.US>. + +300) Added test for broken Digital UNIX 4.0 prot.h. + +301) Better support for C2 security on Digital UNIX. + +302) Hacked autoconf so that you have have single quotes in + --with-passprompt. + +303) For SecureWare-style shadow passwords use getprpwnam() instead + of getprpwuid() since getprpwuid is broken in HP-UX 10.20 at + least (it sleeps for 2 minutes if the shadow files don't exist). + +304) We can't really trust UID_MAX or MAXUID since they may only exist for + backwards compatibility; spider-both@Orb.Nashua.NH.US + +305) Make %groups work as RunAs specifiers; Ray Bellis <rpb@community.net.uk>. + +306) Set USER environment variable to target user. + Suggested by Ray Bellis <rpb@community.net.uk>. + +307) Go back to printing "command not found" unless --disable-path-info + specified. Also, tell user when we ignore '.' in their path and it + would have been used but for --with-ignore-dot. + +308) When using tty tickets make it user:tty not user.tty as a username + could have a '.' in it. + +309) Define BSD_COMP for svr4 to get BSD ioctl defs. Also, if we have + sys/sockio.h but SIOCGIFCONF is not defined by including sys/ioctl.h + include sys/sockio.h directly. + +310) Fixed a bug that could cause "sudo -l" to segfault or complain + about non-existent syntax errors. + +Sudo 1.5.7 released. + +311) Fixed square bracket quoting in configure and moved check for -lnsl + to be before -lsocket. + +312) In load_interfaces(), close sock after bwe are done with it. Leak + noticed by Mike Kienenberger <mkienenb@arsc.edu>. + +313) Missing pieces from change #308; from Mike Kienenberger. + +314) Real Kerberos 5 support from Frank Cusack <fcusack@iconnet.net>. + +315) FWTK 'authsrv' support from Kevin Kadow <kadow@MSG.NET>. + +316) Fixed handling and documentation of -with-umask. + +317) If the check for socket() or inet_addr() fails, retry, this time + linking with both -lsocket and -lnsl for those systems that + have interlibrary dependencies. + +Sudo 1.5.8 released. + +318) Add dirfd() macro for systems without it. + +319) Better check for socket() in -lsocket -lnsl in configure. + +320) Minor configure fixes. + +Sudo 1.5.8p1 released. + +321) Fixed a bug wrt quoting characters in command args. + +322) Make --without-sendmail work. + +Sudo 1.5.8p2 released. + +323) Fixed a segv if HOST_IN_LOG defined and gethostbyname() fails. + Reported by Gero Treuner <gero@faveve.uni-stuttgart.de>. + +324) Fixed a parse bug wrt the ! operator and runas specs. Noted by + David A Beck <BKD@payserv.telekurs.com>. + +325) Use new emalloc/erealloc/estrdup functions (catch errors and exit). + +326) New PAM code that should work on both Solaris and Linux. + +327) Make sudo's usage info better when mutually exclusive args are given + and don't rely on argument order to detect this. From Nick Andrew. + +328) In visudo, shift return value of system() by 8 to get the real exit value. + +Sudo 1.5.9 released. + +329) The runas user and NOPASSWD tags are now persistent across entries + in a command list (ie: cmnd1,cmnd2,cmnd3). A PASSWD tag has been + added to reverse NOPASSWD. The runas user and *PASSWD tags can be + overridden on a per-command basis at which point they become the + new default for the rest of the list. + +330) It is now possible to use the '!' operator in a runas list as + well as in a Cmnd_Alias, Host_Alias and User_Alias. + +331) In estrdup(), do the malloc ourselves so we don't need to rely on the + system strdup(3) which may or may not exist. There is now no need to + provide strdup() for those w/o it. + +332) You can now specify a host list instead of just a host or alias + in a privilege list. Ie: user=host1,host2,ALIAS,!host3 /bin/ls + +333) Stash the "safe" path to the command instead of stashing the struct + stat. Should be safer. + +334) Now set $LOGNAME in addition to $USER. + +335) No longer use stdio in tgetpass() + +336) Don't use _PASSWD_LEN or PASS_MAX as we can't rely on them corresponding + to anything real. Instead, we just use a max password size of 256 + everywhere. + +337) Block keyboard-generated signals during startup and restore signal + mask before exec'ing the program. We don't want the user to be + able to simply kill us and avoid logging. + +338) Rewrote timestamp handling. For the default case, a directory is used + instead of a file. For the tty-based case, the timestamp is just a + file in that directory (eg. /var/run/sudo/username/tty). You now only + get the lecture once, even in the tty case. The goal here is to allow + the tty and non-tty schemes to coexist, though it is worth noting that + when you update a tty file, the mtime of the dir gets updated too. + +339) The meaning of -k has changed to mean "invalidate the timestamp". + There is a new -K option to really remove the timestamp file/dir. + +340) New modular authentication API. This fixes the rat's nest of + #ifdefs that was the old auth code. + +341) New logging functions. log_error() now takes a variable number of + args ala printf() and log_auth() reacts to the return value of validate(). + +342) If a user is not in the sudoers file they are still asked for a password. + This keeps someone who finds a user logged in to a terminal from being + able to tell whether or not the user is allowed to use sudo. + +343) New PAM code again, this time it should be correct. + +344) tgetpass() now has a flag to specify whether or not to turn + off echo while reading the password. Used by the new PAM and + fwtk code. + +345) Fixed shadow password dectection on SCO. + +346) Sudo is now available under a BSD/Apache style license. This is + possible because it no longer contains any of the original 1.1 code. + +347) Added configuration info when sudo is run with the -V flag by root. + +348) Change visudo tmp file from /etc/stmp -> /etc/sudoers.tmp since + Solaris uses stmp for shadow temp file. Also rename _PATH_SUDO_SUDOERS + to _PATH_SUDOERS and _PATH_SUDO_STMP to _PATH_SUDOERS_TMP. + +349) Added configure option to set syslog priorities. + +350) Sudo now locks its log file to prevent mangled entries. + +351) Visudo now locks the sudoers temp file instead of bailing when + the temp file already exists. This fixes the problem of stale + temp files but it does *require* that you not try to put the + temp file in a world-writable directory. This shoud not be + an issue as the temp file should live in the same dir as sudoers. + +352) Fixed crypt() check in libufc. + +353) It is now possible to put a list of users as the first thing in a + user specification. I don't suggest this but it makes the grammar + more uniform. + +354) Visudo will now warn about what it thinks are undefined aliases. + Since it can't be 100% sure these are just warnings, not errors. + +355) Add a --without-passwd option to configure that turns off + passwd/shadow file authentication. Only usable with an alternate + authentication scheme. + +356) Add a --disable-authentication option to configure that causes sudo + to not require authentication by default. The PASSWD tag can be + used to require authentication for an entry. + +357) Add a --with-devel option to add -Wall and uncomment yacc/lex + generation in Makefile. + +358) Zero out plaintext password after use (should do encrypted as well). + +359) Added real dependencies in Makefile. + +360) Deprecated --with-otp-only in favor of --without-passwd. + +361) Add --with-mail-if-no-host to send mail if a user tries to run sudo on + a host for which he/she is not authorized. + +362) Most of sudo now runs as root instead of the invoking user to + minimize the possibility of user control via signals or tracing. + +363) Now Support CIDR-style netmasks (ie: 128.138.0.0/16). + +364) In "sudo -l" mode, the type of the stored (expanded) alias was not + stored with the contents. This could lead to incorrect output + if the sudoers file had different alias types with the same name. + Normal parsing (ie: not in '-l' mode) is unaffected. + +365) Now include strcasecmp() for those without it. + +366) Most compile-time options are now changable at runtime via + the 'Defaults' specification in the sudoers file. + +367) Added a -L flag to printout all the possible 'Defaults' parameters. + +368) It is now possible to escape "special" characters in usernames, hostnames, + etc with a backslash. + +369) Sudo will now accept a hostname/username/netgroupname that contains + almost any character in it. It seems many people want to use '.' + and other non-alphanumerics in usernames. + +370) Fixed the root_sudo option. Sudo was always complaining that root + was not allowed to run sudo if the root_sudo flag was turned off. + +371) tgetpass() now uses a function to read up until the end of line. + Fixes problems in a pipeline when a program sets the tty mode + to be character at a time. + +372) sudo now turns off core dumps via setrlimit (probably paranoia). diff --git a/usr.bin/sudo/HISTORY b/usr.bin/sudo/HISTORY new file mode 100644 index 00000000000..d0c9bf8f511 --- /dev/null +++ b/usr.bin/sudo/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. This version was bought by a +consulting firm called "The Root Group" and released under the GNU +public license. + +In 1994, after maintaining sudo informally withing CU-Boulder for +some time, Todd Miller made a public release of "CU sudo" (version +1.3) with bug fixes and support for more operating systems. The +"CU" was added to differentiate it from the "official" version from +"The Root Group". + +In 1996, Todd, who had been maintaining sudo for several years in +his spare time, brought sudo development under the umbrella of his +consulting firm, Courtesan Consulting. Courtesan remains committed +to a free sudo and is sponsoring another sudo rewrite as well as +continued development of the sudo 1.x code base. + +In 1999, the "CU" prefix was dropped from the name since there has +been no formal release of sudo from "The Root Group" since 1991 +(the original authors now work elsewhere). As of version 1.6, Sudo +no longer contains any of the original "Root Group" code and is +available with a BSD-style license. + +sudo, in its current form, is maintained by: + + Todd Miller <Todd.Miller@courtesan.com> + +Todd continues to enhance sudo and fix bugs. diff --git a/usr.bin/sudo/INSTALL b/usr.bin/sudo/INSTALL new file mode 100644 index 00000000000..a80ff09ea1e --- /dev/null +++ b/usr.bin/sudo/INSTALL @@ -0,0 +1,563 @@ +Installation instructions for Sudo 1.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. Also of interest may be the section on + `Mixing password authentication schemes'. + + 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 + + --help + Print the usage/help info + + --no-create + Do not create output files + + --quiet, --silent + 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 + Adds the specified 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 + Adds the specified 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 + Adds the specified 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 and Solaris 2.6. + + --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 and 10.0. Other + platforms may require source code and/or `configure' changes. + + --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 + 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 + 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 authentication via the passwd (or shadow) file. + It should only be used when another, alternate, authentication + scheme is in use. + + --with-editor=path + Specify the default editor used by visudo (and the only editor used + unless --with-env-editor is specified). 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. Note that this may create a + security hole as most editors allow a user to get a shell (which would + be a root shell and hence, no logging). + +The following options are also configurable at runtime: + + --with-otp-only + This option is now just an alias for --without-passwd. + + --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 FAQ). 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 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 that mail from sudo is sent to. This should go to a sysadmin at + your site. The default is "root". + + --with-mailsubject + 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 "alermail" 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 + 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 + 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 + 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=tries + Number of tries a user gets to enter his/her password before sudo logs + the failure and exits. The default is 3. + + --with-timeout=minutes + 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=minutes + 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 tty (per user). + Ie: instead of the ticket file 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. + + --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 specify --with-insults as well 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 specify --with-insults as well 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. + + --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. + + It is not possible to access the sudoers file via NFS on Linux. + This is due to a bug in the Linux client-side NFS implementation. + It has been fixed in the developement kernel but, as of Aug 27, 1999, + the fixes have not made it into the mainstream kernel. + +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. diff --git a/usr.bin/sudo/INSTALL.configure b/usr.bin/sudo/INSTALL.configure new file mode 100644 index 00000000000..a2c8722ccaf --- /dev/null +++ b/usr.bin/sudo/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/usr.bin/sudo/LICENSE b/usr.bin/sudo/LICENSE new file mode 100644 index 00000000000..ff1e2a8ed0c --- /dev/null +++ b/usr.bin/sudo/LICENSE @@ -0,0 +1,68 @@ +Sudo is distributed under the following BSD-style license: + +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * 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/usr.bin/sudo/Makefile.bsd-wrapper b/usr.bin/sudo/Makefile.bsd-wrapper new file mode 100644 index 00000000000..adb749a52b7 --- /dev/null +++ b/usr.bin/sudo/Makefile.bsd-wrapper @@ -0,0 +1,73 @@ +# $OpenBSD: Makefile.bsd-wrapper,v 1.1 1999/11/18 16:29:01 millert Exp $ + +MAN= sudo.8 sudoers.5 visudo.8 +XCFLAGS= CC="${CC}" CFLAGS="${CFLAGS} ${COPTS}" LDFLAGS="${LDFLAGS}" +CONFIGURE_OPTS= --prefix=/usr --with-devel --with-insults \ + --with-env-editor --with-logfac=authpriv + +.include <bsd.own.mk> + +.if (${SKEY} == "yes") +CONFIGURE_OPTS+=--with-skey +LDADD+= -lskey +DPADD+= ${LIBSKEY} +.endif + +.if (${KERBEROS} == "yes") +CONFIGURE_OPTS+=--with-kerb4 +LDADD+= -lkrb -ldes -lkafs +DPADD+= ${LIBKRB} ${LIBDES} ${LIBKAFS} +.endif + +all: config.status + ${MAKE} + +.FORCE: .IGNORE + +.ifdef GLOBAL_AUTOCONF_CACHE +CF= --cache-file=${GLOBAL_AUTOCONF_CACHE} +.else +CF= +.endif + +config: .FORCE +.ifndef GLOBAL_AUTOCONF_CACHE + -rm -f config.cache +.endif + PATH="/bin:/usr/bin:/sbin:/usr/sbin" \ + ${XCFLAGS} \ + INSTALL_PROGRAM="${INSTALL} ${INSTALL_COPY} ${INSTALL_STRIP}" \ + sh ${.CURDIR}/configure ${CONFIGURE_OPTS} ${CF} + +config.status: + PATH="/bin:/usr/bin:/sbin:/usr/sbin" \ + ${XCFLAGS} \ + INSTALL_PROGRAM="${INSTALL} ${INSTALL_COPY} ${INSTALL_STRIP}" \ + sh ${.CURDIR}/configure ${CONFIGURE_OPTS} ${CF} + +.ifdef NOMAN +maninstall: + @echo NOMAN is set +.endif + +install: maninstall + ${MAKE} ${XCFLAGS} prefix=${DESTDIR}/usr sysconfdir=${DESTDIR}/etc \ + bindir=${DESTDIR}/usr/bin install-binaries install-sudoers + +clean cleandir: + -@test -e Makefile && ${MAKE} distclean + +depend: + # Nothing here so far... + +lint: + # Nothing here so far... + +tags: + # Nothing here so far... + +.include <bsd.obj.mk> +.include <bsd.subdir.mk> +.ifndef NOMAN +.include <bsd.man.mk> +.endif diff --git a/usr.bin/sudo/Makefile.in b/usr.bin/sudo/Makefile.in new file mode 100644 index 00000000000..570e810d96c --- /dev/null +++ b/usr.bin/sudo/Makefile.in @@ -0,0 +1,332 @@ +# +# Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission +# 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.185 1999/09/08 08:06:03 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 + +# Which install program? +INSTALL = $(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 +# set mansect5 to 4 on sysV machines. +mantype = @MANTYPE@ +mansect8 = 8 +mansect5 = 5 +mandir8 = $(mandir)/$(mantype)$(mansect8) +mandir5 = $(mandir)/$(mantype)$(mansect5) + +# 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 defaults.c fileops.c find_path.c fnmatch.c \ + getcwd.c getspwuid.c goodpath.c interfaces.c lex.yy.c lsearch.c \ + logging.c parse.c parse.lex parse.yacc putenv.c snprintf.c strcasecmp.c \ + strerror.c sudo.c sudo.tab.c sudo_setenv.c testsudoers.c tgetpass.c \ + utime.c visudo.c $(AUTH_SRCS) + +AUTH_SRCS = auth/afs.c auth/aix_auth.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 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 getspwuid.o goodpath.o fileops.o find_path.o interfaces.o \ + logging.o parse.o sudo.o sudo_setenv.o tgetpass.o \ + $(AUTH_OBJS) $(PARSEOBJS) + +VISUDOBJS = visudo.o fileops.o $(PARSEOBJS) + +TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS) + +LIBOBJS = @LIBOBJS@ @ALLOCA@ + +VERSION = 1.6 + +DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES FAQ HISTORY INSTALL INSTALL.configure \ + LICENSE Makefile.in PORTING README RUNSON TODO TROUBLESHOOTING \ + UPGRADE acsite.m4 aixcrypt.exp config.guess config.h.in config.sub \ + configure configure.in fnmatch.3 indent.pro install-sh \ + mkinstalldirs pathnames.h.in sample.pam sample.sudoers sudo.cat \ + sudo.man sudo.pod sudoers sudoers.cat sudoers.man sudoers.pod \ + visudo.cat visudo.man visudo.pod auth/API + +SUDODEP = $(srcdir)/sudo.h $(srcdir)/compat.h $(srcdir)/defaults.h \ + $(srcdir)/logging.h config.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) + +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 + +# Dependencies (not counting auth functions) +alloc.o: alloc.c $(SUDODEP) +check.o: check.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) +sudo_setenv.o: sudo_setenv.c $(SUDODEP) +tgetpass.o: tgetpass.c $(SUDODEP) +visudo.o: visudo.c $(SUDODEP) version.h +sudo.o: sudo.c $(SUDODEP) interfaces.h version.h +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 +defaults.o: defaults.c $(SUDODEP) auth/sudo_auth.h +fnmatch.o: fnmatch.c config.h compat.h emul/fnmatch.h +getcwd.o: getcwd.c config.h compat.h +lsearch.o: lsearch.c config.h compat.h emul/search.h +putenv.o: putenv.c config.h compat.h +snprintf.o: snprintf.c config.h compat.h +strcasecmp.o: strcasecmp.c config.h +strerror.o: strerror.c config.h +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 +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.html: $(srcdir)/sudo.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2html --title="Sudo Manual" --infile=sudo.pod --outfile=$(srcdir)/$@) + +sudo.man: $(srcdir)/sudo.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2man --section=$(mansect8) --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod > $(srcdir)/$@) + +sudo.cat: sudo.man + +visudo.html: $(srcdir)/visudo.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2html --title="Visudo Manual" --infile=visudo.pod --outfile=$(srcdir)/$@) + +visudo.man: $(srcdir)/visudo.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2man --section=$(mansect8) --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod > $(srcdir)/$@) + +visudo.cat: visudo.man + +sudoers.html: $(srcdir)/sudoers.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2html --title="Sudoers Manual" --infile=sudoers.pod --outfile=$(srcdir)/$@) + +sudoers.man: $(srcdir)/sudoers.pod + @rm -f $(srcdir)/$@ + (cd $(srcdir); pod2man --section=$(mansect5) --release=$(VERSION) --center="FILE FORMATS" sudoers.pod > $(srcdir)/$@) + +sudoers.cat: sudoers.man + +install: install-dirs install-binaries install-sudoers install-man + +install-dirs: + $(srcdir)/mkinstalldirs $(sudodir) $(visudodir) $(sudoersdir) $(mandir8) $(mandir5) + +install-binaries: $(PROGS) + $(INSTALL) -o $(install_uid) -g $(install_gid) -m 4111 -s sudo $(sudodir)/sudo + $(INSTALL) -o $(install_uid) -g $(install_gid) -m 0111 -s visudo $(visudodir)/visudo + +install-sudoers: + @ if [ -f $(sudoersdir)/sudoers ]; then \ + echo "Setting user/group and mode on existing $(sudoersdir)/sudoers file."; \ + chown $(sudoers_uid) $(sudoersdir)/sudoers; \ + chgrp $(sudoers_gid) $(sudoersdir)/sudoers; \ + chmod $(sudoers_mode) $(sudoersdir)/sudoers; \ + else \ + $(INSTALL) -o $(sudoers_uid) -g $(sudoers_gid) -m $(sudoers_mode) \ + $(srcdir)/sudoers $(sudoersdir)/sudoers; \ + fi + +install-man: + $(INSTALL) -o $(install_uid) -g $(install_gid) -m 0444 $(srcdir)/sudo.$(mantype) $(mandir8)/sudo.$(mansect8) + $(INSTALL) -o $(install_uid) -g $(install_gid) -m 0444 $(srcdir)/visudo.$(mantype) $(mandir8)/visudo.$(mansect8) + $(INSTALL) -o $(install_uid) -g $(install_gid) -m 0444 $(srcdir)/sudoers.$(mantype) $(mandir5)/sudoers.$(mansect5) +@MAN_POSTINSTALL@ + +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 pathnames.h config.h config.status config.cache \ + config.log pod2html-dircache pod2html-itemcache $(PARSESRCS) + +clobber: distclean + +realclean: distclean + rm -f TAGS tags + +cleandir: realclean + +dist: $(DISTFILES) + 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 diff --git a/usr.bin/sudo/PORTING b/usr.bin/sudo/PORTING new file mode 100644 index 00000000000..5c0427ce22a --- /dev/null +++ b/usr.bin/sudo/PORTING @@ -0,0 +1,53 @@ +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 should +be done for you. + +If your OS is an SVR4 derivative (or some approximation thereof), it may +be sufficient to tell configure you are runnng SVR4, something like: + configure foo-bar-sysv4 +where foo is the hardware architecture and bar is the vendor. + +A possible pitfall is getdtablesize(2) which is used to get the +maximum number of open files the process can have. If an OS has +the POSIX sysconf(2) it will be used instead of getdtablesize(2). +ulimit(2) or getrlimit(2) can also be used on some OS's. If all +else fails you can use the value of NOFILE in <sys/param.h>. + +Sudo tries to clear the environment of dangerous envariables like +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 +badenv_table() in sudo.c to see how this is done for various OS's. + +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 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. + +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/usr.bin/sudo/README b/usr.bin/sudo/README new file mode 100644 index 00000000000..45f286d5b05 --- /dev/null +++ b/usr.bin/sudo/README @@ -0,0 +1,94 @@ +This is Sudo version 1.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.courtesan.com 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.courtesan.com/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 +=================== +Sudo requires 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. 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@courtesan.com. +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. + +sudo-users This list is for questions and general discussion about sudo. + +sudo-workers This list is for people working on and porting sudo. + +To subscribe to a list, send a mail message to "majordomo@cs.colorado.edu" +with a line in the message body (_not_ the subject) of "subscribe listname" +where "listname" is one of sudo-announce, sudo-users, or sudo-workers. + +Currently all the lists are fairly low-volume so there hasn't been a +need for digest versions. + +Web page +======== +There is a sudo `web page' at http://www.courtesan.com/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.courtesan.com/sudo/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/usr.bin/sudo/RUNSON b/usr.bin/sudo/RUNSON new file mode 100644 index 00000000000..b36b4e3d269 --- /dev/null +++ b/usr.bin/sudo/RUNSON @@ -0,0 +1,132 @@ +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.4 Todd Miller none +SunOS 4.1.3 sun4 gcc2.7.2.1 1.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.7.2.1 1.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.7.2.1 1.6 Todd Miller none +Solaris 2.6 i386 gcc2.7.2.1 1.6 Todd Miller none +Solaris 2.6 sparc unbundled cc 1.5.7 Giff Hammar none +Solaris 2.6 i386 unbundled cc 1.5.8p2 Udo Keller none +Solaris 7 i386 gcc 2.8.1 1.58p2 Brian Jackson none +Solaris 7 i386 Workshop 5.0 1.58p2 Brian Jackson none +Solaris 7 sun4u egcs 1.1.2 1.5.9p4 Scott Kinnane none +Solaris 5.6 sun4u egcs 1.1.2 1.5.9p4 Scott Kinnane 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 +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.20 hp700 gcc2.7.2.1 1.6 Todd Miller --with-skey +HP-UX 10.10 hp700 unbundled cc 1.5.5b4 Todd Miller --with-skey +HP-UX 10.20 PA-RISC1.1 bundled cc 1.5.4 Leon von Stauber none +HP-UX 10.20 PA-RISC2.0 bundled cc 1.5.4 Leon von Stauber none +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 10.20 hp700 gcc 2.8.1 1.5.6b2 Jeff Earickson --with-DCE +Ultrix 4.3 mips bundled cc 1.5 Maria Magnusson 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.4 Todd Miller none +IRIX 5.3 mips gcc2.7.2.1 1.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.58p2 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 gcc 2.8.1 1.6rc1 Jordan Baker none +IRIX 6.5 mips egcs 1.1.2 1.5.9p4 Scott Kinnane none +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 gcc-2.7.2.1 1.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 +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.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 2.1 i386 shlicc 1.5.3 Todd Miller none +OpenBSD 2.X i586 gcc-2.8.1 1.6 Todd Miller none +OpenBSD 2.X alpha gcc-2.8.1 1.5.9 Todd Miller none +OpenBSD 2.X m68k gcc-2.8.1 1.5.9 Todd Miller none +FreeBSD 1.1 i386 gcc 1.3.2 Dieter Muller none +FreeBSD 2.0.5 i386 gcc 1.3.4 Dieter Muller 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.36 i586 gcc 2.8.1 1.6 Todd Miller 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.34 alpha egcs-2.90.27 1.5.3 Karl Schlitt none +Linux 2.0.33pl1 m68k gcc 2.7.2.3 1.5.6 James Troup none +Linux 2.2.6-15 ppc egcs-1.1.2 1.5.9p4 Barbara Schelkle none +UnixWare 1.1.4 i386 gcc-2.7.2 1.4 Michael Hancock 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.45 mips CDS++ V1 1.59p4 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 +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 +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.5.7p4 Gerry Belanger CFLAGS= +NonStop-UX B32 CO-1475 cc 1.5.9p3 Andrei Panfilenko 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/usr.bin/sudo/TODO b/usr.bin/sudo/TODO new file mode 100644 index 00000000000..9c7b448e44e --- /dev/null +++ b/usr.bin/sudo/TODO @@ -0,0 +1,84 @@ +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 default options to sudoers file (umask, def uid, def gids, dir, PATH). + Defaults = option1, option2, ... + Defaults@host = option1, option2, ... + Defaults!user = option1, option2, ... + Defaults%group = option1, option2, ... + Defaults+netgroup = option1, option2, ... + +03) Add a SHELLS reserved word that checks against /etc/shells. + +04) Make the sudoers file accessible via NIS, Hesiod, and maybe NetInfo. + +05) Add a -h (?) flag to sudo for a history mechanism. + +06) Add an option to hard-code LD_LIBRARY_PATH? + +07) Add Prog_Alias facility (Prog_Alias VI = /usr/secure/bin/vi +args). + +08) check for <net/errno.h> in configure and include it in sudo.c if it exists. + +09) Add generic STREAMS support for getting interfaces and netmasks. + +10) 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... + +11) Overhaul testsudoers to use things from parse.o so we don't reimplement + things. + +12) Make runas_user a struct "runas" with user and group components. + (maybe uid and gid too???) + +13) Add -g group/gid option. + +14) 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. + +15) Add a per-tty restriction? Ie: only can run foo from /dev/console. + +16) Add test for how to read ether interfaces in configure script + +17) Add configure check for $(CC) -R and use it in addition to -L + +18) An option to make "sudo -s" use the target user's shell might be nice + (and more like su). + +19) Use getrlimit() in preference to getconf()/getdtablesize(). + +20) Add configure option to enable old behavior of visudo (O_EXCL)? + --without-sudoers-lock? + +21) Profile sudo again (is the yacc grammar optimal?) + +22) 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. + +23) Make 'sudo -l user' if run as root do a "sudo -l" output for the specified + user. + +24) Use strtol() and strtoul(), not atoi() + +25) In parse.yacc get rid on unneeded '{ ; }' + +26) Look into %e, %p, %k in parse.lex + +27) Document Defaults stuff in sudoers.pod + +28) Make syslog stuff work on vanilla ultrix + +29) Implement date_format and log_format options. + +30) Add support for: Default:user@host + +31) Add -S flag to force password read from stdin diff --git a/usr.bin/sudo/TROUBLESHOOTING b/usr.bin/sudo/TROUBLESHOOTING new file mode 100644 index 00000000000..06ce25c8444 --- /dev/null +++ b/usr.bin/sudo/TROUBLESHOOTING @@ -0,0 +1,130 @@ +FAQ and troubleshooting tips for Sudo +===================================== + +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 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 + ENV + BASH_ENV + LD_* + _RLD_* + SHLIB_PATH (HP-UX only) + LIB_PATH (AIX only) + KRB_CONF (kerb4 only) + KRB5_CONFIG (kerb5 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) How do you pronounce `sudo'? +A) soo-doo (for superuser do). diff --git a/usr.bin/sudo/UPGRADE b/usr.bin/sudo/UPGRADE new file mode 100644 index 00000000000..1b04e609517 --- /dev/null +++ b/usr.bin/sudo/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/usr.bin/sudo/acsite.m4 b/usr.bin/sudo/acsite.m4 new file mode 100644 index 00000000000..f10e261601d --- /dev/null +++ b/usr.bin/sudo/acsite.m4 @@ -0,0 +1,314 @@ +dnl Local m4 macors for autoconf (used by sudo) +dnl +dnl Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> +dnl +dnl XXX - should cache values in all cases!!! +dnl +dnl checks for programs + +dnl +dnl check for sendmail +dnl +AC_DEFUN(SUDO_PROG_SENDMAIL, [AC_MSG_CHECKING(for sendmail) +if test -f "/usr/sbin/sendmail"; then + AC_MSG_RESULT(/usr/sbin/sendmail) + AC_DEFINE(_PATH_SENDMAIL, "/usr/sbin/sendmail") +elif test -f "/usr/lib/sendmail"; then + AC_MSG_RESULT(/usr/lib/sendmail) + AC_DEFINE(_PATH_SENDMAIL, "/usr/lib/sendmail") +elif test -f "/usr/etc/sendmail"; then + AC_MSG_RESULT(/usr/etc/sendmail) + AC_DEFINE(_PATH_SENDMAIL, "/usr/etc/sendmail") +elif test -f "/usr/ucblib/sendmail"; then + AC_MSG_RESULT(/usr/ucblib/sendmail) + AC_DEFINE(_PATH_SENDMAIL, "/usr/ucblib/sendmail") +elif test -f "/usr/local/lib/sendmail"; then + AC_MSG_RESULT(/usr/local/lib/sendmail) + AC_DEFINE(_PATH_SENDMAIL, "/usr/local/lib/sendmail") +elif test -f "/usr/local/bin/sendmail"; then + AC_MSG_RESULT(/usr/local/bin/sendmail) + AC_DEFINE(_PATH_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) + AC_DEFINE(_PATH_VI, "/usr/bin/vi") +elif test -f "/usr/ucb/vi"; then + AC_MSG_RESULT(/usr/ucb/vi) + AC_DEFINE(_PATH_VI, "/usr/ucb/vi") +elif test -f "/usr/bsd/vi"; then + AC_MSG_RESULT(/usr/bsd/vi) + AC_DEFINE(_PATH_VI, "/usr/bsd/vi") +elif test -f "/bin/vi"; then + AC_MSG_RESULT(/bin/vi) + AC_DEFINE(_PATH_VI, "/bin/vi") +elif test -f "/usr/local/bin/vi"; then + AC_MSG_RESULT(/usr/local/bin/vi) + AC_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) + AC_DEFINE(_PATH_MV, "/usr/bin/mv") +elif test -f "/bin/mv"; then + AC_MSG_RESULT(/bin/mv) + AC_DEFINE(_PATH_MV, "/bin/mv") +elif test -f "/usr/ucb/mv"; then + AC_MSG_RESULT(/usr/ucb/mv) + AC_DEFINE(_PATH_MV, "/usr/ucb/mv") +elif test -f "/usr/sbin/mv"; then + AC_MSG_RESULT(/usr/sbin/mv) + AC_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) + AC_DEFINE(_PATH_BSHELL, "/bin/sh") +elif test -f "/usr/bin/sh"; then + AC_MSG_RESULT(/usr/bin/sh) + AC_DEFINE(_PATH_BSHELL, "/usr/bin/sh") +elif test -f "/sbin/sh"; then + AC_MSG_RESULT(/sbin/sh) + AC_DEFINE(_PATH_BSHELL, "/sbin/sh") +elif test -f "/usr/sbin/sh"; then + AC_MSG_RESULT(/usr/sbin/sh) + AC_DEFINE(_PATH_BSHELL, "/usr/sbin/sh") +elif test -f "/bin/ksh"; then + AC_MSG_RESULT(/bin/ksh) + AC_DEFINE(_PATH_BSHELL, "/bin/ksh") +elif test -f "/usr/bin/ksh"; then + AC_MSG_RESULT(/usr/bin/ksh) + AC_DEFINE(_PATH_BSHELL, "/usr/bin/ksh") +elif test -f "/bin/bash"; then + AC_MSG_RESULT(/bin/bash) + AC_DEFINE(_PATH_BSHELL, "/bin/bash") +elif test -f "/usr/bin/bash"; then + AC_MSG_RESULT(/usr/bin/bash) + AC_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) + AC_DEFINE_UNQUOTED(_PATH_SUDO_LOGFILE, "$with_logpath") +elif test -d "/var/log"; then + AC_MSG_RESULT(/var/log/sudo.log) + AC_DEFINE(_PATH_SUDO_LOGFILE, "/var/log/sudo.log") +elif test -d "/var/adm"; then + AC_MSG_RESULT(/var/adm/sudo.log) + AC_DEFINE(_PATH_SUDO_LOGFILE, "/var/adm/sudo.log") +elif test -d "/usr/adm"; then + AC_MSG_RESULT(/usr/adm/sudo.log) + AC_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) + AC_DEFINE_UNQUOTED(_PATH_SUDO_TIMEDIR, "$with_timedir") +elif test -d "/var/run"; then + AC_MSG_RESULT(/var/run/sudo) + AC_DEFINE(_PATH_SUDO_TIMEDIR, "/var/run/sudo") +elif test -d "/tmp"; then + AC_MSG_RESULT(/tmp/.odus) + AC_DEFINE(_PATH_SUDO_TIMEDIR, "/tmp/.odus") +else + AC_MSG_RESULT(unknown, you will have to set _PATH_SUDO_TIMEDIR by hand) +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) +AC_MSG_RESULT(yes), AC_DEFINE(VOID, char) +AC_MSG_RESULT(no))]) + +dnl +dnl SUDO_CHECK_TYPE(TYPE, DEFAULT) +dnl XXX - should require the check for unistd.h... +dnl +AC_DEFUN(SUDO_CHECK_TYPE, +[AC_REQUIRE([AC_HEADER_STDC])dnl +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL(sudo_cv_type_$1, +[AC_EGREP_CPP($1, [#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif], sudo_cv_type_$1=yes, sudo_cv_type_$1=no)])dnl +AC_MSG_RESULT($sudo_cv_type_$1) +if test $sudo_cv_type_$1 = no; then + AC_DEFINE($1, $2) +fi +]) + +dnl +dnl Check for size_t declation +dnl +AC_DEFUN(SUDO_TYPE_SIZE_T, +[SUDO_CHECK_TYPE(size_t, int)]) + +dnl +dnl Check for ssize_t declation +dnl +AC_DEFUN(SUDO_TYPE_SSIZE_T, +[SUDO_CHECK_TYPE(ssize_t, int)]) + +dnl +dnl Check for dev_t declation +dnl +AC_DEFUN(SUDO_TYPE_DEV_T, +[SUDO_CHECK_TYPE(dev_t, int)]) + +dnl +dnl Check for ino_t declation +dnl +AC_DEFUN(SUDO_TYPE_INO_T, +[SUDO_CHECK_TYPE(ino_t, unsigned int)]) + +dnl +dnl check for POSIX utime() using struct utimbuf +dnl +AC_DEFUN(SUDO_FUNC_UTIME_POSIX, +[AC_MSG_CHECKING(for POSIX utime) +AC_CACHE_VAL(sudo_cv_func_utime_posix, +[rm -f conftestdata; > conftestdata +AC_TRY_RUN([#include <sys/types.h> +#include <sys/time.h> +#include <utime.h> +main() { +struct utimbuf ut; +ut.actime = ut.modtime = time(0); +utime("conftestdata", &ut); +exit(0); +}], sudo_cv_func_utime_posix=yes, sudo_cv_func_utime_posix=no, + sudo_cv_func_utime_posix=no) +rm -f core core.* *.core])dnl +AC_MSG_RESULT($sudo_cv_func_utime_posix) +if test $sudo_cv_func_utime_posix = yes; then + AC_DEFINE(HAVE_UTIME_POSIX) +fi +]) + +dnl +dnl check for working fnmatch(3) +dnl +AC_DEFUN(SUDO_FUNC_FNMATCH, +[AC_MSG_CHECKING(for working fnmatch) +AC_CACHE_VAL(sudo_cv_func_fnmatch, +[rm -f conftestdata; > conftestdata +AC_TRY_RUN([main() { +exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", 0)); +}], 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 sa_len field in struct sockaddr +dnl +AC_DEFUN(SUDO_SOCK_SA_LEN, +[AC_MSG_CHECKING(for sa_len field in struct sockaddr) +AC_CACHE_VAL(sudo_cv_sock_sa_len, +[AC_TRY_RUN([#include <sys/types.h> +#include <sys/socket.h> +main() { +struct sockaddr s; +s.sa_len = 0; +exit(0); +}], sudo_cv_sock_sa_len=yes, sudo_cv_sock_sa_len=no, + sudo_cv_sock_sa_len=no) +rm -f core core.* *.core])dnl +AC_MSG_RESULT($sudo_cv_sock_sa_len) +if test $sudo_cv_sock_sa_len = yes; then + AC_DEFINE(HAVE_SA_LEN) +fi +]) + +dnl +dnl check for max length of uid_t in string representation. +dnl we can't really trust UID_MAX or MAXUID since they may exist +dnl only for backwards compatibility. +dnl +AC_DEFUN(SUDO_UID_T_LEN, +[AC_REQUIRE([AC_TYPE_UID_T]) +AC_MSG_CHECKING(max length of uid_t) +AC_CACHE_VAL(sudo_cv_uid_t_len, +[rm -f conftestdata +AC_TRY_RUN( +[#include <stdio.h> +#include <pwd.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/param.h> +main() { + FILE *f; + char b[1024]; + uid_t u = (uid_t) -1; + + if ((f = fopen("conftestdata", "w")) == NULL) + exit(1); + + (void) sprintf(b, "%u", u); + (void) fprintf(f, "%d\n", strlen(b)); + (void) fclose(f); + exit(0); +}], sudo_cv_uid_t_len=`cat conftestdata`, sudo_cv_uid_t_len=10) +]) +rm -f conftestdata +AC_MSG_RESULT($sudo_cv_uid_t_len) +AC_DEFINE_UNQUOTED(MAX_UID_T_LEN, $sudo_cv_uid_t_len) +]) + +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) +[AC_TRY_RUN([main() {if (sizeof(long long) == sizeof(long)) exit(0); else exit(1);}], AC_DEFINE(LONG_IS_QUAD))] +AC_MSG_RESULT(yes), AC_MSG_RESULT(no))]) diff --git a/usr.bin/sudo/aixcrypt.exp b/usr.bin/sudo/aixcrypt.exp new file mode 100644 index 00000000000..5ee024ef6bb --- /dev/null +++ b/usr.bin/sudo/aixcrypt.exp @@ -0,0 +1,4 @@ +#! +__setkey +__encrypt +__crypt diff --git a/usr.bin/sudo/alloc.c b/usr.bin/sudo/alloc.c new file mode 100644 index 00000000000..01dc36f7be7 --- /dev/null +++ b/usr.bin/sudo/alloc.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +#include <malloc.h> +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include <sys/param.h> +#include <sys/types.h> + +#include "sudo.h" + +#ifndef STDC_HEADERS +#if !defined(__GNUC__) && !defined(HAVE_MALLOC_H) +extern VOID *malloc __P((size_t)); +#endif /* !__GNUC__ && !HAVE_MALLOC_H */ +#endif /* !STDC_HEADERS */ + +extern char **Argv; /* from sudo.c */ + +#ifndef lint +static const char rcsid[] = "$Sudo: alloc.c,v 1.8 1999/07/31 16:19:44 millert Exp $"; +#endif /* lint */ + + +/* + * 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 = 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; +{ + + if ((ptr = ptr ? realloc(ptr, size) : malloc(size)) == 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). + */ +void +#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); + } +} + +/* + * evasprintf() calls vasprintf() and exits with an error if vasprintf() + * returns -1 (out of memory). + */ +void +evasprintf(ret, format, args) + char **ret; + const char *format; + va_list args; +{ + + if (vasprintf(ret, format, args) == -1) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } +} diff --git a/usr.bin/sudo/auth/API b/usr.bin/sudo/auth/API new file mode 100644 index 00000000000..4b336cc8c83 --- /dev/null +++ b/usr.bin/sudo/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/usr.bin/sudo/auth/afs.c b/usr.bin/sudo/auth/afs.c new file mode 100644 index 00000000000..e9f6070ca4b --- /dev/null +++ b/usr.bin/sudo/auth/afs.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include <afs/stds.h> +#include <afs/kautils.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: afs.c,v 1.5 1999/08/14 15:36:45 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/usr.bin/sudo/auth/aix_auth.c b/usr.bin/sudo/auth/aix_auth.c new file mode 100644 index 00000000000..670c0fb6a7c --- /dev/null +++ b/usr.bin/sudo/auth/aix_auth.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: aix_auth.c,v 1.7 1999/10/07 21:21:07 millert Exp $"; +#endif /* lint */ + +int +aixauth_verify(pw, prompt, auth) + struct passwd *pw; + char *prompt; + sudo_auth *auth; +{ + char *message, *pass; + int reenter = 1; + + pass = tgetpass(prompt, def_ival(I_PW_TIMEOUT) * 60, 1); + if (authenticate(pw->pw_name, pass, &reenter, &message) == 0) + return(AUTH_SUCCESS); + else + return(AUTH_FAILURE); +} diff --git a/usr.bin/sudo/auth/dce.c b/usr.bin/sudo/auth/dce.c new file mode 100644 index 00000000000..012467b4836 --- /dev/null +++ b/usr.bin/sudo/auth/dce.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Jeff Earickson + * of Colby College, Waterville, ME <jaearick@colby.edu> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * The code below basically comes from the examples supplied on + * the OSF DCE 1.0.3 manpages for the sec_login routines, with + * enough additional polishing to make the routine work with the + * rest of sudo. + * + * This code is known to work on HP 700 and 800 series systems + * running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE. + * (aka, OSF DCE 1.0.3) or with HP's version 1.4 of DCE (aka, OSF + * DCE 1.1). + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include <dce/rpc.h> +#include <dce/sec_login.h> +#include <dce/dce_error.h> /* required to call dce_error_inq_text routine */ + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: dce.c,v 1.7 1999/08/31 09:39:17 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/usr.bin/sudo/auth/fwtk.c b/usr.bin/sudo/auth/fwtk.c new file mode 100644 index 00000000000..448faf87f97 --- /dev/null +++ b/usr.bin/sudo/auth/fwtk.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include <auth.h> +#include <firewall.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: fwtk.c,v 1.9 1999/10/12 00:53:41 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 */ + 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_PW_TIMEOUT) * 60, 0); + } else if (strncmp(resp, "password", 8) == 0) { + pass = tgetpass(prompt, def_ival(I_PW_TIMEOUT) * 60, 1); + } else { + (void) fprintf(stderr, "%s: %s\n", Argv[0], resp); + return(AUTH_FATAL); + } + if (!pass || *pass == '\0') + nil_pw = 1; /* empty password */ + + /* 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]); + return(AUTH_FATAL); + } + + if (strncmp(resp, "ok", 2) == 0) + return(AUTH_SUCCESS); + + /* Main loop prints "Permission Denied" or insult. */ + if (strcmp(resp, "Permission Denied.") != 0) + fprintf(stderr, "%s: %s\n", Argv[0], resp); + return(AUTH_FAILURE); +} + +int +fwtk_cleanup(pw, auth) + struct passwd *pw; + sudo_auth *auth; +{ + + auth_close(); + return(AUTH_SUCCESS); +} diff --git a/usr.bin/sudo/auth/kerb4.c b/usr.bin/sudo/auth/kerb4.c new file mode 100644 index 00000000000..2791ec9aef5 --- /dev/null +++ b/usr.bin/sudo/auth/kerb4.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> +#include <krb.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: kerb4.c,v 1.5 1999/08/14 15:36:46 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/usr.bin/sudo/auth/kerb5.c b/usr.bin/sudo/auth/kerb5.c new file mode 100644 index 00000000000..f9adb3dcaea --- /dev/null +++ b/usr.bin/sudo/auth/kerb5.c @@ -0,0 +1,312 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Frank Cusack + * <fcusack@fcusack.com>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> +#include <krb5.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: kerb5.c,v 1.10 1999/10/13 02:34:55 millert Exp $"; +#endif /* lint */ + +static int verify_krb_v5_tgt __P((krb5_context, krb5_ccache, char *)); +static struct _sudo_krb5_data { + krb5_context sudo_context; + krb5_principal princ; + krb5_ccache ccache; +} sudo_krb5_data = { NULL, NULL, NULL }; +typedef struct _sudo_krb5_data *sudo_krb5_datap; + +extern krb5_cc_ops krb5_mcc_ops; + +int +kerb5_init(pw, promptp, auth) + struct passwd *pw; + char **promptp; + sudo_auth *auth; +{ + krb5_context sudo_context; + krb5_ccache ccache; + krb5_principal princ; + krb5_error_code error; + char cache_name[64]; + char *pname; + + auth->data = (VOID *) &sudo_krb5_data; /* Stash all our data here */ + + if (error = krb5_init_context(&(sudo_krb5_data.sudo_context))) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to initialize context: %s", auth->name, + error_message(error)); + return(AUTH_FAILURE); + } + sudo_context = sudo_krb5_data.sudo_context; + + if (error = krb5_parse_name(sudo_context, pw->pw_name, + &(sudo_krb5_data.princ))) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to parse '%s': %s", auth->name, pw->pw_name, + error_message(error)); + return(AUTH_FAILURE); + } + princ = sudo_krb5_data.princ; + + /* + * Really, we need to tell the caller not to prompt for password. + * The API does not currently provide this unless the auth is standalone. + */ +#if 1 + if (error = krb5_unparse_name(sudo_context, princ, &pname)) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to unparse princ ('%s'): %s", auth->name, + pw->pw_name, error_message(error)); + return(AUTH_FAILURE); + } + + /* Only rewrite prompt if user didn't specify their own. */ + /*if (!strcmp(prompt, PASSPROMPT)) { */ + easprintf(promptp, "Password for %s: ", pname); + /*}*/ + free(pname); +#endif + + /* For CNS compatibility */ + if (error = krb5_cc_register(sudo_context, &krb5_mcc_ops, FALSE)) { + if (error != KRB5_CC_TYPE_EXISTS) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to use Memory ccache: %s", auth->name, + error_message(error)); + return(AUTH_FAILURE); + } + } + + (void) snprintf(cache_name, sizeof(cache_name), "MEMORY:sudocc_%ld", + (long) getpid()); + if (error = krb5_cc_resolve(sudo_context, cache_name, + &(sudo_krb5_data.ccache))) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to resolve ccache: %s", auth->name, + error_message(error)); + return(AUTH_FAILURE); + } + ccache = sudo_krb5_data.ccache; + + if (error = krb5_cc_initialize(sudo_context, ccache, princ)) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to initialize ccache: %s", auth->name, + error_message(error)); + return(AUTH_FAILURE); + } + + return(AUTH_SUCCESS); +} + +int +kerb5_verify(pw, pass, auth) + struct passwd *pw; + char *pass; + sudo_auth *auth; +{ + krb5_context sudo_context; + krb5_principal princ; + krb5_ccache ccache; + krb5_creds creds; + krb5_error_code error; + krb5_get_init_creds_opt opts; + char cache_name[64]; + + sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context; + princ = ((sudo_krb5_datap) auth->data)->princ; + ccache = ((sudo_krb5_datap) auth->data)->ccache; + + /* Initialize options to defaults */ + krb5_get_init_creds_opt_init(&opts); + + /* Note that we always obtain a new TGT to verify the user */ + if (error = krb5_get_init_creds_password(sudo_context, &creds, princ, + pass, krb5_prompter_posix, + NULL, 0, NULL, &opts)) { + if (error == KRB5KRB_AP_ERR_BAD_INTEGRITY) /* Bad password */ + return(AUTH_FAILURE); + /* Some other error */ + log_error(NO_EXIT|NO_MAIL, + "%s: unable to get credentials: %s", auth->name, + error_message(error)); + return(AUTH_FAILURE); + } + + /* Stash the TGT so we can verify it. */ + if (error = krb5_cc_store_cred(sudo_context, ccache, &creds)) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to store credentials: %s", auth->name, + error_message(error)); + } else { + error = verify_krb_v5_tgt(sudo_context, ccache, auth->name); + } + + krb5_free_cred_contents(sudo_context, &creds); + return (error ? AUTH_FAILURE : AUTH_SUCCESS); +} + +int +kerb5_cleanup(pw, auth) + struct passwd *pw; + sudo_auth *auth; +{ + krb5_context sudo_context; + krb5_principal princ; + krb5_ccache ccache; + + sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context; + princ = ((sudo_krb5_datap) auth->data)->princ; + ccache = ((sudo_krb5_datap) auth->data)->ccache; + + if (sudo_context) { + if (ccache) + krb5_cc_destroy(sudo_context, ccache); + if (princ) + krb5_free_principal(sudo_context, princ); + krb5_free_context(sudo_context); + } + + return(AUTH_SUCCESS); +} + +/* + * This routine with some modification is from the MIT V5B6 appl/bsd/login.c + * + * Verify the Kerberos ticket-granting ticket just retrieved for the + * user. If the Kerberos server doesn't respond, assume the user is + * trying to fake us out (since we DID just get a TGT from what is + * supposedly our KDC). If the host/<host> service is unknown (i.e., + * the local keytab doesn't have it), return success but log the error. + * + * This needs to run as root (to read the host service ticket). + * + * Returns 0 for successful authentication, non-zero for failure. + */ +static int +verify_krb_v5_tgt(sudo_context, ccache, auth_name) + krb5_context sudo_context; + krb5_ccache ccache; + char *auth_name; /* For error reporting */ +{ + char phost[BUFSIZ]; + krb5_error_code error; + krb5_principal princ; + krb5_data packet; + krb5_keyblock *keyblock = 0; + krb5_auth_context auth_context = NULL; + + packet.data = 0; + + /* + * Get the server principal for the local host. + * (Use defaults of "host" and canonicalized local name.) + */ + if (error = krb5_sname_to_principal(sudo_context, NULL, NULL, + KRB5_NT_SRV_HST, &princ)) { + log_error(NO_EXIT|NO_MAIL, + "%s: unable to get host principal: %s", auth_name, + error_message(error)); + return(-1); + } + + /* Extract the name directly. Yow. */ + strncpy(phost, krb5_princ_component(sudo_context, princ, 1)->data, + sizeof(phost) - 1); + phost[sizeof(phost) - 1] = '\0'; + + /* + * Do we have host/<host> keys? + * (use default keytab, kvno IGNORE_VNO to get the first match, + * and enctype is currently ignored anyhow.) + */ + if (error = krb5_kt_read_service_key(sudo_context, NULL, princ, 0, + ENCTYPE_DES_CBC_MD5, &keyblock)) { + /* Keytab or service key does not exist. */ + log_error(NO_EXIT, + "%s: host service key not found: %s", auth_name, + error_message(error)); + error = 0; + goto cleanup; + } + if (keyblock) + krb5_free_keyblock(sudo_context, keyblock); + + /* Talk to the kdc and construct the ticket. */ + error = krb5_mk_req(sudo_context, &auth_context, 0, "host", phost, + NULL, ccache, &packet); + if (auth_context) { + krb5_auth_con_free(sudo_context, auth_context); + auth_context = NULL; /* setup for rd_req */ + } + + /* Try to use the ticket. */ + if (!error) + error = krb5_rd_req(sudo_context, &auth_context, &packet, princ, + NULL, NULL, NULL); +cleanup: + if (packet.data) + krb5_free_data_contents(sudo_context, &packet); + krb5_free_principal(sudo_context, princ); + + if (error) + log_error(NO_EXIT|NO_MAIL, + "%s: Cannot verify TGT! Possible attack!: %s", auth_name, + error_message(error)); + return(error); +} diff --git a/usr.bin/sudo/auth/pam.c b/usr.bin/sudo/auth/pam.c new file mode 100644 index 00000000000..623dcab742d --- /dev/null +++ b/usr.bin/sudo/auth/pam.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include <security/pam_appl.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: pam.c,v 1.10 1999/10/07 21:21:07 millert Exp $"; +#endif /* lint */ + +static int sudo_conv __P((int, PAM_CONST struct pam_message **, + struct pam_response **, VOID *)); +static char *def_prompt; + +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); + } + auth->data = (VOID *) pamh; + return(AUTH_SUCCESS); +} + +int +pam_verify(pw, prompt, auth) + struct passwd *pw; + char *prompt; + sudo_auth *auth; +{ + pam_handle_t *pamh = (pam_handle_t *) auth->data; + + def_prompt = prompt; /* for sudo_conv */ + + /* PAM_SILENT prevents error messages from going to syslog(3) */ + if (pam_authenticate(pamh, PAM_SILENT) == PAM_SUCCESS) + return(AUTH_SUCCESS); + else + return(AUTH_FAILURE); +} + +int +pam_cleanup(pw, auth) + struct passwd *pw; + sudo_auth *auth; +{ + pam_handle_t *pamh = (pam_handle_t *) auth->data; + + if (pam_end(pamh, (auth->status == AUTH_SUCCESS)) == PAM_SUCCESS) + return(AUTH_SUCCESS); + else + return(AUTH_FAILURE); +} + +/* + * ``Conversation function'' for PAM. + */ +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; + struct pam_message *pm; + char *p = def_prompt; + int echo = 0; + extern int nil_pw; + + if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL) + return(PAM_CONV_ERR); + (void) memset((VOID *)*response, 0, num_msg * sizeof(struct pam_response)); + + for (pr = *response, pm = *msg; num_msg--; pr++, pm++) { + switch (pm->msg_style) { + case PAM_PROMPT_ECHO_ON: + echo = 1; + case PAM_PROMPT_ECHO_OFF: + /* Override default prompt for unix auth */ + if (strcmp(p, "Password: ") && strcmp(p, "Password:")) + p = (char *) pm->msg; + pr->resp = estrdup((char *) tgetpass(p, + def_ival(I_PW_TIMEOUT) * 60, !echo)); + if (*pr->resp == '\0') + nil_pw = 1; /* empty password */ + 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: + /* Something odd happened */ + /* XXX - should free non-NULL response members */ + free(*response); + *response = NULL; + return(PAM_CONV_ERR); + break; + } + } + + return(PAM_SUCCESS); +} diff --git a/usr.bin/sudo/auth/passwd.c b/usr.bin/sudo/auth/passwd.c new file mode 100644 index 00000000000..62f3a126584 --- /dev/null +++ b/usr.bin/sudo/auth/passwd.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: passwd.c,v 1.4 1999/08/14 15:36:46 millert Exp $"; +#endif /* lint */ + +int +passwd_verify(pw, pass, auth) + struct passwd *pw; + char *pass; + sudo_auth *auth; +{ + +#ifdef HAVE_GETAUTHUID + /* Ultrix shadow passwords may use crypt16() */ + if (!strcmp(pw->pw_passwd, (char *) crypt16(pass, pw->pw_passwd))) + return(AUTH_SUCCESS); +#endif /* HAVE_GETAUTHUID */ + + /* Normal UN*X password check */ + if (!strcmp(pw->pw_passwd, (char *) crypt(pass, pw->pw_passwd))) + return(AUTH_SUCCESS); + + return(AUTH_FAILURE); +} diff --git a/usr.bin/sudo/auth/rfc1938.c b/usr.bin/sudo/auth/rfc1938.c new file mode 100644 index 00000000000..bad20d24dca --- /dev/null +++ b/usr.bin/sudo/auth/rfc1938.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#if defined(HAVE_SKEY) +#include <skey.h> +#define RFC1938 skey +#define rfc1938challenge skeychallenge +#define rfc1938verify skeyverify +#elif defined(HAVE_OPIE) +#include <opie.h> +#define RFC1938 opie +#define rfc1938challenge opiechallenge +#define rfc1938verify opieverify +#endif + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: rfc1938.c,v 1.8 1999/10/07 21:21:07 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/usr.bin/sudo/auth/secureware.c b/usr.bin/sudo/auth/secureware.c new file mode 100644 index 00000000000..ddba29fbc9b --- /dev/null +++ b/usr.bin/sudo/auth/secureware.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> +#ifdef __hpux +# undef MAXINT +# include <hpsecurity.h> +#else +# include <sys/security.h> +#endif /* __hpux */ +#include <prot.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: secureware.c,v 1.7 1999/08/22 09:59:28 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/usr.bin/sudo/auth/securid.c b/usr.bin/sudo/auth/securid.c new file mode 100644 index 00000000000..dff22632cca --- /dev/null +++ b/usr.bin/sudo/auth/securid.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Giles Todd + * <giles@gt.demon.co.uk>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> + +#include <sdi_athd.h> +#include <sdconf.h> +#include <sdacmvls.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: securid.c,v 1.5 1999/08/14 15:36:46 millert Exp $"; +#endif /* lint */ + +union config_record configure; + +int +securid_init(pw, promptp, auth) + struct passwd *pw; + char **promptp; + sudo_auth *auth; +{ + + creadcfg(); /* Only read config file once */ + return(AUTH_SUCCESS); +} + +int +securid_setup(pw, promptp, auth) + struct passwd *pw; + char **promptp; + sudo_auth *auth; +{ + static SD_CLIENT sd_dat; /* SecurID data block */ + + /* Re-initialize SecurID every time. */ + auth->data = (VOID *) &sd_dat; + if (sd_init(sd) == 0) + 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; + + if (sd_auth(sd) == ACM_OK) + return(AUTH_SUCCESS); + else + return(AUTH_FAILURE); +} diff --git a/usr.bin/sudo/auth/sia.c b/usr.bin/sudo/auth/sia.c new file mode 100644 index 00000000000..d41263c9603 --- /dev/null +++ b/usr.bin/sudo/auth/sia.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Spider Boardman + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> +#include <siad.h> + +#include "sudo.h" +#include "sudo_auth.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: sia.c,v 1.8 1999/10/07 21:21:07 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_PW_TIMEOUT) * 60) + timeout = def_ival(I_PW_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/usr.bin/sudo/auth/sudo_auth.c b/usr.bin/sudo/auth/sudo_auth.c new file mode 100644 index 00000000000..74a20ce509b --- /dev/null +++ b/usr.bin/sudo/auth/sudo_auth.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/param.h> +#include <sys/types.h> +#include <pwd.h> +#include <time.h> + +#include "sudo.h" +#include "sudo_auth.h" +#include "insults.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: sudo_auth.c,v 1.15 1999/10/13 02:34:55 millert Exp $"; +#endif /* lint */ + +sudo_auth auth_switch[] = { +#ifdef AUTH_STANDALONE + AUTH_STANDALONE +#else +# ifndef WITHOUT_PASSWD + AUTH_ENTRY(0, "passwd", NULL, NULL, passwd_verify, NULL) +# endif +# if defined(HAVE_SECUREWARE) && !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(prompt) + char *prompt; +{ + short counter = def_ival(I_PW_TRIES) + 1; + short success = AUTH_FAILURE; + short status; + char *p; + sudo_auth *auth; + + /* 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)(sudo_user.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)(sudo_user.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_PW_TIMEOUT) * 60, 1); + if (!p || *p == '\0') + nil_pw = 1; +#endif /* AUTH_STANDALONE */ + + /* Call authentication functions. */ + for (auth = auth_switch; auth->name; auth++) { + if (!IS_CONFIGURED(auth)) + continue; + + if (NEEDS_USER(auth)) + set_perms(PERM_USER, 0); + + success = auth->status = (auth->verify)(sudo_user.pw, p, auth); + + if (NEEDS_USER(auth)) + set_perms(PERM_ROOT, 0); + + if (auth->status != AUTH_FAILURE) + goto cleanup; + } +#ifndef AUTH_STANDALONE + (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_PW_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)(sudo_user.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: + return; + case AUTH_FAILURE: + log_error(NO_MAIL, "%d incorrect password attempt%s", + def_ival(I_PW_TRIES) - counter, + (def_ival(I_PW_TRIES) - counter == 1) ? "" : "s"); + case AUTH_FATAL: + exit(1); + } +} + +void +pass_warn(fp) + FILE *fp; +{ + +#ifdef USE_INSULTS + (void) fprintf(fp, "%s\n", INSULT); +#else + (void) fprintf(fp, "%s\n", def_str(I_BADPASS_MSG)); +#endif /* USE_INSULTS */ +} + +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/usr.bin/sudo/auth/sudo_auth.h b/usr.bin/sudo/auth/sudo_auth.h new file mode 100644 index 00000000000..0b9486d8254 --- /dev/null +++ b/usr.bin/sudo/auth/sudo_auth.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: sudo_auth.h,v 1.15 1999/10/13 02:34:55 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 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)); + +/* Prototypes for normal methods */ +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) +#endif + +#endif /* SUDO_AUTH_H */ diff --git a/usr.bin/sudo/check.c b/usr.bin/sudo/check.c new file mode 100644 index 00000000000..df100afc016 --- /dev/null +++ b/usr.bin/sudo/check.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <time.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <pwd.h> +#include <grp.h> + +#include "sudo.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: check.c,v 1.192 1999/10/07 21:20:55 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 + + int user_is_exempt __P((void)); +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(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; *p; p++) { + if (lastchar == '%' && (*p == 'h' || *p == 'u' || *p == '%')) { + /* substiture 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_GRP)) + return(FALSE); + + if (!(grp = getgrnam(def_str(I_EXEMPT_GRP)))) + return(FALSE); + + if (getgid() == 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 = def_str(I_TIMESTAMPDIR); + + if (def_flag(I_TTY_TICKETS)) { + char *p; + + if ((p = strrchr(user_tty, '/'))) + p++; + else + p = user_tty; + if (strlen(dirparent) + strlen(user_name) + strlen(p) + 3 > MAXPATHLEN) + log_error(0, "timestamp path too long: %s/%s/%s", dirparent, + user_name, p); + easprintf(timestampdir, "%s/%s", dirparent, user_name); + easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p); + } else { + if (strlen(dirparent) + strlen(user_name) + 2 > MAXPATHLEN) + log_error(0, "timestamp path too long: %s/%s", dirparent, user_name); + easprintf(timestampdir, "%s/%s", dirparent, user_name); + *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) { + now = time(NULL); + if (def_ival(I_TS_TIMEOUT) && + now - sb.st_mtime < 60 * def_ival(I_TS_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_TS_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) { + log_error(NO_EXIT, "can't remove %s (%s), will reset to epoch", + strerror(errno), ts); + 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/usr.bin/sudo/compat.h b/usr.bin/sudo/compat.h new file mode 100644 index 00000000000..bb6e4bc35fd --- /dev/null +++ b/usr.bin/sudo/compat.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: compat.h,v 1.54 1999/10/08 01:12:49 millert Exp $ + */ + +#ifndef _SUDO_COMPAT_H +#define _SUDO_COMPAT_H + +/* + * Macros that may be missing on some Operating Systems + */ + +/* Deal with ANSI stuff reasonably. */ +#ifndef __P +# if defined (__cplusplus) || defined (__STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif +#endif /* __P */ + +/* + * Some systems (ie ISC V/386) do not define MAXPATHLEN even in param.h + */ +#ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +#endif + +/* + * Some systems do not define MAXHOSTNAMELEN. + */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif + +/* + * 4.2BSD lacks FD_* macros (we only use FD_SET and FD_ZERO) + */ +#ifndef FD_SETSIZE +# define FD_SET(fd, fds) ((fds) -> fds_bits[0] |= (1 << (fd))) +# define FD_ZERO(fds) ((fds) -> fds_bits[0] = 0) +#endif /* !FD_SETSIZE */ + +/* + * Posix versions for those without... + */ +#ifndef _S_IFMT +# define _S_IFMT S_IFMT +#endif /* _S_IFMT */ +#ifndef _S_IFREG +# define _S_IFREG S_IFREG +#endif /* _S_IFREG */ +#ifndef _S_IFDIR +# define _S_IFDIR S_IFDIR +#endif /* _S_IFDIR */ +#ifndef _S_IFLNK +# define _S_IFLNK S_IFLNK +#endif /* _S_IFLNK */ +#ifndef S_ISREG +# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif /* S_ISREG */ +#ifndef S_ISDIR +# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif /* S_ISDIR */ + +/* + * Some OS's may not have this. + */ +#ifndef S_IRWXU +# define S_IRWXU 0000700 /* rwx for owner */ +#endif /* S_IRWXU */ + +/* + * In case this is not defined in <sys/types.h> or <sys/select.h> + */ +#ifndef howmany +# define howmany(x, y) (((x) + ((y) - 1)) / (y)) +#endif + +/* + * These should be defined in <unistd.h> but not everyone has them. + */ +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +/* + * These should be defined in <unistd.h> but not everyone has them. + */ +#ifndef SEEK_SET +# define SEEK_SET 0 +#endif +#ifndef SEEK_CUR +# define SEEK_CUR 1 +#endif +#ifndef SEEK_END +# define SEEK_END 2 +#endif + +/* + * BSD defines these in <sys/param.h> but others may not. + */ +#ifndef MIN +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +/* + * Emulate seteuid() for HP-UX via setresuid(2) and seteuid(2) for others. + */ +#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 */ + +/* + * 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 */ + +#endif /* _SUDO_COMPAT_H */ diff --git a/usr.bin/sudo/config.guess b/usr.bin/sudo/config.guess new file mode 100644 index 00000000000..c0326b5ca2c --- /dev/null +++ b/usr.bin/sudo/config.guess @@ -0,0 +1,693 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner <bothner@cygnus.com>. +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# 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 system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +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 + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + # 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. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-cbm-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*|MIS*: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 ;; + 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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-atari-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-sun-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-apple-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 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #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 + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + 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 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${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 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm 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:*:4) + if /usr/sbin/lsattr -EHl proc0 | 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=4.${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 NetBSD 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/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm 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 ;; + 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 ;; + 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} + 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/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp3[0-9][05]:OpenBSD:*:*) + echo m68k-hp-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`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 i386-pc-cygwin32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin32 + 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 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then + echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then + echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then + echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then + echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then + echo "powerpc-unknown-linux-gnu" ; exit 0 + elif test "${UNAME_MACHINE}" = "alpha" ; then + echo alpha-unknown-linux-gnu ; exit 0 + elif test "${UNAME_MACHINE}" = "sparc" ; then + echo sparc-unknown-linux-gnu ; exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us + # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. + test ! -d /usr/lib/ldscripts/. \ + && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + # Determine whether the default compiler is a.out or elf + cat >dummy.c <<EOF +main(argc, argv) +int argc; +char *argv[]; +{ +#ifdef __ELF__ + printf ("%s-pc-linux-gnu\n", argv[1]); +#else + printf ("%s-pc-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# 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. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + 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]??,*:*: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.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:* | RM*:ReliantUNIX-*:*:*) + 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 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%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) + printf ("vax-dec-bsd\n"); exit (0); +#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 + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm 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 + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/usr.bin/sudo/config.h.in b/usr.bin/sudo/config.h.in new file mode 100644 index 00000000000..4511cb086a4 --- /dev/null +++ b/usr.bin/sudo/config.h.in @@ -0,0 +1,521 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: config.h.in,v 1.139 1999/11/04 19:01:08 millert Exp $ + */ + +/* + * config.h -- You shouldn't edit this by hand unless you are + * NOT using configure. + */ + +#ifndef _SUDO_CONFIG_H +#define _SUDO_CONFIG_H + +/* New ANSI-style OS defs. */ +#if defined(hpux) && !defined(__hpux) +# define __hpux 1 +#endif /* hpux */ + +#if defined(convex) && !defined(__convex__) +# define __convex__ 1 +#endif /* convex */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +#undef _ALL_SOURCE +#endif + +/* Define if on ConvexOs. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _CONVEX_SOURCE +#undef _CONVEX_SOURCE +#endif + +/* Define if needed to get POSIX functionality. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _POSIX_SOURCE +#undef _POSIX_SOURCE +#endif + +/* Define if needed to get GNU extensions on Linux. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _GNU_SOURCE +#undef _GNU_SOURCE +#endif + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef uid_t + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef gid_t + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef mode_t + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +#undef size_t + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef ssize_t + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef dev_t + +/* Define to `unsigned int' if <sys/types.h> doesn't define. */ +#undef ino_t + +/* Define to be nil if C compiler doesn't support "const." */ +#undef const + +/* Define if your compiler supports the "long long" type. */ +#undef HAVE_LONG_LONG + +/* Define if sizeof(long) == sizeof(long long). */ +#undef LONG_IS_QUAD + +/* Solaris doesn't use const qualifiers in PAM. */ +#ifdef sun +#define PAM_CONST +#else +#define PAM_CONST const +#endif + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you want to use execv() instead of execvp(). */ +#undef USE_EXECV + +/* Define if you have POSIX signals. */ +#undef HAVE_SIGACTION +#ifdef HAVE_SIGACTION +# define POSIX_SIGNALS +#endif /* HAVE_SIGACTION */ + +/* Define if you have tzset(3). */ +#undef HAVE_TZSET + +/* Define if you have getcwd(3). */ +#undef HAVE_GETCWD + +/* Define if you have fnmatch(3). */ +#undef HAVE_FNMATCH + +/* Define if you have lsearch(3). */ +#undef HAVE_LSEARCH + +/* Define if you have strchr(3). */ +#undef HAVE_STRCHR +#if !defined(HAVE_STRCHR) && !defined(strchr) +# define strchr index +#endif + +/* Define if you have strrchr(3). */ +#undef HAVE_STRRCHR +#if !defined(HAVE_STRRCHR) && !defined(strrchr) +# define strrchr rindex +#endif + +/* Define if you have memchr(3). */ +#undef HAVE_MEMCHR + +/* Define if you have memcpy(3). */ +#undef HAVE_MEMCPY +#if !defined(HAVE_MEMCPY) && !defined(memcpy) +# define memcpy(D, S, L) (bcopy(S, D, L)) +#endif + +/* Define if you have memset(3). */ +#undef HAVE_MEMSET +#if !defined(HAVE_MEMSET) && !defined(memset) +# define memset(S, X, N) (bzero(S, N)) +#endif + +/* Define if you have sysconf(3c). */ +#undef HAVE_SYSCONF + +/* Define if you have putenv(3). */ +#undef HAVE_PUTENV + +/* Define if you have setenv(3). */ +#undef HAVE_SETENV + +/* Define if you have strcasecmp(3). */ +#undef HAVE_STRCASECMP + +/* Define if you have tcgetattr(3). */ +#undef HAVE_TCGETATTR + +/* Define if you have innetgr(3). */ +#undef HAVE_INNETGR + +/* Define if you have getdomainname(2). */ +#undef HAVE_GETDOMAINNAME + +/* Define if you have utime(2). */ +#undef HAVE_UTIME + +/* Define if you have a POSIX utime() (uses struct utimbuf) */ +#undef HAVE_UTIME_POSIX + +/* Define if you have bigcrypt(3). */ +#undef HAVE_BIGCRYPT + +/* Define if you have set_auth_parameters(3). */ +#undef HAVE_SET_AUTH_PARAMETERS + +/* Define if you have initprivs(3). */ +#undef HAVE_INITPRIVS + +/* Define if you have dispcrypt(3). */ +#undef HAVE_DISPCRYPT + +/* Define if you have getspnam(3). [SVR4-style shadow passwords] */ +#undef HAVE_GETSPNAM + +/* Define if you have getprpwnam(3). [SecureWare-style shadow passwords] */ +#undef HAVE_GETPRPWNAM + +/* Define if you have iscomsec(3). [HP-UX >= 10.x check for shadow enabled] */ +#undef HAVE_ISCOMSEC + +/* Define if you have getspwuid(3). [HP-UX <= 9.X shadow passwords] */ +#undef HAVE_GETSPWUID + +/* Define if you have getpwanam(3). [SunOS 4.x shadow passwords] */ +#undef HAVE_GETPWANAM + +/* Define if you have issecure(3). [SunOS 4.x check for shadow enabled] */ +#undef HAVE_ISSECURE + +/* Define if you have getauthuid(3). [ULTRIX 4.x shadow passwords] */ +#undef HAVE_GETAUTHUID + +/* Define if you have seteuid(3). */ +#undef HAVE_SETEUID + +/* Define if you have waitpid(2). */ +#undef HAVE_WAITPID + +/* Define if you have wait3(2). */ +#undef HAVE_WAIT3 + +/* Define if you have strerror(3). */ +#undef HAVE_STRERROR + +/* Define if you have lockf(3). */ +#undef HAVE_LOCKF + +/* Define if you have flock(2). */ +#undef HAVE_FLOCK + +/* Define if you have ftruncate(2). */ +#undef HAVE_FTRUNCATE + +/* Define if you have setrlimit(2). */ +#undef HAVE_SETRLIMIT + +/* Define if you have strftime(2). */ +#undef HAVE_STRFTIME + +/* Define if you have snprintf(3). */ +#undef HAVE_SNPRINTF + +/* Define if you have vsnprintf(3). */ +#undef HAVE_VSNPRINTF + +/* Define if you have asprintf(3). */ +#undef HAVE_ASPRINTF + +/* Define if you have vasprintf(3). */ +#undef HAVE_VASPRINTF + +/* Define if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the <alloca.h> header file. */ +#undef HAVE_ALLOCA_H + +/* Define if you have the <paths.h> header file. */ +#undef HAVE_PATHS_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <strings.h> header file but no <string.h>. */ +#ifndef HAVE_STRING_H +#undef HAVE_STRINGS_H +#endif /* !HAVE_STRING_H */ + +/* Define your flavor of dir entry header file. */ +#undef HAVE_DIRENT_H +#undef HAVE_SYS_NDIR_H +#undef HAVE_SYS_DIR_H +#undef HAVE_NDIR_H + +/* Define if you have the <utime.h> header file. */ +#undef HAVE_UTIME_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the <fnmatch.h> header file. */ +#undef HAVE_FNMATCH_H + +/* Define if you have the <netgroup.h> header file. */ +#undef HAVE_NETGROUP_H + +/* Define if you have the <termio.h> header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the <termios.h> header file and tcgetattr(3). */ +#ifdef HAVE_TCGETATTR +#undef HAVE_TERMIOS_H +#endif /* HAVE_TCGETATTR */ + +/* Define if you have the <sys/sockio.h> header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define if you have the <sys/bsdtypes.h> header file. */ +#undef HAVE_SYS_BSDTYPES_H + +/* Define if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if your struct sockadr has an sa_len field. */ +#undef HAVE_SA_LEN + +/* Define if you want visudo to honor EDITOR and VISUAL env variables. */ +#undef ENV_EDITOR + +/* Define to avoid using the passwd/shadow file for authentication. */ +#undef WITHOUT_PASSWD + +/* Define to void if your C compiler fully groks void, else char */ +#undef VOID + +/* Define to the max length of a uid_t in string context (excluding the NUL) */ +#undef MAX_UID_T_LEN + +/* Define if your syslog(3) does not guarantee the message will be logged */ +/* and syslog(3) returns non-zero to denote failure */ +#undef BROKEN_SYSLOG + +/* Define if the code in interfaces.c does not compile for you. */ +#undef STUB_LOAD_INTERFACES + +/* + * Defaults for options. These may be overridden via a "Defaults" line + * in the sudoers file. + */ + +/* Define if you a different ticket file for each tty. */ +#undef USE_TTY_TICKETS + +/* Define if you want to insult the user for entering an incorrect password. */ +#undef USE_INSULTS + +/* Define if you want the insults from the "classic" version sudo. */ +#undef CLASSIC_INSULTS + +/* Define if you want 2001-like insults. */ +#undef HAL_INSULTS + +/* Define if you want insults from the "Goon Show" */ +#undef GOONS_INSULTS + +/* Define if you want insults culled from the twisted minds of CSOps. */ +#undef CSOPS_INSULTS + +/* Define to override the user's path with a builtin one. */ +#undef SECURE_PATH + +/* Define if you want a two line OTP (skey/opie) prompt. */ +#undef LONG_OTP_PROMPT + +/* The umask that the root-run prog should use */ +#undef SUDO_UMASK + +/* Define if you want the hostname to be entered into the log file */ +#undef HOST_IN_LOG + +/* Define to be the number of minutes before sudo asks for passwd again. */ +#undef TIMEOUT + +/* Define to be the passwd prompt timeout (in minutes). */ +#undef PASSWORD_TIMEOUT + +/* Define to be the number of tries the user gets to enter the passwd. */ +#undef TRIES_FOR_PASSWORD + +/* Define to be the user sudo should run commands as by default. */ +#undef RUNAS_DEFAULT + +/* Define if you want to require fully qualified hosts in sudoers. */ +#undef FQDN + +/* If defined, users in this group need not enter a passwd (ie "sudo"). */ +#undef EXEMPTGROUP + +/* Define to the path of the editor visudo should use. */ +#undef EDITOR + +/* Define if root should not be allowed to use sudo. */ +#undef NO_ROOT_SUDO + +/* Define to be the user that gets sudo mail. */ +#undef MAILTO + +/* Define to be the subject of the mail sent to MAILTO by sudo. */ +#undef MAILSUBJECT + +/* Define to be the message given for a bad password. */ +#undef INCORRECT_PASSWORD + +/* Define to be the password prompt. */ +#undef PASSPROMPT + +/* Define to SLOG_SYSLOG, SLOG_FILE, or SLOG_BOTH */ +#undef LOGGING + +/* Define to be the syslog facility to use. */ +#undef LOGFAC + +/* Define to be the syslog priority to use for successful attemps. */ +#undef PRI_SUCCESS + +/* Define to be the syslog priority to use for unsuccessful attemps/errors. */ +#undef PRI_FAILURE + +/* Define to be the max chars per log line (for line wrapping). */ +#undef MAXLOGFILELEN + +/* Define if you want to ignore '.' and '' in $PATH */ +#undef IGNORE_DOT_PATH + +/* Define if you want "command not allowed" instead of "command not found" */ +#undef DONT_LEAK_PATH_INFO + +/* Define if you don't want users to get the lecture the first they user sudo */ +#undef NO_LECTURE + +/* Define SEND_MAIL_WHEN_NO_USER to send mail when user not in sudoers file */ +#undef SEND_MAIL_WHEN_NO_USER + +/* Define SEND_MAIL_WHEN_NO_HOST to send mail when not allowed on this host */ +#undef SEND_MAIL_WHEN_NO_HOST + +/* Define SEND_MAIL_WHEN_NOT_OK to send mail when not allowed to run command */ +#undef SEND_MAIL_WHEN_NOT_OK + +/* 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 in shell mode. */ +#undef SHELL_SETS_HOME + +/* Define if you don't want sudo to prompt for a password by default. */ +#undef NO_AUTHENTICATION + + +/* + * Authentication methods. + */ + +/* Define if you use S/Key. */ +#undef HAVE_SKEY + +/* Define if you use NRL OPIE. */ +#undef HAVE_OPIE + +/* Define if you use SecurID. */ +#undef HAVE_SECURID + +/* Define if you use AIX general authentication. */ +#undef HAVE_AUTHENTICATE + +/* Define if you use Kerberos IV or Kerberos V < 1.1. */ +#undef HAVE_KERB4 + +/* Define if you use Kerberos V version 1.1 or higher. */ +#undef HAVE_KERB5 + +/* Define if you use SIA. */ +#undef HAVE_SIA + +/* Define if you use PAM. */ +#undef HAVE_PAM + +/* Define if you use AFS. */ +#undef HAVE_AFS + +/* Define if you use OSF DCE. */ +#undef HAVE_DCE + +/* Define if you use the FWTK authsrv daemon. */ +#undef HAVE_FWTK + + +/********** You probably don't want to modify anything below here ***********/ + +/* + * 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 + +#ifdef USE_EXECV +# define EXEC execv +#else +# define EXEC execvp +#endif /* USE_EXECV */ + +#ifdef __svr4__ +# define BSD_COMP +#endif /* __svr4__ */ + +#endif /* _SUDO_CONFIG_H */ diff --git a/usr.bin/sudo/config.sub b/usr.bin/sudo/config.sub new file mode 100644 index 00000000000..1c16182fd45 --- /dev/null +++ b/usr.bin/sudo/config.sub @@ -0,0 +1,931 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. +# 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. + +# 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. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +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 + linux-gnu*) + 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) + os= + 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/'` + ;; + -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 + ;; +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 | m68k | m68000 | m88k | ns32k | arm \ + | arme[lb] | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | i370 | sh \ + | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc | sparclet | sparclite | sparc64) + basic_machine=$basic_machine-unknown + ;; + # 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[3456]86) + 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. + vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + 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-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + 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 + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + 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 + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-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 + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[3456]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[3456]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[3456]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[3456]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + 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 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + 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 + ;; + 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 + ;; + np1) + basic_machine=np1-gould + ;; + 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) + basic_machine=i586-intel + ;; + pentiumpro | p6) + basic_machine=i686-intel + ;; + pentium-* | p5-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-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 + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + 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 + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + 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 + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + 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. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + 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 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -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* \ + | -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* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -linux-gnu* | -uxpv*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -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|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # 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*) + ;; + -xenix) + os=-xenix + ;; + -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*-semi) + os=-aout + ;; + 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 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-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 + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + 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 + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/usr.bin/sudo/configure b/usr.bin/sudo/configure new file mode 100644 index 00000000000..84762f38090 --- /dev/null +++ b/usr.bin/sudo/configure @@ -0,0 +1,8253 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-otp-only deprecated" +ac_help="$ac_help + --with-alertmail deprecated" +ac_help="$ac_help + --with-CC C compiler to use" +ac_help="$ac_help + --with-incpath additional places to look for include files" +ac_help="$ac_help + --with-libpath additional places to look for libraries" +ac_help="$ac_help + --with-libraries additional libraries to link with" +ac_help="$ac_help + --with-devel add developement options" +ac_help="$ac_help + --with-csops add CSOps standard options" +ac_help="$ac_help + --without-passwd don't use passwd/shadow file for authentication" +ac_help="$ac_help + --with-skey enable S/Key support " +ac_help="$ac_help + --with-opie enable OPIE support " +ac_help="$ac_help + --with-long-otp-prompt use a two line OTP (skey/opie) prompt" +ac_help="$ac_help + --with-SecurID enable SecurID support" +ac_help="$ac_help + --with-fwtk enable FWTK AuthSRV support" +ac_help="$ac_help + --with-kerb4 enable kerberos v4 support" +ac_help="$ac_help + --with-kerb5 enable kerberos v5 support" +ac_help="$ac_help + --with-authenticate enable AIX general authentication support" +ac_help="$ac_help + --with-pam enable PAM support" +ac_help="$ac_help + --with-AFS enable AFS support" +ac_help="$ac_help + --with-DCE enable DCE support" +ac_help="$ac_help + --without-lecture don't print lecture for first-time sudoer" +ac_help="$ac_help + --with-logging log via syslog, file, or both" +ac_help="$ac_help + --with-logfac syslog facility to log with (default is local2)" +ac_help="$ac_help + --with-goodpri syslog priority for commands (def is notice)" +ac_help="$ac_help + --with-badpri syslog priority for failures (def is LOG_ALERT)" +ac_help="$ac_help + --with-logpath path to the sudo log file" +ac_help="$ac_help + --with-loglen maximum length of a log file line (default is 80)" +ac_help="$ac_help + --with-ignore-dot ignore '.' in the PATH" +ac_help="$ac_help + --with-mailto who should get sudo mail (default is "root")" +ac_help="$ac_help + --with-mailsubject subject of sudo mail" +ac_help="$ac_help + --without-mail-if-no-user do not send mail if user not in sudoers" +ac_help="$ac_help + --with-mail-if-no-host send mail if user in sudoers but not for this host" +ac_help="$ac_help + --with-mail-if-noperms send mail if user not allowed to run command" +ac_help="$ac_help + --with-passprompt default password prompt" +ac_help="$ac_help + --with-badpass-message message the user sees when the password is wrong" +ac_help="$ac_help + --with-fqdn expect fully qualified hosts in sudoers" +ac_help="$ac_help + --with-timedir path to the sudo timestamp dir" +ac_help="$ac_help + --with-sendmail=path set path to sendmail + --without-sendmail do not send mail at all" +ac_help="$ac_help + --with-sudoers-mode mode of sudoers file (defaults to 0440)" +ac_help="$ac_help + --with-sudoers-uid uid that owns sudoers file (defaults to 0)" +ac_help="$ac_help + --with-sudoers-gid gid that owns sudoers file (defaults to 0)" +ac_help="$ac_help + --with-umask umask with which the prog should run (default is 0022) + --without-umask Preserves the umask of the user invoking sudo." +ac_help="$ac_help + --with-runas-default User to run commands as (default is "root"" +ac_help="$ac_help + --with-exempt=group no passwd needed for users in this group" +ac_help="$ac_help + --with-editor=path Default editor for visudo (defaults to vi)" +ac_help="$ac_help + --with-env-editor Use the environment variable EDITOR for visudo" +ac_help="$ac_help + --with-passwd-tries number of tries to enter password (default is 3)" +ac_help="$ac_help + --with-timeout minutes before sudo asks for passwd again (def is 5)" +ac_help="$ac_help + --with-password-timeout passwd prompt timeout in minutes (default is 5)" +ac_help="$ac_help + --with-execv use execv() instead of execvp()" +ac_help="$ac_help + --with-tty-tickets use a different ticket file for each tty" +ac_help="$ac_help + --with-insults insult the user for entering an incorrect password" +ac_help="$ac_help + --with-all-insults include all the sudo insult sets" +ac_help="$ac_help + --with-classic-insults include the insults from the "classic" sudo" +ac_help="$ac_help + --with-csops-insults include CSOps insults" +ac_help="$ac_help + --with-hal-insults include 2001-like insults" +ac_help="$ac_help + --with-goons-insults include the insults from the \"Goon Show\"" +ac_help="$ac_help + --with-secure-path override the user's path with a builtin one" +ac_help="$ac_help + --without-interfaces don't try to read the ip addr of ether interfaces" +ac_help="$ac_help + --disable-authentication + Do not require authentication by default" +ac_help="$ac_help + --disable-shadow Never use shadow passwords" +ac_help="$ac_help + --disable-root-sudo don't allow root to run sudo" +ac_help="$ac_help + --enable-log-host Log the hostname in the log file" +ac_help="$ac_help + --enable-noargs-shell If sudo is given no arguments run a shell" +ac_help="$ac_help + --enable-shell-sets-home + set \$HOME to target user in shell mode" +ac_help="$ac_help + --disable-path-info Print 'command not allowed' not 'command not found'" +ac_help="$ac_help + --disable-sia Never use SIA on Digital UNIX" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +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' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +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 + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # 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 ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$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" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) 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) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$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 ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval with_${ac_package}='$ac_optarg' ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + 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 "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args \"$ac_arg\"" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# 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 + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=sudo.h + +# 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 "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# 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 "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +echo "Configuring Sudo version 1.6" +PROGS="sudo visudo" +CPPFLAGS="" +LDFLAGS="" +SUDO_LDFLAGS="" +LIBS="" +SUDO_LIBS="" +NET_LIBS="" +AFS_LIBS="" +OSDEFS="" +AUTH_OBJS="" +LIBOBJS="" +MANTYPE="man" +MAN_POSTINSTALL="" +SUDOERS_MODE=0440 +SUDOERS_UID=0 +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 "configure: warning: --with-otp-only option deprecated, treating as --without-passwd" 1>&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" + cat >> confdefs.h <<\EOF +#define WITHOUT_PASSWD 1 +EOF + + echo "configure: warning: --with-alertmail option deprecated, treating as --mailto" 1>&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 "configure: error: "must give --with-CC an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "illegal argument: --without-CC."" 1>&2; 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 "configure: error: "must give --with-incpath an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-incpath not supported."" 1>&2; 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 "configure: error: "must give --with-libpath an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-libpath not supported."" 1>&2; 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 "configure: error: "must give --with-libraries an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-libraries not supported."" 1>&2; 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_csops" + ;; +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 + with_insults=yes + 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 $ac_n "checking whether to use shadow/passwd file authentication""... $ac_c" 1>&6 +echo "configure:836: checking whether to use shadow/passwd file authentication" >&5 + echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "Sorry, --with-passwd does not take an argument."" 1>&2; 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 "configure: error: "cannot use both S/Key and OPIE"" 1>&2; exit 1; } + fi + cat >> confdefs.h <<\EOF +#define HAVE_SKEY 1 +EOF + + echo $ac_n "checking whether to try S/Key authentication""... $ac_c" 1>&6 +echo "configure:857: checking whether to try S/Key authentication" >&5 + echo "$ac_t""yes" 1>&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 "configure: error: "cannot use both S/Key and OPIE"" 1>&2; exit 1; } + fi + cat >> confdefs.h <<\EOF +#define HAVE_OPIE 1 +EOF + + echo $ac_n "checking whether to try NRL OPIE authentication""... $ac_c" 1>&6 +echo "configure:880: checking whether to try NRL OPIE authentication" >&5 + echo "$ac_t""yes" 1>&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 $ac_n "checking whether to use a two line prompt for OTP authentication""... $ac_c" 1>&6 +echo "configure:900: checking whether to use a two line prompt for OTP authentication" >&5 + echo "$ac_t""yes" 1>&6 + ;; + no) ;; + *) { echo "configure: error: "--with-long-otp-prompt does not take an argument."" 1>&2; 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 $ac_n "checking whether to use SecurID for authentication""... $ac_c" 1>&6 +echo "configure:920: checking whether to use SecurID for authentication" >&5 + echo "$ac_t""yes" 1>&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 + yes) cat >> confdefs.h <<\EOF +#define HAVE_FWTK 1 +EOF + + echo $ac_n "checking whether to use FWTK AuthSRV for authentication""... $ac_c" 1>&6 +echo "configure:938: checking whether to use FWTK AuthSRV for authentication" >&5 + echo "$ac_t""yes" 1>&6 + with_passwd=no + AUTH_OBJS="fwtk.o" + ;; + no) ;; + *) cat >> confdefs.h <<\EOF +#define HAVE_FWTK 1 +EOF + + echo $ac_n "checking whether to use FWTK AuthSRV for authentication""... $ac_c" 1>&6 +echo "configure:949: checking whether to use FWTK AuthSRV for authentication" >&5 + echo "$ac_t""yes" 1>&6 + SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${with_fwtk}" + CPPFLAGS="${CPPFLAGS} -I${with_fwtk}" + with_passwd=no + AUTH_OBJS="fwtk.o" + with_fwtk=yes + ;; +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 $ac_n "checking whether to try Kerberos 4 authentication""... $ac_c" 1>&6 +echo "configure:966: checking whether to try Kerberos 4 authentication" >&5 + echo "$ac_t""yes" 1>&6 + ;; + no) ;; + *) { echo "configure: error: "--with-kerb4 does not take an argument."" 1>&2; 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 $ac_n "checking whether to try Kerberos 5 authentication""... $ac_c" 1>&6 +echo "configure:981: checking whether to try Kerberos 5 authentication" >&5 + echo "$ac_t""yes" 1>&6 + ;; + no) ;; + *) { echo "configure: error: "--with-kerb5 does not take an argument."" 1>&2; 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 $ac_n "checking whether to use AIX general authentication""... $ac_c" 1>&6 +echo "configure:1000: checking whether to use AIX general authentication" >&5 + echo "$ac_t""yes" 1>&6 + with_passwd=no + AUTH_OBJS="aix_auth.o" + ;; + no) ;; + *) { echo "configure: error: "--with-authenticate does not take an argument."" 1>&2; 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 $ac_n "checking whether to use PAM authentication""... $ac_c" 1>&6 +echo "configure:1021: checking whether to use PAM authentication" >&5 + echo "$ac_t""yes" 1>&6 + with_passwd=no + AUTH_OBJS="pam.o" + ;; + no) ;; + *) { echo "configure: error: "--with-pam does not take an argument."" 1>&2; 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 $ac_n "checking whether to try AFS (kerberos) authentication""... $ac_c" 1>&6 +echo "configure:1042: checking whether to try AFS (kerberos) authentication" >&5 + echo "$ac_t""yes" 1>&6 + AUTH_OBJS="${AUTH_OBJS} afs.o" + ;; + no) ;; + *) { echo "configure: error: "--with-AFS does not take an argument."" 1>&2; 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 $ac_n "checking whether to try DCE (kerberos) authentication""... $ac_c" 1>&6 +echo "configure:1062: checking whether to try DCE (kerberos) authentication" >&5 + echo "$ac_t""yes" 1>&6 + AUTH_OBJS="${AUTH_OBJS} dce.o" + ;; + no) ;; + *) { echo "configure: error: "--with-DCE does not take an argument."" 1>&2; exit 1; } + ;; +esac +fi + + +echo $ac_n "checking whether to lecture users the first time they run sudo""... $ac_c" 1>&6 +echo "configure:1074: checking whether to lecture users the first time they run sudo" >&5 +# 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) echo "$ac_t""yes" 1>&6 + ;; + no|none) cat >> confdefs.h <<\EOF +#define NO_LECTURE 1 +EOF + + echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "unknown argument to --with-lecture: $with_lecture"" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""yes" 1>&6 +fi + + +echo $ac_n "checking whether sudo should log via syslog or to a file by default""... $ac_c" 1>&6 +echo "configure:1096: checking whether sudo should log via syslog or to a file by default" >&5 +# 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 "configure: error: "must give --with-logging an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-logging not supported."" 1>&2; exit 1; } + ;; + syslog) cat >> confdefs.h <<\EOF +#define LOGGING SLOG_SYSLOG +EOF + + echo "$ac_t""syslog" 1>&6 + ;; + file) cat >> confdefs.h <<\EOF +#define LOGGING SLOG_FILE +EOF + + echo "$ac_t""file" 1>&6 + ;; + both) cat >> confdefs.h <<\EOF +#define LOGGING SLOG_BOTH +EOF + + echo "$ac_t""both" 1>&6 + ;; + *) { echo "configure: error: "unknown argument to --with-logging: $with_logging"" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define LOGGING SLOG_SYSLOG +EOF + echo "$ac_t""syslog" 1>&6 +fi + + +echo $ac_n "checking which syslog facility sudo should log with""... $ac_c" 1>&6 +echo "configure:1135: checking which syslog facility sudo should log with" >&5 +# 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 "configure: error: "must give --with-logfac an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-logfac not supported."" 1>&2; exit 1; } + ;; + authpriv|auth|daemon|user|local0|local1|local2|local3|local4|local5|local6|local7) cat >> confdefs.h <<EOF +#define LOGFAC "$with_logfac" +EOF + + echo "$ac_t""$with_logfac" 1>&6 + ;; + *) { echo "configure: error: "$with_logfac is not a supported syslog facility."" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<EOF +#define LOGFAC "local2" +EOF + echo "$ac_t"""local2"" 1>&6 +fi + + +echo $ac_n "checking at which syslog priority to log commands""... $ac_c" 1>&6 +echo "configure:1162: checking at which syslog priority to log commands" >&5 +# 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 "configure: error: "must give --with-goodpri an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-goodpri not supported."" 1>&2; exit 1; } + ;; + alert|crit|debug|emerg|err|info|notice|warning) cat >> confdefs.h <<EOF +#define PRI_SUCCESS "$with_goodpri" +EOF + + echo "$ac_t""$with_goodpri" 1>&6 + ;; + *) { echo "configure: error: "$with_goodpri is not a supported syslog priority."" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<EOF +#define PRI_SUCCESS "notice" +EOF + echo "$ac_t"""notice"" 1>&6 +fi + + +echo $ac_n "checking at which syslog priority to log failures""... $ac_c" 1>&6 +echo "configure:1189: checking at which syslog priority to log failures" >&5 +# 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 "configure: error: "must give --with-badpri an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-badpri not supported."" 1>&2; exit 1; } + ;; + alert|crit|debug|emerg|err|info|notice|warning) cat >> confdefs.h <<EOF +#define PRI_FAILURE "$with_badpri" +EOF + + echo "$ac_t""$with_badpri" 1>&6 + ;; + *) { echo "configure: error: $with_badpri is not a supported syslog priority." 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<EOF +#define PRI_FAILURE "alert" +EOF + echo "$ac_t"""alert"" 1>&6 +fi + + +# 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 "configure: error: "must give --with-logpath an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-logpath not supported."" 1>&2; exit 1; } + ;; +esac +fi + + +echo $ac_n "checking how long a line in the log file should be""... $ac_c" 1>&6 +echo "configure:1228: checking how long a line in the log file should be" >&5 +# 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 "configure: error: "must give --with-loglen an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-loglen not supported."" 1>&2; exit 1; } + ;; + [0-9]*) cat >> confdefs.h <<EOF +#define MAXLOGFILELEN $with_loglen +EOF + + echo "$ac_t""$with_loglen" 1>&6 + ;; + *) { echo "configure: error: "you must enter a number, not $with_loglen"" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define MAXLOGFILELEN 80 +EOF + echo "$ac_t""80" 1>&6 +fi + + +echo $ac_n "checking whether sudo should ignore '.' or '' in \$PATH""... $ac_c" 1>&6 +echo "configure:1255: checking whether sudo should ignore '.' or '' in \$PATH" >&5 +# 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) cat >> confdefs.h <<\EOF +#define IGNORE_DOT_PATH 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-ignore-dot does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking who should get the mail that sudo sends""... $ac_c" 1>&6 +echo "configure:1277: checking who should get the mail that sudo sends" >&5 +# 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 "configure: error: "must give --with-mailto an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-mailto not supported."" 1>&2; exit 1; } + ;; + *) cat >> confdefs.h <<EOF +#define MAILTO "$with_mailto" +EOF + + echo "$ac_t""$with_mailto" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define MAILTO "root" +EOF + echo "$ac_t""root" 1>&6 +fi + + +# 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 "configure: error: "must give --with-mailsubject an argument."" 1>&2; exit 1; } + ;; + no) echo "Sorry, --without-mailsubject not supported." + ;; + *) cat >> confdefs.h <<EOF +#define MAILSUBJECT "$with_mailsubject" +EOF + + echo $ac_n "checking sudo mail subject""... $ac_c" 1>&6 +echo "configure:1314: checking sudo mail subject" >&5 + echo "$ac_t""Using alert mail subject: $with_mailsubject" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define MAILSUBJECT "*** SECURITY information for %h ***" +EOF + +fi + + +echo $ac_n "checking whether to send mail when a user is not in sudoers""... $ac_c" 1>&6 +echo "configure:1327: checking whether to send mail when a user is not in sudoers" >&5 +# 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) cat >> confdefs.h <<\EOF +#define SEND_MAIL_WHEN_NO_USER 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "unknown argument to --with-mail-if-no-user: $with_mail_if_no_user"" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define SEND_MAIL_WHEN_NO_USER 1 +EOF + echo "$ac_t""yes" 1>&6 +fi + + +echo $ac_n "checking whether to send mail when user listed but not for this host""... $ac_c" 1>&6 +echo "configure:1352: checking whether to send mail when user listed but not for this host" >&5 +# 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) cat >> confdefs.h <<\EOF +#define SEND_MAIL_WHEN_NO_HOST 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "unknown argument to --with-mail-if-no-host: $with_mail_if_no_host"" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to send mail when a user tries a disallowed command""... $ac_c" 1>&6 +echo "configure:1374: checking whether to send mail when a user tries a disallowed command" >&5 +# 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) cat >> confdefs.h <<\EOF +#define SEND_MAIL_WHEN_NOT_OK 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "unknown argument to --with-mail-if-noperms: $with_mail_if_noperms"" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking for bad password prompt""... $ac_c" 1>&6 +echo "configure:1396: checking for bad password prompt" >&5 +# 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 "configure: error: "must give --with-passprompt an argument."" 1>&2; exit 1; } + ;; + no) echo "Sorry, --without-passprompt not supported." + ;; + *) cat >> confdefs.h <<EOF +#define PASSPROMPT "$with_passprompt" +EOF + + echo "$ac_t""$with_passprompt" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define PASSPROMPT "Password:" +EOF + echo "$ac_t""Password:" 1>&6 +fi + + +echo $ac_n "checking for bad password message""... $ac_c" 1>&6 +echo "configure:1421: checking for bad password message" >&5 +# 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 "configure: error: "Must give --with-badpass-message an argument."" 1>&2; exit 1; } + ;; + no) echo "Sorry, --without-badpass-message not supported." + ;; + *) cat >> confdefs.h <<EOF +#define INCORRECT_PASSWORD "$with_badpass_message" +EOF + + echo "$ac_t""$with_badpass_message" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define INCORRECT_PASSWORD "Sorry, try again." +EOF + echo "$ac_t""Sorry, try again." 1>&6 +fi + + +echo $ac_n "checking whether to expect fully qualified hosts in sudoers""... $ac_c" 1>&6 +echo "configure:1446: checking whether to expect fully qualified hosts in sudoers" >&5 +# Check whether --with-fqdn or --without-fqdn was given. +if test "${with_fqdn+set}" = set; then + withval="$with_fqdn" + case $with_fqdn in + yes) cat >> confdefs.h <<\EOF +#define FQDN 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-fqdn does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&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 "configure: error: "must give --with-timedir an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-timedir not supported."" 1>&2; exit 1; } + ;; +esac +fi + + +# Check whether --with-sendmail or --without-sendmail was given. +if test "${with_sendmail+set}" = set; then + withval="$with_sendmail" + case $with_sendmail in + yes) with_sendmail="" + ;; + no) ;; + *) cat >> confdefs.h <<EOF +#define _PATH_SENDMAIL "$with_sendmail" +EOF + + ;; +esac +fi + + +# Check whether --with-sudoers-mode or --without-sudoers-mode was given. +if test "${with_sudoers_mode+set}" = set; then + withval="$with_sudoers_mode" + case $with_sudoers_mode in + yes) { echo "configure: error: "must give --with-sudoers-mode an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-sudoers-mode not supported."" 1>&2; exit 1; } + ;; + [1-9]*) SUDOERS_MODE=0${with_sudoers_mode} + ;; + 0*) SUDOERS_MODE=$with_sudoers_mode + ;; + *) { echo "configure: error: "you must use a numeric uid, not a name."" 1>&2; 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 "configure: error: "must give --with-sudoers-uid an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-sudoers-uid not supported."" 1>&2; exit 1; } + ;; + [0-9]*) SUDOERS_UID=$with_sudoers_uid + ;; + *) { echo "configure: error: "you must use a numeric uid, not a name."" 1>&2; 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 "configure: error: "must give --with-sudoers-gid an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-sudoers-gid not supported."" 1>&2; exit 1; } + ;; + [0-9]*) SUDOERS_GID=$with_sudoers_gid + ;; + *) { echo "configure: error: "you must use a numeric gid, not a name."" 1>&2; exit 1; } + ;; +esac +fi + + +echo $ac_n "checking for umask programs should be run with""... $ac_c" 1>&6 +echo "configure:1546: checking for umask programs should be run with" >&5 +# 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 "configure: error: "must give --with-umask an argument."" 1>&2; exit 1; } + ;; + no) echo "$ac_t""user" 1>&6 + ;; + [0-9]*) cat >> confdefs.h <<EOF +#define SUDO_UMASK $with_umask +EOF + + echo "$ac_t""$with_umask" 1>&6 + ;; + *) { echo "configure: error: "you must enter a numeric mask."" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define SUDO_UMASK 0022 +EOF + echo "$ac_t""0022" 1>&6 +fi + + +echo $ac_n "checking for default user to run commands as""... $ac_c" 1>&6 +echo "configure:1573: checking for default user to run commands as" >&5 +# 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 "configure: error: "must give --with-runas-default an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-runas-default not supported."" 1>&2; exit 1; } + ;; + *) cat >> confdefs.h <<EOF +#define RUNAS_DEFAULT "$with_runas_default" +EOF + + echo "$ac_t""$with_runas_default" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define RUNAS_DEFAULT "root" +EOF + echo "$ac_t""root" 1>&6 +fi + + +# 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 "configure: error: "must give --with-exempt an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-exempt not supported."" 1>&2; exit 1; } + ;; + *) cat >> confdefs.h <<EOF +#define EXEMPTGROUP "$with_exempt" +EOF + + echo $ac_n "checking for group to be exempt from password""... $ac_c" 1>&6 +echo "configure:1610: checking for group to be exempt from password" >&5 + echo "$ac_t""$with_exempt" 1>&6 + ;; +esac +fi + + +echo $ac_n "checking for editor that visudo should use""... $ac_c" 1>&6 +echo "configure:1618: checking for editor that visudo should use" >&5 +# 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 "configure: error: "must give --with-editor an argument."" 1>&2; exit 1; } + ;; + no) { echo "configure: error: "--without-editor not supported."" 1>&2; exit 1; } + ;; + *) cat >> confdefs.h <<EOF +#define EDITOR "$with_editor" +EOF + + echo "$ac_t""$with_editor" 1>&6 + ;; +esac +else + cat >> confdefs.h <<\EOF +#define EDITOR _PATH_VI +EOF + echo "$ac_t""vi" 1>&6 +fi + + +echo $ac_n "checking whether to obey EDITOR and VISUAL environment variables""... $ac_c" 1>&6 +echo "configure:1643: checking whether to obey EDITOR and VISUAL environment variables" >&5 +# 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) cat >> confdefs.h <<\EOF +#define ENV_EDITOR 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-env-editor does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking number of tries a user gets to enter their password""... $ac_c" 1>&6 +echo "configure:1665: checking number of tries a user gets to enter their password" >&5 +# 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) cat >> confdefs.h <<\EOF +#define TRIES_FOR_PASSWORD 3 +EOF + + echo "$ac_t""3" 1>&6 + ;; + no) { echo "configure: error: "--without-editor not supported."" 1>&2; exit 1; } + ;; + [1-9]*) cat >> confdefs.h <<EOF +#define TRIES_FOR_PASSWORD $with_passwd_tries +EOF + + echo "$ac_t""$with_passwd_tries" 1>&6 + ;; + *) { echo "configure: error: "you must enter the numer of tries, > 0"" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define TRIES_FOR_PASSWORD 3 +EOF + echo "$ac_t""3" 1>&6 +fi + + +echo $ac_n "checking time in minutes after which sudo will ask for a password again""... $ac_c" 1>&6 +echo "configure:1696: checking time in minutes after which sudo will ask for a password again" >&5 +# 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) cat >> confdefs.h <<\EOF +#define TIMEOUT 5 +EOF + + echo "$ac_t""5" 1>&6 + ;; + no) cat >> confdefs.h <<\EOF +#define TIMEOUT 0 +EOF + + echo "$ac_t""no timeout" 1>&6 + ;; + [0-9]*) cat >> confdefs.h <<EOF +#define TIMEOUT $with_timeout +EOF + + echo "$ac_t""$with_timeout" 1>&6 + ;; + *) { echo "configure: error: "you must enter the numer of minutes."" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define TIMEOUT 5 +EOF + echo "$ac_t""5" 1>&6 +fi + + +echo $ac_n "checking time in minutes after the password prompt will time out""... $ac_c" 1>&6 +echo "configure:1731: checking time in minutes after the password prompt will time out" >&5 +# 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) cat >> confdefs.h <<\EOF +#define PASSWORD_TIMEOUT 5 +EOF + + echo "$ac_t""5" 1>&6 + ;; + no) cat >> confdefs.h <<\EOF +#define PASSWORD_TIMEOUT 0 +EOF + + echo "$ac_t""no timeout" 1>&6 + ;; + [0-9]*) cat >> confdefs.h <<EOF +#define PASSWORD_TIMEOUT $with_password_timeout +EOF + + echo "$ac_t""$with_password_timeout" 1>&6 + ;; + *) { echo "configure: error: "you must enter the numer of minutes."" 1>&2; exit 1; } + ;; +esac +else + cat >> confdefs.h <<\EOF +#define PASSWORD_TIMEOUT 5 +EOF + echo "$ac_t""5" 1>&6 +fi + + +echo $ac_n "checking whether to use execvp or execv""... $ac_c" 1>&6 +echo "configure:1766: checking whether to use execvp or execv" >&5 +# Check whether --with-execv or --without-execv was given. +if test "${with_execv+set}" = set; then + withval="$with_execv" + case $with_execv in + yes) cat >> confdefs.h <<\EOF +#define USE_EXECV 1 +EOF + + echo "$ac_t""execv" 1>&6 + ;; + no) echo "$ac_t""execvp" 1>&6 + ;; + *) { echo "configure: error: "--with-execv does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""execvp" 1>&6 +fi + + +echo $ac_n "checking whether to use per-tty ticket files""... $ac_c" 1>&6 +echo "configure:1788: checking whether to use per-tty ticket files" >&5 +# 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) cat >> confdefs.h <<\EOF +#define USE_TTY_TICKETS 1 +EOF + + echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-tty-tickets does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to include insults""... $ac_c" 1>&6 +echo "configure:1810: checking whether to include insults" >&5 +# Check whether --with-insults or --without-insults was given. +if test "${with_insults+set}" = set; then + withval="$with_insults" + case $with_insults in + yes) cat >> confdefs.h <<\EOF +#define USE_INSULTS 1 +EOF + + echo "$ac_t""yes" 1>&6 + with_classic_insults=yes + with_csops_insults=yes + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-insults does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""no" 1>&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 "configure: error: "--with-all-insults does not take an argument."" 1>&2; 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 "configure: error: "--with-classic-insults does not take an argument."" 1>&2; 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 "configure: error: "--with-csops-insults does not take an argument."" 1>&2; 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 "configure: error: "--with-hal-insults does not take an argument."" 1>&2; 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 "configure: error: "--with-goons-insults does not take an argument."" 1>&2; exit 1; } + ;; +esac +fi + + +if test "$with_insults" = "yes"; then + echo $ac_n "checking which insult sets to include""... $ac_c" 1>&6 +echo "configure:1915: checking which insult sets to include" >&5 + 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 "$ac_t""$i" 1>&6 +fi + +echo $ac_n "checking whether to override the user's path""... $ac_c" 1>&6 +echo "configure:1925: checking whether to override the user's path" >&5 +# Check whether --with-secure-path or --without-secure-path was given. +if test "${with_secure_path+set}" = set; then + withval="$with_secure_path" + case $with_secure_path in + yes) cat >> confdefs.h <<EOF +#define SECURE_PATH "/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" +EOF + + echo "$ac_t"":/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) cat >> confdefs.h <<EOF +#define SECURE_PATH "$with_secure_path" +EOF + + echo "$ac_t""$with_secure_path" 1>&6 + ;; +esac +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to get ip addresses from the network interfaces""... $ac_c" 1>&6 +echo "configure:1951: checking whether to get ip addresses from the network interfaces" >&5 +# 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 "$ac_t""yes" 1>&6 + ;; + no) cat >> confdefs.h <<\EOF +#define STUB_LOAD_INTERFACES 1 +EOF + + echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--with-interfaces does not take an argument."" 1>&2; exit 1; } + ;; +esac +else + echo "$ac_t""yes" 1>&6 +fi + + + +echo $ac_n "checking whether to do user authentication by default""... $ac_c" 1>&6 +echo "configure:1974: checking whether to do user authentication by default" >&5 +# Check whether --enable-authentication or --disable-authentication was given. +if test "${enable_authentication+set}" = set; then + enableval="$enable_authentication" + case "$enableval" in + yes) echo "$ac_t""yes" 1>&6 + ;; + no) echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define NO_AUTHENTICATION 1 +EOF + + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-authentication: $enableval" + ;; + esac + +else + echo "$ac_t""yes" 1>&6 +fi + + +echo $ac_n "checking whether to disable shadow password support""... $ac_c" 1>&6 +echo "configure:1998: checking whether to disable shadow password support" >&5 +# Check whether --enable-shadow or --disable-shadow was given. +if test "${enable_shadow+set}" = set; then + enableval="$enable_shadow" + case "$enableval" in + yes) echo "$ac_t""no" 1>&6 + ;; + no) echo "$ac_t""yes" 1>&6 + CHECKSHADOW="false" + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-shadow: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether root should be allowed to use sudo""... $ac_c" 1>&6 +echo "configure:2019: checking whether root should be allowed to use sudo" >&5 +# 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 "$ac_t""yes" 1>&6 + ;; + no) cat >> confdefs.h <<\EOF +#define NO_ROOT_SUDO 1 +EOF + + echo "$ac_t""no" 1>&6 + ;; + *) { echo "configure: error: "--enable-root-sudo does not take an argument."" 1>&2; exit 1; } + ;; + esac + +else + echo "$ac_t""yes" 1>&6 +fi + + +echo $ac_n "checking whether to log the hostname in the log file""... $ac_c" 1>&6 +echo "configure:2042: checking whether to log the hostname in the log file" >&5 +# 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 "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HOST_IN_LOG 1 +EOF + + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-log-host: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to invoke a shell if sudo is given no arguments""... $ac_c" 1>&6 +echo "configure:2066: checking whether to invoke a shell if sudo is given no arguments" >&5 +# 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 "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define SHELL_IF_NO_ARGS 1 +EOF + + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-noargs-shell: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to set \$HOME to target user in shell mode""... $ac_c" 1>&6 +echo "configure:2090: checking whether to set \$HOME to target user in shell mode" >&5 +# 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 "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define SHELL_SETS_HOME 1 +EOF + + ;; + no) echo "$ac_t""no" 1>&6 + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-shell-sets-home: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether to disable 'command not found' messages""... $ac_c" 1>&6 +echo "configure:2114: checking whether to disable 'command not found' messages" >&5 +# 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 "$ac_t""no" 1>&6 + ;; + no) echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DONT_LEAK_PATH_INFO 1 +EOF + + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-path-info: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + +# Extract the first word of "egrep", so it can be a program name with args. +set dummy egrep; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2140: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_EGREPPROG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$EGREPPROG"; then + ac_cv_prog_EGREPPROG="$EGREPPROG" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_EGREPPROG="egrep" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +EGREPPROG="$ac_cv_prog_EGREPPROG" +if test -n "$EGREPPROG"; then + echo "$ac_t""$EGREPPROG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$EGREPPROG"; then + echo "Sorry, configure requires egrep to run." + exit +fi + +ac_cv_prog_cc_cross="no" +cross_compiling="no" +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2175: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +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 $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2204: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +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 $# -gt 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" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:2252: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <<EOF +#line 2262 "configure" +#include "confdefs.h" +main(){return(0);} +EOF +if { (eval echo configure:2266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:2286: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:2291: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2300: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:2315: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +ac_cv_prog_cc_cross="no" +cross_compiling="no" +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:2345: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 2360 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2366: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 2377 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 +echo "configure:2406: checking for POSIXized ISC" >&5 +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + echo "$ac_t""yes" 1>&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 "$ac_t""no" 1>&6 + ISC= +fi + + +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 $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2434: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_UNAMEPROG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$UNAMEPROG"; then + ac_cv_prog_UNAMEPROG="$UNAMEPROG" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_UNAMEPROG="uname" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +UNAMEPROG="$ac_cv_prog_UNAMEPROG" +if test -n "$UNAMEPROG"; then + echo "$ac_t""$UNAMEPROG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "tr", so it can be a program name with args. +set dummy tr; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2462: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_TRPROG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$TRPROG"; then + ac_cv_prog_TRPROG="$TRPROG" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_TRPROG="tr" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +TRPROG="$ac_cv_prog_TRPROG" +if test -n "$TRPROG"; then + echo "$ac_t""$TRPROG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "sed", so it can be a program name with args. +set dummy sed; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2490: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_SEDPROG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$SEDPROG"; then + ac_cv_prog_SEDPROG="$SEDPROG" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_SEDPROG="sed" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +SEDPROG="$ac_cv_prog_SEDPROG" +if test -n "$SEDPROG"; then + echo "$ac_t""$SEDPROG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "nroff", so it can be a program name with args. +set dummy nroff; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2518: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_NROFFPROG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NROFFPROG"; then + ac_cv_prog_NROFFPROG="$NROFFPROG" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_NROFFPROG="nroff" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +NROFFPROG="$ac_cv_prog_NROFFPROG" +if test -n "$NROFFPROG"; then + echo "$ac_t""$NROFFPROG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$NROFFPROG"; then + MANTYPE="cat" +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 + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:2573: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`$ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`$ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +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 $ac_n "checking previous host type""... $ac_c" 1>&6 +echo "configure:2602: checking previous host type" >&5 + if eval "test \"`echo '$''{'sudo_cv_prev_host'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&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 eval "test \"`echo '$''{'sudo_cv_prev_host'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&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 + echo $ac_n "checking for getpwanam""... $ac_c" 1>&6 +echo "configure:2642: checking for getpwanam" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getpwanam'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2647 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getpwanam(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwanam(); + +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_getpwanam) || defined (__stub___getpwanam) +choke me +#else +getpwanam(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_getpwanam=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getpwanam=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getpwanam`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPWANAM 1 +EOF + for ac_func in issecure +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2690: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2695 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +else + echo "$ac_t""no" 1>&6 +fi + + 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 + ;; + *-*-aix*) + # To get all prototypes (so we pass -Wall) + CPPFLAGS="${CPPFLAGS} -D_XOPEN_EXTENDED_SOURCE" + cat >> confdefs.h <<\EOF +#define _ALL_SOURCE 1 +EOF + + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp" + ;; + *-*-hiuxmpp*) + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 +echo "configure:2769: checking for getprpwnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2781 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:2792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 +echo "configure:2814: checking for getprpwnam in -lsecurity" >&5 +if test -n ""; then + ac_lib_var=`echo security'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsecurity $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2826 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:2837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity"; SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +fi + +fi + + CHECKSHADOW="false" + fi + ;; + *-*-hpux1[0-9]*) + # uncomment this for a statically linked sudo + # (XXX - should be an option to configure) + #STATIC_SUDO=true + + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 +echo "configure:2872: checking for getprpwnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2884 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:2895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + echo $ac_n "checking for iscomsec in -lsec""... $ac_c" 1>&6 +echo "configure:2914: checking for iscomsec in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'iscomsec | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'iscomsec | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2926 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char iscomsec(); + +int main() { +iscomsec() +; return 0; } +EOF +if { (eval echo configure:2937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_ISCOMSEC 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + + if test -n "$STATIC_SUDO"; then + if test -n "$GCC"; then + SUDO_LDFLAGS="${SUDO_LDFLAGS} -static" + else + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive" + fi + fi + + # DCE support (requires ANSI C compiler) + if test "$with_DCE" = "yes"; then + if test -n "$GCC"; then + CPPFLAGS="${CPPFLAGS} -D_HPUX_SOURCE" + else + CPPFLAGS="${CPPFLAGS} -Aa -D_HPUX_SOURCE" + fi + fi + + # AFS support needs -lBSD + if test "$with_AFS" = "yes"; then + AFS_LIBS="-lc -lBSD" + fi + ;; + *-*-hpux9*) + # uncomment this for a statically linked sudo + # (XXX - should be an option to configure) + #STATIC_SUDO=true + + cat >> confdefs.h <<\EOF +#define BROKEN_SYSLOG 1 +EOF + + + if test "$CHECKSHADOW" = "true"; then + for ac_func in getspwuid +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3003: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3008 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + CHECKSHADOW="false" + fi + + if test -n "$STATIC_SUDO"; then + if test -n "$GCC"; then + SUDO_LDFLAGS="${SUDO_LDFLAGS} -static" + else + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive" + fi + 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" + + if test -n "$GCC"; then + CPPFLAGS="${CPPFLAGS} -D_HPUX_SOURCE -D_REENTRANT -I/usr/include/reentrant" + else + CPPFLAGS="${CPPFLAGS} -Aa -D_HPUX_SOURCE -D_REENTRANT -I/usr/include/reentrant" + fi + fi + + # AFS support needs -lBSD + if test "$with_AFS" = "yes"; then + AFS_LIBS="-lc -lBSD" + fi + ;; + *-*-hpux*) + + cat >> confdefs.h <<\EOF +#define BROKEN_SYSLOG 1 +EOF + + + # Not sure if setuid binaries are safe in < 9.x + if test -n "$GCC"; then + SUDO_LDFLAGS="${SUDO_LDFLAGS} -static" + else + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive" + fi + + # AFS support needs -lBSD + if test "$with_AFS" = "yes"; then + AFS_LIBS="-lc -lBSD" + fi + ;; + *-dec-osf*) + # ignore envariables wrt dynamic lib path + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-no_library_replacement" + + echo $ac_n "checking whether to disable sia support on Digital UNIX""... $ac_c" 1>&6 +echo "configure:3108: checking whether to disable sia support on Digital UNIX" >&5 + # Check whether --enable-sia or --disable-sia was given. +if test "${enable_sia+set}" = set; then + enableval="$enable_sia" + case "$enableval" in + yes) echo "$ac_t""no" 1>&6 + ;; + no) echo "$ac_t""yes" 1>&6 + CHECKSIA=false + ;; + *) echo "$ac_t""no" 1>&6 + echo "Ignoring unknown argument to --enable-sia: $enableval" + ;; + esac + +else + echo "$ac_t""no" 1>&6 +fi + + + # use SIA by default, if we have it, else SecureWare + # unless overridden on the command line + if test "$CHECKSIA" = "true"; then + echo $ac_n "checking for sia_ses_init""... $ac_c" 1>&6 +echo "configure:3132: checking for sia_ses_init" >&5 +if eval "test \"`echo '$''{'ac_cv_func_sia_ses_init'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3137 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char sia_ses_init(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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(); + +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 +sia_ses_init(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_sia_ses_init=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_sia_ses_init=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'sia_ses_init`\" = yes"; then + echo "$ac_t""yes" 1>&6 + 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 "configure: error: "you cannot mix SIA and other authentication schemes. You can turn off SIA support via the --disable-sia option"" 1>&2; exit 1; } + fi; CHECKSHADOW=false +else + echo "$ac_t""no" 1>&6 +fi + + fi + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 +echo "configure:3188: checking for getprpwnam in -lsecurity" >&5 +if test -n ""; then + ac_lib_var=`echo security'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsecurity $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3200 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:3211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +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 + echo $ac_n "checking for snprintf""... $ac_c" 1>&6 +echo "configure:3241: checking for snprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3246 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char snprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char snprintf(); + +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_snprintf) || defined (__stub___snprintf) +choke me +#else +snprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_snprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_snprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'snprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SNPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + + echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6 +echo "configure:3293: checking for vsnprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3298 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vsnprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vsnprintf(); + +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_vsnprintf) || defined (__stub___vsnprintf) +choke me +#else +vsnprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_vsnprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_vsnprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'vsnprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_VSNPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + + # 4.x and higher need -ldb too... + echo $ac_n "checking for dbopen in -ldb""... $ac_c" 1>&6 +echo "configure:3346: checking for dbopen in -ldb" >&5 +if test -n ""; then + ac_lib_var=`echo db'_'dbopen | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo db'_'dbopen | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldb $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3358 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dbopen(); + +int main() { +dbopen() +; return 0; } +EOF +if { (eval echo configure:3369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm" +else + echo "$ac_t""no" 1>&6 +SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm" +fi + + for ac_func in dispcrypt +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3393: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3398 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + echo $ac_n "checking for broken /usr/include/prot.h""... $ac_c" 1>&6 +echo "configure:3446: checking for broken /usr/include/prot.h" >&5 + cat > conftest.$ac_ext <<EOF +#line 3448 "configure" +#include "confdefs.h" + +#include <sys/types.h> +#include <sys/security.h> +#include <prot.h> + +int main() { +exit(0); +; return 0; } +EOF +if { (eval echo configure:3459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""no" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""yes, fixing locally" 1>&6 + sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h + +fi +rm -f conftest* + else + with_passwd=no + AUTH_OBJS="sia.o" + fi + ;; + *-*-irix*) + # configure may not think irix has stdc headers + # but it's good enough for sudo + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + + 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 $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6 +echo "configure:3505: checking for getpwnam in -lsun" >&5 +if test -n ""; then + ac_lib_var=`echo sun'_'getpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sun'_'getpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsun $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3517 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwnam(); + +int main() { +getpwnam() +; return 0; } +EOF +if { (eval echo configure:3528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="${LIBS} -lsun" +else + echo "$ac_t""no" 1>&6 +fi + + fi + ;; + *-*-linux*) + # To get crypt(3) and vasprintf() prototypes (so we pass -Wall) + cat >> confdefs.h <<\EOF +#define _GNU_SOURCE 1 +EOF + + + # Some Linux versions need to link with -lshadow + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getspnam""... $ac_c" 1>&6 +echo "configure:3560: checking for getspnam" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getspnam'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3565 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getspnam(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +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_getspnam) || defined (__stub___getspnam) +choke me +#else +getspnam(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_getspnam=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getspnam=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getspnam`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getspnam in -lshadow""... $ac_c" 1>&6 +echo "configure:3609: checking for getspnam in -lshadow" >&5 +if test -n ""; then + ac_lib_var=`echo shadow'_'getspnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo shadow'_'getspnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lshadow $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3621 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +int main() { +getspnam() +; return 0; } +EOF +if { (eval echo configure:3632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lshadow"; LIBS="${LIBS} -lshadow" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + 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 $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 +echo "configure:3671: checking for getprpwnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3683 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:3694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + 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 +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + ;; + *-*-ultrix*) + OS="ultrix" + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getauthuid in -lauth""... $ac_c" 1>&6 +echo "configure:3724: checking for getauthuid in -lauth" >&5 +if test -n ""; then + ac_lib_var=`echo auth'_'getauthuid | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo auth'_'getauthuid | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lauth $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3736 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getauthuid(); + +int main() { +getauthuid() +; return 0; } +EOF +if { (eval echo configure:3747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETAUTHUID 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lauth"; LIBS="${LIBS} -lauth" +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + ;; + *-*-riscos*) + LIBS="${LIBS} -lsun -lbsd" + CPPFLAGS="${CPPFLAGS} -I/usr/include -I/usr/include/bsd" + OSDEFS="${OSDEFS} -D_MIPS" + ;; + *-*-isc*) + OSDEFS="${OSDEFS} -D_ISC" + LIB_CRYPT=1 + SUDO_LIBS="${SUDO_LIBS} -lcrypt" + LIBS="${LIBS} -lcrypt" + + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6 +echo "configure:3786: checking for getspnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getspnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3798 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +int main() { +getspnam() +; return 0; } +EOF +if { (eval echo configure:3809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec" +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + ;; + *-*-sco*) + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6 +echo "configure:3838: checking for getprpwnam in -lprot" >&5 +if test -n "-lx"; then + ac_lib_var=`echo prot'_'getprpwnam-lx | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo prot'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lprot -lx $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3850 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:3861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lprot -lx"; LIBS="${LIBS} -lprot -lx"; SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 +echo "configure:3885: checking for getspnam in -lgen" >&5 +if test -n ""; then + ac_lib_var=`echo gen'_'getspnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgen $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3897 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +int main() { +getspnam() +; return 0; } +EOF +if { (eval echo configure:3908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lgen"; LIBS="${LIBS} -lgen" +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + ;; + *-sequent-sysv*) + if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6 +echo "configure:3937: checking for getspnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getspnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3949 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +int main() { +getspnam() +; return 0; } +EOF +if { (eval echo configure:3960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec" +else + echo "$ac_t""no" 1>&6 +fi + + CHECKSHADOW="false" + fi + ;; + *-ccur-sysv4|*-ccur-sysvr4) + LIBS="${LIBS} -lgen" + SUDO_LIBS="${SUDO_LIBS} -lgen" + ;; + *-*-bsdi*) + # Use shlicc for BSD/OS 2.x unless asked to do otherwise + if test "$OSREV" -ge 2 -a "${with_CC+set}" != set -a \ + "$ac_cv_prog_CC" = "gcc"; then + echo 'using shlicc as CC' + ac_cv_prog_CC=shlicc + CC="$ac_cv_prog_CC" + fi + ;; + *-*-*bsd*) + if test "$CHECKSHADOW" = "true"; then + CHECKSHADOW="false" + fi + ;; +esac + +if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getspnam""... $ac_c" 1>&6 +echo "configure:4008: checking for getspnam" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getspnam'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4013 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getspnam(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getspnam(); + +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_getspnam) || defined (__stub___getspnam) +choke me +#else +getspnam(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_getspnam=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getspnam=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getspnam`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETSPNAM 1 +EOF + CHECKSHADOW="false" +else + echo "$ac_t""no" 1>&6 +fi + +fi +if test "$CHECKSHADOW" = "true"; then + echo $ac_n "checking for getprpwnam""... $ac_c" 1>&6 +echo "configure:4061: checking for getprpwnam" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getprpwnam'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4066 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getprpwnam(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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() { + +/* 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 +getprpwnam(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_getprpwnam=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getprpwnam=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getprpwnam`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + CHECKSHADOW="false"; SECUREWARE=1 +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 +echo "configure:4110: checking for getprpwnam in -lsec" >&5 +if test -n ""; then + ac_lib_var=`echo sec'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4122 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:4133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 +echo "configure:4155: checking for getprpwnam in -lsecurity" >&5 +if test -n ""; then + ac_lib_var=`echo security'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsecurity $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4167 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:4178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lsecurity"; LIBS="${LIBS} -lsecurity" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6 +echo "configure:4200: checking for getprpwnam in -lprot" >&5 +if test -n ""; then + ac_lib_var=`echo prot'_'getprpwnam | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo prot'_'getprpwnam | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lprot $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4212 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getprpwnam(); + +int main() { +getprpwnam() +; return 0; } +EOF +if { (eval echo configure:4223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPRPWNAM 1 +EOF + CHECKSHADOW="false"; SECUREWARE=1; SUDO_LIBS="${SUDO_LIBS} -lprot"; LIBS="${LIBS} -lprot" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + +fi + +fi + +if test $ac_cv_prog_gcc = yes; then + echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 +echo "configure:4256: checking whether ${CC-cc} needs -traditional" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_pattern="Autoconf.*'x'" + cat > conftest.$ac_ext <<EOF +#line 4262 "configure" +#include "confdefs.h" +#include <sgtty.h> +Autoconf TIOCGETP +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +else + rm -rf conftest* + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat > conftest.$ac_ext <<EOF +#line 4280 "configure" +#include "confdefs.h" +#include <termio.h> +Autoconf TCGETA +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi + +echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:4302: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4307 "configure" +#include "confdefs.h" + +int main() { + +/* 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; +} + +; return 0; } +EOF +if { (eval echo configure:4356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +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 $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4381: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_YACC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +YACC="$ac_cv_prog_YACC" +if test -n "$YACC"; then + echo "$ac_t""$YACC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +if test -z "$with_sendmail"; then + echo $ac_n "checking for sendmail""... $ac_c" 1>&6 +echo "configure:4412: checking for sendmail" >&5 +if test -f "/usr/sbin/sendmail"; then + echo "$ac_t""/usr/sbin/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +EOF + +elif test -f "/usr/lib/sendmail"; then + echo "$ac_t""/usr/lib/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/lib/sendmail" +EOF + +elif test -f "/usr/etc/sendmail"; then + echo "$ac_t""/usr/etc/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/etc/sendmail" +EOF + +elif test -f "/usr/ucblib/sendmail"; then + echo "$ac_t""/usr/ucblib/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/ucblib/sendmail" +EOF + +elif test -f "/usr/local/lib/sendmail"; then + echo "$ac_t""/usr/local/lib/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/local/lib/sendmail" +EOF + +elif test -f "/usr/local/bin/sendmail"; then + echo "$ac_t""/usr/local/bin/sendmail" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SENDMAIL "/usr/local/bin/sendmail" +EOF + +else + echo "$ac_t""not found" 1>&6 +fi + +fi +echo $ac_n "checking for mv""... $ac_c" 1>&6 +echo "configure:4455: checking for mv" >&5 +if test -f "/usr/bin/mv"; then + echo "$ac_t""/usr/bin/mv" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_MV "/usr/bin/mv" +EOF + +elif test -f "/bin/mv"; then + echo "$ac_t""/bin/mv" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_MV "/bin/mv" +EOF + +elif test -f "/usr/ucb/mv"; then + echo "$ac_t""/usr/ucb/mv" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_MV "/usr/ucb/mv" +EOF + +elif test -f "/usr/sbin/mv"; then + echo "$ac_t""/usr/sbin/mv" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_MV "/usr/sbin/mv" +EOF + +else + echo "$ac_t""not found" 1>&6 +fi + +echo $ac_n "checking for bourne shell""... $ac_c" 1>&6 +echo "configure:4485: checking for bourne shell" >&5 +if test -f "/bin/sh"; then + echo "$ac_t""/bin/sh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/bin/sh" +EOF + +elif test -f "/usr/bin/sh"; then + echo "$ac_t""/usr/bin/sh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/usr/bin/sh" +EOF + +elif test -f "/sbin/sh"; then + echo "$ac_t""/sbin/sh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/sbin/sh" +EOF + +elif test -f "/usr/sbin/sh"; then + echo "$ac_t""/usr/sbin/sh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/usr/sbin/sh" +EOF + +elif test -f "/bin/ksh"; then + echo "$ac_t""/bin/ksh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/bin/ksh" +EOF + +elif test -f "/usr/bin/ksh"; then + echo "$ac_t""/usr/bin/ksh" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/usr/bin/ksh" +EOF + +elif test -f "/bin/bash"; then + echo "$ac_t""/bin/bash" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/bin/bash" +EOF + +elif test -f "/usr/bin/bash"; then + echo "$ac_t""/usr/bin/bash" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_BSHELL "/usr/bin/bash" +EOF + +else + echo "$ac_t""not found" 1>&6 +fi + +echo $ac_n "checking for vi""... $ac_c" 1>&6 +echo "configure:4539: checking for vi" >&5 +if test -f "/usr/bin/vi"; then + echo "$ac_t""/usr/bin/vi" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_VI "/usr/bin/vi" +EOF + +elif test -f "/usr/ucb/vi"; then + echo "$ac_t""/usr/ucb/vi" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_VI "/usr/ucb/vi" +EOF + +elif test -f "/usr/bsd/vi"; then + echo "$ac_t""/usr/bsd/vi" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_VI "/usr/bsd/vi" +EOF + +elif test -f "/bin/vi"; then + echo "$ac_t""/bin/vi" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_VI "/bin/vi" +EOF + +elif test -f "/usr/local/bin/vi"; then + echo "$ac_t""/usr/local/bin/vi" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_VI "/usr/local/bin/vi" +EOF + +else + echo "$ac_t""not found" 1>&6 +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:4575: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4580 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4588: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 4605 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + 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 <<EOF +#line 4623 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + 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 <<EOF +#line 4644 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#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); } + +EOF +if { (eval echo configure:4655: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&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 +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:4683: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4688 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:4696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + ac_header_dirent=$ac_hdr; break +else + echo "$ac_t""no" 1>&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:4721: checking for opendir in -ldir" >&5 +if test -n ""; then + ac_lib_var=`echo dir'_'opendir | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4733 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir(); + +int main() { +opendir() +; return 0; } +EOF +if { (eval echo configure:4744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:4766: checking for opendir in -lx" >&5 +if test -n ""; then + ac_lib_var=`echo x'_'opendir | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4778 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir(); + +int main() { +opendir() +; return 0; } +EOF +if { (eval echo configure:4789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +for ac_hdr in string.h strings.h unistd.h malloc.h paths.h utime.h fnmatch.h netgroup.h sys/sockio.h sys/bsdtypes.h sys/select.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4815: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4820 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4825: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +if test "$OS" != "ultrix"; then + for ac_hdr in termio.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4856: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4861 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4866: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_hdr in termios.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4896: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4901 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + for ac_func in tcgetattr +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4929: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4934 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +else + echo "$ac_t""no" 1>&6 +fi +done + +fi +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:4988: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4993 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_mode_t=yes +else + rm -rf conftest* + ac_cv_type_mode_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_mode_t" 1>&6 +if test $ac_cv_type_mode_t = no; then + cat >> confdefs.h <<\EOF +#define mode_t int +EOF + +fi + +echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 +echo "configure:5021: checking for uid_t in sys/types.h" >&5 +if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5026 "configure" +#include "confdefs.h" +#include <sys/types.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "uid_t" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_uid_t=yes +else + rm -rf conftest* + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_type_uid_t" 1>&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 $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:5055: checking for size_t" >&5 +if eval "test \"`echo '$''{'sudo_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5060 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t" >/dev/null 2>&1; then + rm -rf conftest* + sudo_cv_type_size_t=yes +else + rm -rf conftest* + sudo_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$sudo_cv_type_size_t" 1>&6 +if test $sudo_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t int +EOF + +fi + +echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 +echo "configure:5090: checking for ssize_t" >&5 +if eval "test \"`echo '$''{'sudo_cv_type_ssize_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5095 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ssize_t" >/dev/null 2>&1; then + rm -rf conftest* + sudo_cv_type_ssize_t=yes +else + rm -rf conftest* + sudo_cv_type_ssize_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$sudo_cv_type_ssize_t" 1>&6 +if test $sudo_cv_type_ssize_t = no; then + cat >> confdefs.h <<\EOF +#define ssize_t int +EOF + +fi + +echo $ac_n "checking for dev_t""... $ac_c" 1>&6 +echo "configure:5125: checking for dev_t" >&5 +if eval "test \"`echo '$''{'sudo_cv_type_dev_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5130 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "dev_t" >/dev/null 2>&1; then + rm -rf conftest* + sudo_cv_type_dev_t=yes +else + rm -rf conftest* + sudo_cv_type_dev_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$sudo_cv_type_dev_t" 1>&6 +if test $sudo_cv_type_dev_t = no; then + cat >> confdefs.h <<\EOF +#define dev_t int +EOF + +fi + +echo $ac_n "checking for ino_t""... $ac_c" 1>&6 +echo "configure:5160: checking for ino_t" >&5 +if eval "test \"`echo '$''{'sudo_cv_type_ino_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5165 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ino_t" >/dev/null 2>&1; then + rm -rf conftest* + sudo_cv_type_ino_t=yes +else + rm -rf conftest* + sudo_cv_type_ino_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$sudo_cv_type_ino_t" 1>&6 +if test $sudo_cv_type_ino_t = no; then + cat >> confdefs.h <<\EOF +#define ino_t unsigned int +EOF + +fi + +echo $ac_n "checking for full void implementation""... $ac_c" 1>&6 +echo "configure:5195: checking for full void implementation" >&5 +cat > conftest.$ac_ext <<EOF +#line 5197 "configure" +#include "confdefs.h" + +int main() { +void *foo; +foo = (void *)0; (void *)"test"; +; return 0; } +EOF +if { (eval echo configure:5205: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define VOID void +EOF + +echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define VOID char +EOF + +echo "$ac_t""no" 1>&6 +fi +rm -f conftest* + +echo $ac_n "checking max length of uid_t""... $ac_c" 1>&6 +echo "configure:5225: checking max length of uid_t" >&5 +if eval "test \"`echo '$''{'sudo_cv_uid_t_len'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <<EOF +#line 5234 "configure" +#include "confdefs.h" +#include <stdio.h> +#include <pwd.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/param.h> +main() { + FILE *f; + char b[1024]; + uid_t u = (uid_t) -1; + + if ((f = fopen("conftestdata", "w")) == NULL) + exit(1); + + (void) sprintf(b, "%u", u); + (void) fprintf(f, "%d\n", strlen(b)); + (void) fclose(f); + exit(0); +} +EOF +if { (eval echo configure:5255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + sudo_cv_uid_t_len=`cat conftestdata` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + sudo_cv_uid_t_len=10 +fi +rm -fr conftest* +fi + + +fi + +rm -f conftestdata +echo "$ac_t""$sudo_cv_uid_t_len" 1>&6 +cat >> confdefs.h <<EOF +#define MAX_UID_T_LEN $sudo_cv_uid_t_len +EOF + + +echo $ac_n "checking for long long support""... $ac_c" 1>&6 +echo "configure:5278: checking for long long support" >&5 +cat > conftest.$ac_ext <<EOF +#line 5280 "configure" +#include "confdefs.h" + +int main() { +long long foo = 1000; foo /= 10; +; return 0; } +EOF +if { (eval echo configure:5287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define HAVE_LONG_LONG 1 +EOF + +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <<EOF +#line 5297 "configure" +#include "confdefs.h" +main() {if (sizeof(long long) == sizeof(long)) exit(0); else exit(1);} +EOF +if { (eval echo configure:5301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + cat >> confdefs.h <<\EOF +#define LONG_IS_QUAD 1 +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -fr conftest* +fi + +echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* +echo $ac_n "checking for sa_len field in struct sockaddr""... $ac_c" 1>&6 +echo "configure:5323: checking for sa_len field in struct sockaddr" >&5 +if eval "test \"`echo '$''{'sudo_cv_sock_sa_len'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + sudo_cv_sock_sa_len=no +else + cat > conftest.$ac_ext <<EOF +#line 5331 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/socket.h> +main() { +struct sockaddr s; +s.sa_len = 0; +exit(0); +} +EOF +if { (eval echo configure:5341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + sudo_cv_sock_sa_len=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + sudo_cv_sock_sa_len=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi +echo "$ac_t""$sudo_cv_sock_sa_len" 1>&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 $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:5366: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5371 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <signal.h> +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:5388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <<EOF +#define RETSIGTYPE $ac_cv_type_signal +EOF + +;; +esac +for ac_func in strchr strrchr memchr memcpy memset sysconf sigaction tzset seteuid ftruncate strftime setrlimit +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5410: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5415 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +if test -n "$SECUREWARE"; then + for ac_func in bigcrypt +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5466: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5471 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_func in set_auth_parameters +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5521: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5526 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_func in initprivs +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5576: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5581 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +fi +if test -z "$BROKEN_GETCWD"; then + echo $ac_n "checking for getcwd""... $ac_c" 1>&6 +echo "configure:5631: checking for getcwd" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getcwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5636 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getcwd(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getcwd(); + +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_getcwd) || defined (__stub___getcwd) +choke me +#else +getcwd(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_getcwd=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getcwd=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getcwd`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETCWD 1 +EOF + +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS getcwd.o" +fi + +fi +echo $ac_n "checking for lockf""... $ac_c" 1>&6 +echo "configure:5684: checking for lockf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_lockf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5689 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char lockf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char lockf(); + +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_lockf) || defined (__stub___lockf) +choke me +#else +lockf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_lockf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_lockf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'lockf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LOCKF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +for ac_func in flock +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5735: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5740 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +fi + +echo $ac_n "checking for waitpid""... $ac_c" 1>&6 +echo "configure:5790: checking for waitpid" >&5 +if eval "test \"`echo '$''{'ac_cv_func_waitpid'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5795 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char waitpid(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char waitpid(); + +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_waitpid) || defined (__stub___waitpid) +choke me +#else +waitpid(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5818: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_waitpid=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_waitpid=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'waitpid`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_WAITPID 1 +EOF + +else + echo "$ac_t""no" 1>&6 +for ac_func in wait3 +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5841: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5846 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +fi + +echo $ac_n "checking for innetgr""... $ac_c" 1>&6 +echo "configure:5896: checking for innetgr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_innetgr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5901 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char innetgr(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char innetgr(); + +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_innetgr) || defined (__stub___innetgr) +choke me +#else +innetgr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_innetgr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_innetgr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'innetgr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_INNETGR 1 +EOF + for ac_func in getdomainname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5944: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 5949 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for lsearch""... $ac_c" 1>&6 +echo "configure:6001: checking for lsearch" >&5 +if eval "test \"`echo '$''{'ac_cv_func_lsearch'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6006 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char lsearch(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char lsearch(); + +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_lsearch) || defined (__stub___lsearch) +choke me +#else +lsearch(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_lsearch=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_lsearch=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'lsearch`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LSEARCH 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for lsearch in -lcompat""... $ac_c" 1>&6 +echo "configure:6050: checking for lsearch in -lcompat" >&5 +if test -n ""; then + ac_lib_var=`echo compat'_'lsearch | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo compat'_'lsearch | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcompat $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6062 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char lsearch(); + +int main() { +lsearch() +; return 0; } +EOF +if { (eval echo configure:6073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_safe=`echo "search.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for search.h""... $ac_c" 1>&6 +echo "configure:6090: checking for search.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6095 "configure" +#include "confdefs.h" +#include <search.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6100: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LSEARCH 1 +EOF + LIBS="${LIBS} -lcompat" +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS lsearch.o" +fi + +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS lsearch.o" +fi + +fi + +echo $ac_n "checking for setenv""... $ac_c" 1>&6 +echo "configure:6133: checking for setenv" >&5 +if eval "test \"`echo '$''{'ac_cv_func_setenv'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6138 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char setenv(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setenv(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_setenv) || defined (__stub___setenv) +choke me +#else +setenv(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6161: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_setenv=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_setenv=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'setenv`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SETENV 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for putenv""... $ac_c" 1>&6 +echo "configure:6182: checking for putenv" >&5 +if eval "test \"`echo '$''{'ac_cv_func_putenv'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6187 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char putenv(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char putenv(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_putenv) || defined (__stub___putenv) +choke me +#else +putenv(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_putenv=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_putenv=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'putenv`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_PUTENV 1 +EOF + +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS putenv.o" +fi + +fi + +echo $ac_n "checking for utime""... $ac_c" 1>&6 +echo "configure:6236: checking for utime" >&5 +if eval "test \"`echo '$''{'ac_cv_func_utime'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6241 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char utime(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char utime(); + +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_utime) || defined (__stub___utime) +choke me +#else +utime(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_utime=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_utime=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'utime`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_UTIME 1 +EOF + +echo $ac_n "checking for POSIX utime""... $ac_c" 1>&6 +echo "configure:6283: checking for POSIX utime" >&5 +if eval "test \"`echo '$''{'sudo_cv_func_utime_posix'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata; > conftestdata +if test "$cross_compiling" = yes; then + sudo_cv_func_utime_posix=no +else + cat > conftest.$ac_ext <<EOF +#line 6292 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/time.h> +#include <utime.h> +main() { +struct utimbuf ut; +ut.actime = ut.modtime = time(0); +utime("conftestdata", &ut); +exit(0); +} +EOF +if { (eval echo configure:6304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + sudo_cv_func_utime_posix=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + sudo_cv_func_utime_posix=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi +echo "$ac_t""$sudo_cv_func_utime_posix" 1>&6 +if test $sudo_cv_func_utime_posix = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_UTIME_POSIX 1 +EOF + +fi + +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS utime.o" +fi + +echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6 +echo "configure:6332: checking for working fnmatch" >&5 +if eval "test \"`echo '$''{'sudo_cv_func_fnmatch'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata; > conftestdata +if test "$cross_compiling" = yes; then + sudo_cv_func_fnmatch=no +else + cat > conftest.$ac_ext <<EOF +#line 6341 "configure" +#include "confdefs.h" +main() { +exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", 0)); +} +EOF +if { (eval echo configure:6347: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + sudo_cv_func_fnmatch=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + sudo_cv_func_fnmatch=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi +echo "$ac_t""$sudo_cv_func_fnmatch" 1>&6 +if test $sudo_cv_func_fnmatch = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_FNMATCH 1 +EOF + +else + LIBOBJS="$LIBOBJS fnmatch.o" +fi + +for ac_func in strerror strcasecmp +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:6374: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6379 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6402: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +LIBOBJS="$LIBOBJS ${ac_func}.o" +fi +done + + +echo $ac_n "checking for snprintf""... $ac_c" 1>&6 +echo "configure:6429: checking for snprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6434 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char snprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char snprintf(); + +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_snprintf) || defined (__stub___snprintf) +choke me +#else +snprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6457: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_snprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_snprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'snprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SNPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + +echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6 +echo "configure:6481: checking for vsnprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6486 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vsnprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vsnprintf(); + +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_vsnprintf) || defined (__stub___vsnprintf) +choke me +#else +vsnprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_vsnprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_vsnprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'vsnprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_VSNPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + +echo $ac_n "checking for asprintf""... $ac_c" 1>&6 +echo "configure:6533: checking for asprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_asprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6538 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char asprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char asprintf(); + +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_asprintf) || defined (__stub___asprintf) +choke me +#else +asprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_asprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_asprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'asprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_ASPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + +echo $ac_n "checking for vasprintf""... $ac_c" 1>&6 +echo "configure:6585: checking for vasprintf" >&5 +if eval "test \"`echo '$''{'ac_cv_func_vasprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6590 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vasprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vasprintf(); + +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_vasprintf) || defined (__stub___vasprintf) +choke me +#else +vasprintf(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_vasprintf=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_vasprintf=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'vasprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_VASPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +NEED_SNPRINTF=1 +fi + +if test -n "$NEED_SNPRINTF"; then + LIBOBJS="$LIBOBJS snprintf.o" +fi +if test -z "$LIB_CRYPT"; then + echo $ac_n "checking for crypt""... $ac_c" 1>&6 +echo "configure:6641: checking for crypt" >&5 +if eval "test \"`echo '$''{'ac_cv_func_crypt'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6646 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char crypt(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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() { + +/* 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 +crypt(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_crypt=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_crypt=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +echo "configure:6687: checking for crypt in -lcrypt" >&5 +if test -n ""; then + ac_lib_var=`echo crypt'_'crypt | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6699 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char crypt(); + +int main() { +crypt() +; return 0; } +EOF +if { (eval echo configure:6710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SUDO_LIBS="${SUDO_LIBS} -lcrypt"; LIBS="${LIBS} -lcrypt" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for crypt in -lcrypt_d""... $ac_c" 1>&6 +echo "configure:6729: checking for crypt in -lcrypt_d" >&5 +if test -n ""; then + ac_lib_var=`echo crypt_d'_'crypt | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo crypt_d'_'crypt | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt_d $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6741 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char crypt(); + +int main() { +crypt() +; return 0; } +EOF +if { (eval echo configure:6752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SUDO_LIBS="${SUDO_LIBS} -lcrypt_d"; LIBS="${LIBS} -lcrypt_d" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for crypt in -lufc""... $ac_c" 1>&6 +echo "configure:6771: checking for crypt in -lufc" >&5 +if test -n ""; then + ac_lib_var=`echo ufc'_'crypt | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo ufc'_'crypt | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lufc $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6783 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char crypt(); + +int main() { +crypt() +; return 0; } +EOF +if { (eval echo configure:6794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SUDO_LIBS="${SUDO_LIBS} -lufc"; LIBS="${LIBS} -lufc" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + +fi + +fi +echo $ac_n "checking for socket""... $ac_c" 1>&6 +echo "configure:6822: checking for socket" >&5 +if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 6827 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char socket(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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() { + +/* 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 +socket(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_socket=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_socket=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:6868: checking for socket in -lsocket" >&5 +if test -n ""; then + ac_lib_var=`echo socket'_'socket | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6880 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { +socket() +; return 0; } +EOF +if { (eval echo configure:6891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 +echo "configure:6910: checking for socket in -linet" >&5 +if test -n ""; then + ac_lib_var=`echo inet'_'socket | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-linet $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6922 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { +socket() +; return 0; } +EOF +if { (eval echo configure:6933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet" +else + echo "$ac_t""no" 1>&6 +echo "configure: warning: unable to find socket() trying -lsocket -lnsl" 1>&2 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:6953: checking for socket in -lsocket" >&5 +if test -n "-lnsl"; then + ac_lib_var=`echo socket'_'socket-lnsl | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 6965 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { +socket() +; return 0; } +EOF +if { (eval echo configure:6976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + +fi + +echo $ac_n "checking for inet_addr""... $ac_c" 1>&6 +echo "configure:7003: checking for inet_addr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_inet_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7008 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char inet_addr(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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() { + +/* 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 +inet_addr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:7031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_inet_addr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_inet_addr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'inet_addr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for inet_addr in -lnsl""... $ac_c" 1>&6 +echo "configure:7049: checking for inet_addr in -lnsl" >&5 +if test -n ""; then + ac_lib_var=`echo nsl'_'inet_addr | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo nsl'_'inet_addr | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7061 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char inet_addr(); + +int main() { +inet_addr() +; return 0; } +EOF +if { (eval echo configure:7072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for inet_addr in -linet""... $ac_c" 1>&6 +echo "configure:7091: checking for inet_addr in -linet" >&5 +if test -n ""; then + ac_lib_var=`echo inet'_'inet_addr | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo inet'_'inet_addr | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-linet $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7103 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char inet_addr(); + +int main() { +inet_addr() +; return 0; } +EOF +if { (eval echo configure:7114: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet" +else + echo "$ac_t""no" 1>&6 +echo "configure: warning: unable to find socket() trying -lsocket -lnsl" 1>&2 +echo $ac_n "checking for inet_addr in -lsocket""... $ac_c" 1>&6 +echo "configure:7134: checking for inet_addr in -lsocket" >&5 +if test -n "-lnsl"; then + ac_lib_var=`echo socket'_'inet_addr-lnsl | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo socket'_'inet_addr | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7146 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char inet_addr(); + +int main() { +inet_addr() +; return 0; } +EOF +if { (eval echo configure:7157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + +fi + +echo $ac_n "checking for syslog""... $ac_c" 1>&6 +echo "configure:7184: checking for syslog" >&5 +if eval "test \"`echo '$''{'ac_cv_func_syslog'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7189 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char syslog(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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() { + +/* 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 +syslog(); +#endif + +; return 0; } +EOF +if { (eval echo configure:7212: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_syslog=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_syslog=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'syslog`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for syslog in -lsocket""... $ac_c" 1>&6 +echo "configure:7230: checking for syslog in -lsocket" >&5 +if test -n ""; then + ac_lib_var=`echo socket'_'syslog | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo socket'_'syslog | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7242 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char syslog(); + +int main() { +syslog() +; return 0; } +EOF +if { (eval echo configure:7253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for syslog in -lnsl""... $ac_c" 1>&6 +echo "configure:7272: checking for syslog in -lnsl" >&5 +if test -n ""; then + ac_lib_var=`echo nsl'_'syslog | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo nsl'_'syslog | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7284 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char syslog(); + +int main() { +syslog() +; return 0; } +EOF +if { (eval echo configure:7295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for syslog in -linet""... $ac_c" 1>&6 +echo "configure:7314: checking for syslog in -linet" >&5 +if test -n ""; then + ac_lib_var=`echo inet'_'syslog | sed 'y% ./+-%___p_%'` +else + ac_lib_var=`echo inet'_'syslog | sed 'y%./+-%__p_%'` +fi +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-linet $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7326 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char syslog(); + +int main() { +syslog() +; return 0; } +EOF +if { (eval echo configure:7337: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet" +else + echo "$ac_t""no" 1>&6 +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 $ac_n "checking for working alloca.h""... $ac_c" 1>&6 +echo "configure:7367: checking for working alloca.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7372 "configure" +#include "confdefs.h" +#include <alloca.h> +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:7379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&6 +echo "configure:7400: checking for alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7405 "configure" +#include "confdefs.h" + +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# if HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +#endif + +int main() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if { (eval echo configure:7428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + ac_cv_func_alloca_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_alloca_works=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 +if test $ac_cv_func_alloca_works = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca_works = no; then + # 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.o + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 +echo "configure:7460: checking whether alloca needs Cray hooks" >&5 +if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7465 "configure" +#include "confdefs.h" +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_os_cray" 1>&6 +if test $ac_cv_os_cray = yes; then +for ac_func in _getb67 GETB67 getb67; do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:7490: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 7495 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:7518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<EOF +#define CRAY_STACKSEG_END $ac_func +EOF + + break +else + echo "$ac_t""no" 1>&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:7545: checking stack direction for C alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat > conftest.$ac_ext <<EOF +#line 7553 "configure" +#include "confdefs.h" +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; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:7572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + ac_cv_c_stack_direction=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_stack_direction=-1 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 +cat >> confdefs.h <<EOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +EOF + +fi + +fi + +if test "$with_kerb5" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_KERB5 1 +EOF + + if test -f "/usr/local/include/krb5.h"; then + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + elif test -f "/usr/local/kerberos/include/krb5.h"; then + CPPFLAGS="$CPPFLAGS -I/usr/local/kerberos/include" + elif test -f "/usr/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/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_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 $ac_n "checking for -ldes""... $ac_c" 1>&6 +echo "configure:7652: checking for -ldes" >&5 +if eval "test \"`echo '$''{'ac_cv_lib_des'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldes $LIBS" +cat > conftest.$ac_ext <<EOF +#line 7659 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:7666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + ac_cv_lib_des=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lib_des=no +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +echo "$ac_t""$ac_cv_lib_des" 1>&6 +if test "$ac_cv_lib_des" = yes; then + SUDO_LIBS="${SUDO_LIBS} -lkrb -ldes" +else + SUDO_LIBS="${SUDO_LIBS} -lkrb" +fi + + AUTH_OBJS="${AUTH_OBJS} kerb4.o" +fi + +if test "$with_pam" = "yes"; then + SUDO_LIBS="${SUDO_LIBS} -ldl -lpam" +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 +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 $ac_n "checking for log file location""... $ac_c" 1>&6 +echo "configure:7789: checking for log file location" >&5 +if test -n "$with_logpath"; then + echo "$ac_t""$with_logpath" 1>&6 + cat >> confdefs.h <<EOF +#define _PATH_SUDO_LOGFILE "$with_logpath" +EOF + +elif test -d "/var/log"; then + echo "$ac_t""/var/log/sudo.log" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SUDO_LOGFILE "/var/log/sudo.log" +EOF + +elif test -d "/var/adm"; then + echo "$ac_t""/var/adm/sudo.log" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SUDO_LOGFILE "/var/adm/sudo.log" +EOF + +elif test -d "/usr/adm"; then + echo "$ac_t""/usr/adm/sudo.log" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SUDO_LOGFILE "/usr/adm/sudo.log" +EOF + +else + echo "$ac_t""unknown" 1>&6 +fi + +echo $ac_n "checking for timestamp file location""... $ac_c" 1>&6 +echo "configure:7819: checking for timestamp file location" >&5 +if test -n "$with_timedir"; then + echo "$ac_t""$with_timedir" 1>&6 + cat >> confdefs.h <<EOF +#define _PATH_SUDO_TIMEDIR "$with_timedir" +EOF + +elif test -d "/var/run"; then + echo "$ac_t""/var/run/sudo" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SUDO_TIMEDIR "/var/run/sudo" +EOF + +elif test -d "/tmp"; then + echo "$ac_t""/tmp/.odus" 1>&6 + cat >> confdefs.h <<\EOF +#define _PATH_SUDO_TIMEDIR "/tmp/.odus" +EOF + +else + echo "$ac_t""unknown" 1>&6 +fi + + +if test "$with_passwd" = "no"; then + cat >> confdefs.h <<\EOF +#define WITHOUT_PASSWD 1 +EOF + + if test -z "$AUTH_OBJS"; then + { echo "configure: error: no authentication methods defined." 1>&2; 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)' + +trap '' 1 2 15 +cat > confcache <<\EOF +# 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. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# 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) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile config.h pathnames.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@PROGS@%$PROGS%g +s%@SUDO_LDFLAGS@%$SUDO_LDFLAGS%g +s%@SUDO_LIBS@%$SUDO_LIBS%g +s%@NET_LIBS@%$NET_LIBS%g +s%@AFS_LIBS@%$AFS_LIBS%g +s%@OSDEFS@%$OSDEFS%g +s%@AUTH_OBJS@%$AUTH_OBJS%g +s%@LIBOBJS@%$LIBOBJS%g +s%@MANTYPE@%$MANTYPE%g +s%@MAN_POSTINSTALL@%$MAN_POSTINSTALL%g +s%@SUDOERS_MODE@%$SUDOERS_MODE%g +s%@SUDOERS_UID@%$SUDOERS_UID%g +s%@SUDOERS_GID@%$SUDOERS_GID%g +s%@DEV@%$DEV%g +s%@EGREPPROG@%$EGREPPROG%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@UNAMEPROG@%$UNAMEPROG%g +s%@TRPROG@%$TRPROG%g +s%@SEDPROG@%$SEDPROG%g +s%@NROFFPROG@%$NROFFPROG%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@YACC@%$YACC%g +s%@ALLOCA@%$ALLOCA%g + +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_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # 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" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + 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 "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# 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='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h pathnames.h" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. 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.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# 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.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +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/usr.bin/sudo/configure.in b/usr.bin/sudo/configure.in new file mode 100644 index 00000000000..1cc2c9b9ed6 --- /dev/null +++ b/usr.bin/sudo/configure.in @@ -0,0 +1,1638 @@ +dnl +dnl Process this file with GNU autoconf to produce a configure script. +dnl $Sudo: configure.in,v 1.291 1999/11/08 22:45:42 millert Exp $ +dnl +dnl Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> +dnl +AC_INIT(sudo.h) +AC_CONFIG_HEADER(config.h pathnames.h) +dnl +dnl This won't work before AC_INIT() +dnl +echo "Configuring Sudo version 1.6" +dnl +dnl Variables that get substituted in the Makefile +dnl +AC_SUBST(CFLAGS)dnl must not initialize CFLAGS, it is magic +PROGS="sudo visudo" +AC_SUBST(PROGS)dnl +CPPFLAGS="" +AC_SUBST(CPPFLAGS)dnl +LDFLAGS="" +AC_SUBST(LDFLAGS)dnl +SUDO_LDFLAGS="" +AC_SUBST(SUDO_LDFLAGS)dnl +LIBS="" +AC_SUBST(LIBS)dnl +SUDO_LIBS="" +AC_SUBST(SUDO_LIBS)dnl +NET_LIBS="" +AC_SUBST(NET_LIBS)dnl +AFS_LIBS="" +AC_SUBST(AFS_LIBS)dnl +OSDEFS="" +AC_SUBST(OSDEFS)dnl +AUTH_OBJS="" +AC_SUBST(AUTH_OBJS)dnl +LIBOBJS="" +AC_SUBST(LIBOBJS)dnl +MANTYPE="man" +AC_SUBST(MANTYPE)dnl +MAN_POSTINSTALL="" +AC_SUBST(MAN_POSTINSTALL)dnl +SUDOERS_MODE=0440 +AC_SUBST(SUDOERS_MODE)dnl +SUDOERS_UID=0 +AC_SUBST(SUDOERS_UID)dnl +SUDOERS_GID=0 +AC_SUBST(SUDOERS_GID)dnl +DEV="#" +AC_SUBST(DEV) +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) + 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_DEFINE(WITHOUT_PASSWD) + 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_csops" + ;; +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 + with_insults=yes + 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) + 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) + 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) + AC_MSG_CHECKING(whether to use a two line prompt for OTP authentication) + AC_MSG_RESULT(yes) + ;; + no) ;; + *) 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) + 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 + yes) AC_DEFINE(HAVE_FWTK) + AC_MSG_CHECKING(whether to use FWTK AuthSRV for authentication) + AC_MSG_RESULT(yes) + with_passwd=no + AUTH_OBJS="fwtk.o" + ;; + no) ;; + *) AC_DEFINE(HAVE_FWTK) + AC_MSG_CHECKING(whether to use FWTK AuthSRV for authentication) + AC_MSG_RESULT(yes) + SUDO_LDFLAGS="${SUDO_LDFLAGS} -L${with_fwtk}" + CPPFLAGS="${CPPFLAGS} -I${with_fwtk}" + with_passwd=no + AUTH_OBJS="fwtk.o" + with_fwtk=yes + ;; +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) + 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) + 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) + 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) + 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_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) AC_MSG_RESULT(yes) + ;; + no|none) AC_DEFINE(NO_LECTURE) + AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["unknown argument to --with-lecture: $with_lecture"]) + ;; +esac], [AC_MSG_RESULT(yes)]) + +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) + 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) AC_DEFINE_UNQUOTED(LOGFAC, "$with_logfac") + AC_MSG_RESULT([$with_logfac]) + ;; + *) AC_MSG_ERROR(["$with_logfac is not a supported syslog facility."]) + ;; +esac], [AC_DEFINE_UNQUOTED(LOGFAC, "local2") AC_MSG_RESULT("local2")]) + +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) AC_DEFINE_UNQUOTED(PRI_SUCCESS, "$with_goodpri") + AC_MSG_RESULT([$with_goodpri]) + ;; + *) AC_MSG_ERROR(["$with_goodpri is not a supported syslog priority."]) + ;; +esac], [AC_DEFINE_UNQUOTED(PRI_SUCCESS, "notice") AC_MSG_RESULT("notice")]) + +AC_MSG_CHECKING(at which syslog priority to log failures) +AC_ARG_WITH(badpri, [ --with-badpri syslog priority for failures (def is LOG_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) AC_DEFINE_UNQUOTED(PRI_FAILURE, "$with_badpri") + AC_MSG_RESULT([$with_badpri]) + ;; + *) AC_MSG_ERROR([$with_badpri is not a supported syslog priority.]) + ;; +esac], [AC_DEFINE_UNQUOTED(PRI_FAILURE, "alert") AC_MSG_RESULT("alert")]) + +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]]*) AC_DEFINE_UNQUOTED(MAXLOGFILELEN, $with_loglen) + AC_MSG_RESULT([$with_loglen]) + ;; + *) AC_MSG_ERROR(["you must enter a number, not $with_loglen"]) + ;; +esac], [AC_DEFINE(MAXLOGFILELEN, 80) AC_MSG_RESULT(80)]) + +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) AC_DEFINE(IGNORE_DOT_PATH) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["--with-ignore-dot does not take an argument."]) + ;; +esac], AC_MSG_RESULT(no)) + +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."]) + ;; + *) AC_DEFINE_UNQUOTED(MAILTO, "$with_mailto") + AC_MSG_RESULT([$with_mailto]) + ;; +esac], [AC_DEFINE(MAILTO, "root") AC_MSG_RESULT(root)]) + +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." + ;; + *) AC_DEFINE_UNQUOTED(MAILSUBJECT, "$with_mailsubject") + AC_MSG_CHECKING(sudo mail subject) + AC_MSG_RESULT([Using alert mail subject: $with_mailsubject]) + ;; +esac], AC_DEFINE(MAILSUBJECT, "*** SECURITY information for %h ***")) + +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) AC_DEFINE(SEND_MAIL_WHEN_NO_USER) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["unknown argument to --with-mail-if-no-user: $with_mail_if_no_user"]) + ;; +esac], [AC_DEFINE(SEND_MAIL_WHEN_NO_USER) AC_MSG_RESULT(yes)]) + +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) AC_DEFINE(SEND_MAIL_WHEN_NO_HOST) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["unknown argument to --with-mail-if-no-host: $with_mail_if_no_host"]) + ;; +esac], AC_MSG_RESULT(no)) + +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) AC_DEFINE(SEND_MAIL_WHEN_NOT_OK) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["unknown argument to --with-mail-if-noperms: $with_mail_if_noperms"]) + ;; +esac], AC_MSG_RESULT(no)) + +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." + ;; + *) AC_DEFINE_UNQUOTED(PASSPROMPT, "$with_passprompt") + AC_MSG_RESULT([$with_passprompt]) + ;; +esac], [AC_DEFINE(PASSPROMPT, "Password:") AC_MSG_RESULT(Password:)]) + +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." + ;; + *) AC_DEFINE_UNQUOTED(INCORRECT_PASSWORD, "$with_badpass_message") + AC_MSG_RESULT([$with_badpass_message]) + ;; +esac], [AC_DEFINE(INCORRECT_PASSWORD, ["Sorry, try again."]) AC_MSG_RESULT([Sorry, try again.])]) + +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) AC_DEFINE(FQDN) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["--with-fqdn does not take an argument."]) + ;; +esac], AC_MSG_RESULT(no)) + +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) ;; + *) AC_DEFINE_UNQUOTED(_PATH_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 0022) + --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) AC_MSG_RESULT(user) + ;; + [[0-9]]*) AC_DEFINE_UNQUOTED(SUDO_UMASK, $with_umask) + AC_MSG_RESULT([$with_umask]) + ;; + *) AC_MSG_ERROR(["you must enter a numeric mask."]) + ;; +esac], [AC_DEFINE(SUDO_UMASK, 0022) AC_MSG_RESULT(0022)]) + +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."]) + ;; + *) AC_DEFINE_UNQUOTED(RUNAS_DEFAULT, "$with_runas_default") + AC_MSG_RESULT([$with_runas_default]) + ;; +esac], [AC_DEFINE(RUNAS_DEFAULT, "root") AC_MSG_RESULT(root)]) + +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") + 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") + 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) AC_DEFINE(ENV_EDITOR) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["--with-env-editor does not take an argument."]) + ;; +esac], AC_MSG_RESULT(no)) + +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) AC_DEFINE(TRIES_FOR_PASSWORD, 3) + AC_MSG_RESULT(3) + ;; + no) AC_MSG_ERROR(["--without-editor not supported."]) + ;; + [[1-9]]*) AC_DEFINE_UNQUOTED(TRIES_FOR_PASSWORD, $with_passwd_tries) + AC_MSG_RESULT([$with_passwd_tries]) + ;; + *) AC_MSG_ERROR(["you must enter the numer of tries, > 0"]) + ;; +esac], [AC_DEFINE(TRIES_FOR_PASSWORD, 3) AC_MSG_RESULT(3)]) + +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)], +[echo $with_timeout; case $with_timeout in + yes) AC_DEFINE(TIMEOUT, 5) + AC_MSG_RESULT(5) + ;; + no) AC_DEFINE(TIMEOUT, 0) + AC_MSG_RESULT([no timeout]) + ;; + [[0-9]]*) AC_DEFINE_UNQUOTED(TIMEOUT, $with_timeout) + AC_MSG_RESULT([$with_timeout]) + ;; + *) AC_MSG_ERROR(["you must enter the numer of minutes."]) + ;; +esac], [AC_DEFINE(TIMEOUT, 5) AC_MSG_RESULT(5)]) + +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)], +[case $with_password_timeout in + yes) AC_DEFINE(PASSWORD_TIMEOUT, 5) + AC_MSG_RESULT(5) + ;; + no) AC_DEFINE(PASSWORD_TIMEOUT, 0) + AC_MSG_RESULT([no timeout]) + ;; + [[0-9]]*) AC_DEFINE_UNQUOTED(PASSWORD_TIMEOUT, $with_password_timeout) + AC_MSG_RESULT([$with_password_timeout]) + ;; + *) AC_MSG_ERROR(["you must enter the numer of minutes."]) + ;; +esac], [AC_DEFINE(PASSWORD_TIMEOUT, 5) AC_MSG_RESULT(5)]) + +AC_MSG_CHECKING(whether to use execvp or execv) +AC_ARG_WITH(execv, [ --with-execv use execv() instead of execvp()], +[case $with_execv in + yes) AC_DEFINE(USE_EXECV) + AC_MSG_RESULT(execv) + ;; + no) AC_MSG_RESULT(execvp) + ;; + *) AC_MSG_ERROR(["--with-execv does not take an argument."]) + ;; +esac], AC_MSG_RESULT(execvp)) + +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) AC_DEFINE(USE_TTY_TICKETS) + AC_MSG_RESULT(yes) + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["--with-tty-tickets does not take an argument."]) + ;; +esac], AC_MSG_RESULT(no)) + +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) AC_DEFINE(USE_INSULTS) + AC_MSG_RESULT(yes) + with_classic_insults=yes + with_csops_insults=yes + ;; + no) AC_MSG_RESULT(no) + ;; + *) AC_MSG_ERROR(["--with-insults does not take an argument."]) + ;; +esac], AC_MSG_RESULT(no)) + +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) + ;; + 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) + ;; + 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) + ;; + 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) + ;; + no) ;; + *) AC_MSG_ERROR(["--with-goons-insults does not take an argument."]) + ;; +esac]) + +dnl include all insult sets on one line +if test "$with_insults" = "yes"; 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") + 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) + 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) + ;; + *) AC_MSG_RESULT(no) + echo "Ignoring unknown argument to --enable-authentication: $enableval" + ;; + esac +], AC_MSG_RESULT(yes)) + +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) + 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) + ;; + 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) + ;; + 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) + ;; + 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) + ;; + *) 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 C compiler checks +dnl XXX - the cross-compiler check gets false positives so we override it +dnl +ac_cv_prog_cc_cross="no" +cross_compiling="no" +AC_PROG_CC +ac_cv_prog_cc_cross="no" +cross_compiling="no" +AC_PROG_CPP +AC_ISC_POSIX + +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" +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_FUNC(getpwanam, AC_DEFINE(HAVE_GETPWANAM) AC_CHECK_FUNCS(issecure)) + 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 + ;; + *-*-aix*) + # To get all prototypes (so we pass -Wall) + CPPFLAGS="${CPPFLAGS} -D_XOPEN_EXTENDED_SOURCE" + AC_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 + ;; + *-*-hpux1[[0-9]]*) + # uncomment this for a statically linked sudo + # (XXX - should be an option to configure) + #STATIC_SUDO=true + + if test "$CHECKSHADOW" = "true"; then + AC_CHECK_LIB(sec, getprpwnam, AC_DEFINE(HAVE_GETPRPWNAM) AC_CHECK_LIB(sec, iscomsec, AC_DEFINE(HAVE_ISCOMSEC)) [SUDO_LIBS="${SUDO_LIBS} -lsec"; LIBS="${LIBS} -lsec"; SECUREWARE=1]) + CHECKSHADOW="false" + fi + + if test -n "$STATIC_SUDO"; then + if test -n "$GCC"; then + SUDO_LDFLAGS="${SUDO_LDFLAGS} -static" + else + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive" + fi + fi + + # DCE support (requires ANSI C compiler) + if test "$with_DCE" = "yes"; then + if test -n "$GCC"; then + CPPFLAGS="${CPPFLAGS} -D_HPUX_SOURCE" + else + CPPFLAGS="${CPPFLAGS} -Aa -D_HPUX_SOURCE" + fi + fi + + # AFS support needs -lBSD + if test "$with_AFS" = "yes"; then + AFS_LIBS="-lc -lBSD" + fi + ;; + *-*-hpux9*) + # uncomment this for a statically linked sudo + # (XXX - should be an option to configure) + #STATIC_SUDO=true + + AC_DEFINE(BROKEN_SYSLOG) + + if test "$CHECKSHADOW" = "true"; then + AC_CHECK_FUNCS(getspwuid) + CHECKSHADOW="false" + fi + + if test -n "$STATIC_SUDO"; then + if test -n "$GCC"; then + SUDO_LDFLAGS="${SUDO_LDFLAGS} -static" + else + SUDO_LDFLAGS="${SUDO_LDFLAGS} -Wl,-a,archive" + fi + 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" + + if test -n "$GCC"; then + CPPFLAGS="${CPPFLAGS} -D_HPUX_SOURCE -D_REENTRANT -I/usr/include/reentrant" + else + CPPFLAGS="${CPPFLAGS} -Aa -D_HPUX_SOURCE -D_REENTRANT -I/usr/include/reentrant" + fi + fi + + # AFS support needs -lBSD + if test "$with_AFS" = "yes"; then + AFS_LIBS="-lc -lBSD" + fi + ;; + *-*-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 + ;; + *-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) [ + 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) + # -ldb includes bogus versions of snprintf/vsnprintf + AC_CHECK_FUNC(snprintf, AC_DEFINE(HAVE_SNPRINTF), NEED_SNPRINTF=1) + AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF), NEED_SNPRINTF=1) + # 4.x and higher need -ldb too... + AC_CHECK_LIB(db, dbopen, [SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"], [SUDO_LIBS="${SUDO_LIBS} -lsecurity -ldb -laud -lm"; LIBS="${LIBS} -lsecurity -ldb -laud -lm"]) + AC_CHECK_FUNCS(dispcrypt) + AC_MSG_CHECKING([for broken /usr/include/prot.h]) + AC_TRY_COMPILE([ +#include <sys/types.h> +#include <sys/security.h> +#include <prot.h> + ], [exit(0);], AC_MSG_RESULT(no), + [AC_MSG_RESULT([yes, fixing locally]) + sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h + ]) + else + with_passwd=no + AUTH_OBJS="sia.o" + fi + ;; + *-*-irix*) + # configure may not think irix has stdc headers + # but it's good enough for sudo + AC_DEFINE(STDC_HEADERS) + 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 + ;; + *-*-linux*) + # To get crypt(3) and vasprintf() prototypes (so we pass -Wall) + AC_DEFINE(_GNU_SOURCE) + + # Some Linux versions need to link with -lshadow + if test "$CHECKSHADOW" = "true"; then + AC_CHECK_FUNC(getspnam, AC_DEFINE(HAVE_GETSPNAM), AC_CHECK_LIB(shadow, getspnam, AC_DEFINE(HAVE_GETSPNAM) [SUDO_LIBS="${SUDO_LIBS} -lshadow"; LIBS="${LIBS} -lshadow"])) + CHECKSHADOW="false" + fi + ;; + *-convex-bsd*) + AC_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) [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" + ;; + *-*-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 + ;; + *-*-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 + ;; + *-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 + ;; + *-ccur-sysv4|*-ccur-sysvr4) + LIBS="${LIBS} -lgen" + SUDO_LIBS="${SUDO_LIBS} -lgen" + ;; + *-*-bsdi*) + # Use shlicc for BSD/OS 2.x unless asked to do otherwise + if test "$OSREV" -ge 2 -a "${with_CC+set}" != set -a \ + "$ac_cv_prog_CC" = "gcc"; then + echo 'using shlicc as CC' + ac_cv_prog_CC=shlicc + CC="$ac_cv_prog_CC" + fi + ;; + *-*-*bsd*) + if test "$CHECKSHADOW" = "true"; then + CHECKSHADOW="false" + fi + ;; +esac + +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_FUNC(getspnam, AC_DEFINE(HAVE_GETSPNAM) [CHECKSHADOW="false"]) +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 +dnl +dnl Program checks +dnl +AC_PROG_YACC +if test -z "$with_sendmail"; then + SUDO_PROG_SENDMAIL +fi +SUDO_PROG_MV +SUDO_PROG_BSHELL +SUDO_PROG_VI +dnl +dnl Header file checks +dnl +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_CHECK_HEADERS(string.h strings.h unistd.h malloc.h paths.h utime.h fnmatch.h netgroup.h sys/sockio.h sys/bsdtypes.h sys/select.h) +dnl ultrix termio/termios are broken +if test "$OS" != "ultrix"; then + AC_CHECK_HEADERS(termio.h) + AC_CHECK_HEADERS(termios.h, AC_CHECK_FUNCS(tcgetattr)) +fi +dnl +dnl typedef checks +dnl +AC_TYPE_MODE_T +AC_TYPE_UID_T +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 sigaction tzset seteuid ftruncate strftime setrlimit) +if test -n "$SECUREWARE"; then + AC_CHECK_FUNCS(bigcrypt) + AC_CHECK_FUNCS(set_auth_parameters) + AC_CHECK_FUNCS(initprivs) +fi +if test -z "$BROKEN_GETCWD"; then + AC_CHECK_FUNC(getcwd, AC_DEFINE(HAVE_GETCWD), LIBOBJS="$LIBOBJS getcwd.o") +fi +AC_CHECK_FUNC(lockf, AC_DEFINE(HAVE_LOCKF), AC_CHECK_FUNCS(flock)) +AC_CHECK_FUNC(waitpid, AC_DEFINE(HAVE_WAITPID), AC_CHECK_FUNCS(wait3)) +AC_CHECK_FUNC(innetgr, AC_DEFINE(HAVE_INNETGR) AC_CHECK_FUNCS(getdomainname)) +AC_CHECK_FUNC(lsearch, AC_DEFINE(HAVE_LSEARCH), AC_CHECK_LIB(compat, lsearch, AC_CHECK_HEADER(search.h, AC_DEFINE(HAVE_LSEARCH) [LIBS="${LIBS} -lcompat"], LIBOBJS="$LIBOBJS lsearch.o"), LIBOBJS="$LIBOBJS lsearch.o")) +AC_CHECK_FUNC(setenv, AC_DEFINE(HAVE_SETENV), AC_FUNC_CHECK(putenv, AC_DEFINE(HAVE_PUTENV), LIBOBJS="$LIBOBJS putenv.o")) +AC_CHECK_FUNC(utime, AC_DEFINE(HAVE_UTIME) +SUDO_FUNC_UTIME_POSIX, LIBOBJS="$LIBOBJS utime.o") +SUDO_FUNC_FNMATCH(AC_DEFINE(HAVE_FNMATCH), LIBOBJS="$LIBOBJS fnmatch.o") +AC_REPLACE_FUNCS(strerror strcasecmp) +AC_CHECK_FUNC(snprintf, AC_DEFINE(HAVE_SNPRINTF), NEED_SNPRINTF=1) +AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF), NEED_SNPRINTF=1) +AC_CHECK_FUNC(asprintf, AC_DEFINE(HAVE_ASPRINTF), NEED_SNPRINTF=1) +AC_CHECK_FUNC(vasprintf, AC_DEFINE(HAVE_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 + LIBOBJS="$LIBOBJS snprintf.o" +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_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 socket() 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) + 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/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/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 Find kerberos 4 includes and libs or complain +dnl +if test "$with_kerb4" = "yes"; then + AC_DEFINE(HAVE_KERB4) + 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 PAM libs +dnl +if test "$with_pam" = "yes"; then + SUDO_LIBS="${SUDO_LIBS} -ldl -lpam" +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 +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) + 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 Makefiles +dnl +AC_OUTPUT(Makefile) + +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 diff --git a/usr.bin/sudo/defaults.c b/usr.bin/sudo/defaults.c new file mode 100644 index 00000000000..11b57d6cc11 --- /dev/null +++ b/usr.bin/sudo/defaults.c @@ -0,0 +1,679 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <sys/types.h> +#include <sys/param.h> + +#include "sudo.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: defaults.c,v 1.12 1999/11/05 22:11:55 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_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)); + +/* + * Table describing compile-time and run-time options. + */ +struct sudo_defs_types sudo_defs_table[] = { + { + "syslog_ifac", T_INT, { 0 }, + NULL + }, { + "syslog_igoodpri", T_INT, { 0 }, + NULL + }, { + "syslog_ibadpri", T_INT, { 0 }, + NULL + }, { + "syslog", T_LOGFAC|T_BOOL, { 0 }, + "Syslog facility if syslog is being used for logging: %s" + }, { + "syslog_goodpri", T_LOGPRI, { 0 }, + "Syslog priority to use when user authenticates successfully: %s" + }, { + "syslog_badpri", T_LOGPRI, { 0 }, + "Syslog priority to use when user authenticates unsuccessfully: %s" + }, { + "long_otp_prompt", T_FLAG, { 0 }, + "Put OTP prompt on its own line" + }, { + "ignore_dot", T_FLAG, { 0 }, + "Ignore '.' in $PATH" + }, { + "mail_always", T_FLAG, { 0 }, + "Always send mail when sudo is run" + }, { + "mail_no_user", T_FLAG, { 0 }, + "Send mail if the user is not in sudoers" + }, { + "mail_no_host", T_FLAG, { 0 }, + "Send mail if the user is not in sudoers for this host" + }, { + "mail_no_perms", T_FLAG, { 0 }, + "Send mail if the user is not allowed to run a command" + }, { + "tty_tickets", T_FLAG, { 0 }, + "Use a separate timestamp for each user/tty combo" + }, { + "lecture", T_FLAG, { 0 }, + "Lecture user the first time they run sudo" + }, { + "authenticate", T_FLAG, { 0 }, + "Require users to authenticate by default" + }, { + "root_sudo", T_FLAG, { 0 }, + "Root may run sudo" + }, { + "log_host", T_FLAG, { 0 }, + "Log the hostname in the (non-syslog) log file" + }, { + "log_year", T_FLAG, { 0 }, + "Log the year in the (non-syslog) log file" + }, { + "shell_noargs", T_FLAG, { 0 }, + "If sudo is invoked with no arguments, start a shell" + }, { + "set_home", T_FLAG, { 0 }, + "Set $HOME to the target user when starting a shell with -s" + }, { + "path_info", T_FLAG, { 0 }, + "Allow some information gathering to give useful error messages" + }, { + "fqdn", T_FLAG, { 0 }, + "Require fully-qualified hsotnames in the sudoers file" + }, { + "insults", T_FLAG, { 0 }, + "Insult the user when they enter an incorrect password" + }, { + "requiretty", T_FLAG, { 0 }, + "Only allow the user to run sudo if they have a tty" + }, { + "loglinelen", T_INT|T_BOOL, { 0 }, + "Length at which to wrap log file lines (0 for no wrap): %d" + }, { + "timestamp_timeout", T_INT|T_BOOL, { 0 }, + "Authentication timestamp timeout: %d minutes" + }, { + "passwd_timeout", T_INT|T_BOOL, { 0 }, + "Password prompt timeout: %d minutes" + }, { + "passwd_tries", T_INT, { 0 }, + "Number of tries to enter a password: %d" + }, { + "umask", T_MODE|T_BOOL, { 0 }, + "Umask to use or 0777 to use user's: 0%o" + }, { + "logfile", T_STR|T_BOOL|T_PATH, { 0 }, + "Path to log file: %s" + }, { + "mailerpath", T_STR|T_BOOL|T_PATH, { 0 }, + "Path to mail program: %s" + }, { + "mailerflags", T_STR|T_BOOL, { 0 }, + "Flags for mail program: %s" + }, { + "mailto", T_STR|T_BOOL, { 0 }, + "Address to send mail to: %s" + }, { + "mailsub", T_STR, { 0 }, + "Subject line for mail messages: %s" + }, { + "badpass_message", T_STR, { 0 }, + "Incorrect password message: %s" + }, { + "timestampdir", T_STR|T_PATH, { 0 }, + "Path to authentication timestamp dir: %s" + }, { + "exempt_group", T_STR|T_BOOL, { 0 }, + "Users in this group are exempt from password and PATH requirements: %s" + }, { + "passprompt", T_STR, { 0 }, + "Default password prompt: %s" + }, { + "runas_default", T_STR, { 0 }, + "Default user to run commands as: %s" + }, { + "secure_path", T_STR|T_BOOL, { 0 }, + "Value to override user's $PATH with: %s" + }, { + NULL, 0, { 0 }, NULL + } +}; + +/* + * Print version and configure info. + */ +void +dump_defaults() +{ + struct sudo_defs_types *cur; + + 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: + if (cur->sd_un.str) { + (void) printf(cur->desc, cur->sd_un.str); + putchar('\n'); + } + break; + 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; + } + } + } + +#ifdef ENV_EDITOR + (void) printf("Default editor for visudo: %s\n", EDITOR); +#else + (void) printf("Editor for visudo: %s\n", EDITOR); +#endif +} + +/* + * 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, 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; + + for (cur = sudo_defs_table; cur->name; cur++) { + 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_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 != '/') { + (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_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; + break; + } + + 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: + if (def->sd_un.str) { + free(def->sd_un.str); + def->sd_un.str = NULL; + } + 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_NOUSER) = TRUE; +#endif +#ifdef SEND_MAIL_WHEN_NO_HOST + def_flag(I_MAIL_NOHOST) = TRUE; +#endif +#ifdef SEND_MAIL_WHEN_NOT_OK + def_flag(I_MAIL_NOPERMS) = 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 + + /* Syslog options need special care since they both strings and ints */ +#if (LOGGING & SLOG_SYSLOG) + (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_LOGFACSTR], TRUE); + (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_GOODPRISTR], TRUE); + (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_BADPRISTR], TRUE); +#endif + + /* 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_LOGLEN) = MAXLOGFILELEN; + def_ival(I_TS_TIMEOUT) = TIMEOUT; + def_ival(I_PW_TIMEOUT) = PASSWORD_TIMEOUT; + def_ival(I_PW_TRIES) = TRIES_FOR_PASSWORD; + + /* Finally do the strings */ + def_str(I_MAILTO) = estrdup(MAILTO); + def_str(I_MAILSUB) = estrdup(MAILSUBJECT); + def_str(I_BADPASS_MSG) = estrdup(INCORRECT_PASSWORD); + def_str(I_TIMESTAMPDIR) = estrdup(_PATH_SUDO_TIMEDIR); + def_str(I_PASSPROMPT) = estrdup(PASSPROMPT); + def_str(I_RUNAS_DEF) = estrdup(RUNAS_DEFAULT); +#ifdef _PATH_SENDMAIL + def_str(I_MAILERPATH) = estrdup(_PATH_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_GRP) = estrdup(EXEMPTGROUP); +#endif +#ifdef SECURE_PATH + def_str(I_SECURE_PATH) = estrdup(SECURE_PATH); +#endif + + /* + * 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_DEF); + + 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' || 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_syslogfac(val, def, op) + char *val; + struct sudo_defs_types *def; + int op; +{ + struct strmap *fac; + + if (op == FALSE) { + 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_GOODPRISTR]) + idef = &sudo_defs_table[I_GOODPRI]; + else if (def == &sudo_defs_table[I_BADPRISTR]) + 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); +} diff --git a/usr.bin/sudo/defaults.h b/usr.bin/sudo/defaults.h new file mode 100644 index 00000000000..386a7e2be9b --- /dev/null +++ b/usr.bin/sudo/defaults.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: defaults.h,v 1.7 1999/10/11 16:24:02 millert Exp $ + */ + +#ifndef _SUDO_DEFAULTS_H +#define _SUDO_DEFAULTS_H + +/* + * Structure describing compile-time and run-time options. + */ +struct sudo_defs_types { + char *name; + int type; + union { + int flag; + char *str; + unsigned int ival; + mode_t mode; + } sd_un; + char *desc; +}; + +/* + * 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_STR +#define T_STR 0x002 +#undef T_FLAG +#define T_FLAG 0x003 +#undef T_MODE +#define T_MODE 0x004 +#undef T_LOGFAC +#define T_LOGFAC 0x005 +#undef T_LOGPRI +#define T_LOGPRI 0x006 +#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 + */ + +/* Integer versions of syslog options. */ +#define I_LOGFAC 0 /* syslog facility */ +#define I_GOODPRI 1 /* syslog priority for successful auth */ +#define I_BADPRI 2 /* syslog priority for unsuccessful auth */ + +/* String versions of syslog options. */ +#define I_LOGFACSTR 3 /* syslog facility */ +#define I_GOODPRISTR 4 /* syslog priority for successful auth */ +#define I_BADPRISTR 5 /* syslog priority for unsuccessful auth */ + +/* Booleans */ +#define I_LONG_OTP_PROMPT 6 +#define I_IGNORE_DOT 7 +#define I_MAIL_ALWAYS 8 +#define I_MAIL_NOUSER 9 +#define I_MAIL_NOHOST 10 +#define I_MAIL_NOPERMS 11 +#define I_TTY_TICKETS 12 +#define I_LECTURE 13 +#define I_AUTHENTICATE 14 +#define I_ROOT_SUDO 15 +#define I_LOG_HOST 16 +#define I_LOG_YEAR 17 +#define I_SHELL_NOARGS 18 +#define I_SET_HOME 19 +#define I_PATH_INFO 20 +#define I_FQDN 21 +#define I_INSULTS 22 +#define I_REQUIRETTY 23 + +/* Integer values */ +#define I_LOGLEN 24 /* wrap log file line after N chars */ +#define I_TS_TIMEOUT 25 /* timestamp stale after N minutes */ +#define I_PW_TIMEOUT 26 /* exit if pass not entered in N minutes */ +#define I_PW_TRIES 27 /* exit after N bad password tries */ +#define I_UMASK 28 /* umask to use or 0777 to use user's */ + +/* Strings */ +#define I_LOGFILE 29 /* path to logfile (or NULL for none) */ +#define I_MAILERPATH 30 /* path to sendmail or other mailer */ +#define I_MAILERFLAGS 31 /* flags to pass to the mailer */ +#define I_MAILTO 32 /* who to send bitch mail to */ +#define I_MAILSUB 33 /* subject line of mail msg */ +#define I_BADPASS_MSG 34 /* what to say when passwd is wrong */ +#define I_TIMESTAMPDIR 35 /* path to timestamp dir */ +#define I_EXEMPT_GRP 36 /* no password or PATH override for these */ +#define I_PASSPROMPT 37 /* password prompt */ +#define I_RUNAS_DEF 38 /* default user to run commands as */ +#define I_SECURE_PATH 39 /* set $PATH to this if not NULL */ + +/* + * 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_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/usr.bin/sudo/fileops.c b/usr.bin/sudo/fileops.c new file mode 100644 index 00000000000..dc8444419c3 --- /dev/null +++ b/usr.bin/sudo/fileops.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#include <fcntl.h> +#include <time.h> +#include <sys/types.h> +#include <sys/param.h> +#ifdef HAVE_UTIME +# ifdef HAVE_UTIME_H +# include <utime.h> +# endif /* HAVE_UTIME_H */ +#else +# include "emul/utime.h" +#endif /* HAVE_UTIME */ + +#include "sudo.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: fileops.c,v 1.1 1999/08/07 09:59:43 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_EX; + 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/usr.bin/sudo/find_path.c b/usr.bin/sudo/find_path.c new file mode 100644 index 00000000000..4d84b4e79dc --- /dev/null +++ b/usr.bin/sudo/find_path.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <errno.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> + +#include "sudo.h" + +#ifndef STDC_HEADERS +extern char *getenv __P((const char *)); +extern char *strcpy __P((char *, const char *)); +extern int fprintf __P((FILE *, const char *, ...)); +extern ssize_t readlink __P((const char *, VOID *, size_t)); +extern int stat __P((const char *, struct stat *)); +extern int lstat __P((const char *, struct stat *)); +#endif /* !STDC_HEADERS */ + +#ifndef lint +static const char rcsid[] = "$Sudo: find_path.c,v 1.94 1999/10/07 21:20:57 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) + char *infile; /* file to find */ + char **outfile; /* result parameter */ +{ + static char command[MAXPATHLEN]; /* qualified filename */ + char *n; /* for traversing path */ + char *path = NULL; /* contents of PATH env var */ + char *origpath; /* so we can free path later */ + char *result = NULL; /* result of path/file lookup */ + int checkdot = 0; /* check current dir? */ + + 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); + } + + /* + * Grab PATH out of the environment (or from the string table + * if SECURE_PATH is in effect) and make a local copy. + */ + if (def_str(I_SECURE_PATH)) + path = def_str(I_SECURE_PATH); + else if ((path = getenv("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/usr.bin/sudo/getspwuid.c b/usr.bin/sudo/getspwuid.c new file mode 100644 index 00000000000..6205aea1412 --- /dev/null +++ b/usr.bin/sudo/getspwuid.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <pwd.h> +#ifdef HAVE_GETSPNAM +# include <shadow.h> +#endif /* HAVE_GETSPNAM */ +#ifdef HAVE_GETPRPWNAM +# ifdef __hpux +# undef MAXINT +# include <hpsecurity.h> +# else +# include <sys/security.h> +# endif /* __hpux */ +# include <prot.h> +#endif /* HAVE_GETPRPWNAM */ +#ifdef HAVE_GETPWANAM +# include <sys/label.h> +# include <sys/audit.h> +# include <pwdadj.h> +#endif /* HAVE_GETPWANAM */ +#ifdef HAVE_GETAUTHUID +# include <auth.h> +#endif /* HAVE_GETAUTHUID */ + +#include "sudo.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: getspwuid.c,v 1.55 1999/10/07 21:20:57 millert Exp $"; +#endif /* lint */ + +#ifndef STDC_HEADERS +extern char *getenv __P((const char *)); +#endif /* !STDC_HEADERS */ + +/* + * 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 char *sudo_getshell __P((struct passwd *)); +static char *sudo_getepw __P((struct passwd *)); + + +/* + * Return the user's shell based on either the SHELL + * environment variable or the passwd(5) entry (in that order). + */ +static char * +sudo_getshell(pw) + struct passwd *pw; +{ + char *pw_shell; + + if ((pw_shell = getenv("SHELL")) == NULL) + pw_shell = pw->pw_shell; + +#ifdef _PATH_BSHELL + /* empty string "" means bourne shell */ + if (*pw_shell == '\0') + pw_shell = _PATH_BSHELL; +#endif /* _PATH_BSHELL */ + + return(pw_shell); +} + +/* + * Return the encrypted password for the user described by pw. If shadow + * passwords are in use, look in the shadow file. + */ +static char * +sudo_getepw(pw) + struct passwd *pw; +{ + + /* If there is a function to check for shadow enabled, use it... */ +#ifdef HAVE_ISCOMSEC + if (!iscomsec()) + return(pw->pw_passwd); +#endif /* HAVE_ISCOMSEC */ +#ifdef HAVE_ISSECURE + if (!issecure()) + return(pw->pw_passwd); +#endif /* HAVE_ISSECURE */ + +#ifdef HAVE_GETPRPWNAM + { + struct pr_passwd *spw; + + spw = getprpwnam(pw->pw_name); + if (spw != NULL && spw->ufld.fd_encrypt != NULL) { +# ifdef __alpha + crypt_type = spw->ufld.fd_oldcrypt; +# endif /* __alpha */ + return(spw->ufld.fd_encrypt); + } + } +#endif /* HAVE_GETPRPWNAM */ +#ifdef HAVE_GETSPNAM + { + struct spwd *spw; + + if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp) + return(spw->sp_pwdp); + } +#endif /* HAVE_GETSPNAM */ +#ifdef HAVE_GETSPWUID + { + struct s_passwd *spw; + + if ((spw = getspwuid(pw->pw_uid)) && spw->pw_passwd) + return(spw->pw_passwd); + } +#endif /* HAVE_GETSPWUID */ +#ifdef HAVE_GETPWANAM + { + struct passwd_adjunct *spw; + + if ((spw = getpwanam(pw->pw_name)) && spw->pwa_passwd) + return(spw->pwa_passwd); + } +#endif /* HAVE_GETPWANAM */ +#ifdef HAVE_GETAUTHUID + { + AUTHORIZATION *spw; + + if ((spw = getauthuid(pw->pw_uid)) && spw->a_password) + return(spw->a_password); + } +#endif /* HAVE_GETAUTHUID */ + + /* Fall back on normal password. */ + return(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. + */ +struct passwd * +sudo_getpwuid(uid) + uid_t uid; +{ + struct passwd *pw, *local_pw; + + if ((pw = getpwuid(uid)) == NULL) + return(NULL); + + /* 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); + + /* pw_shell is a special case since we overide with $SHELL */ + local_pw->pw_shell = estrdup(sudo_getshell(pw)); + + /* pw_passwd gets a shadow password if applicable */ + local_pw->pw_passwd = estrdup(sudo_getepw(pw)); + + return(local_pw); +} diff --git a/usr.bin/sudo/goodpath.c b/usr.bin/sudo/goodpath.c new file mode 100644 index 00000000000..862ac9697ab --- /dev/null +++ b/usr.bin/sudo/goodpath.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include "sudo.h" + +#ifndef STDC_HEADERS +extern int stat __P((const char *, struct stat *)); +#endif /* !STDC_HEADERS */ + +#ifndef lint +static const char rcsid[] = "$Sudo: goodpath.c,v 1.37 1999/08/20 20:37:14 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/usr.bin/sudo/indent.pro b/usr.bin/sudo/indent.pro new file mode 100644 index 00000000000..b8269d84ab3 --- /dev/null +++ b/usr.bin/sudo/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/usr.bin/sudo/ins_2001.h b/usr.bin/sudo/ins_2001.h new file mode 100644 index 00000000000..bd29863c124 --- /dev/null +++ b/usr.bin/sudo/ins_2001.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: ins_2001.h,v 1.28 1999/07/31 16:19:45 millert Exp $ + */ + +#ifndef _SUDO_INS_2001_H +#define _SUDO_INS_2001_H + + /* + * HAL insults (paraphrased) from 2001. + */ + + "Just what do you think you're doing Dave?", + "It can only be attributed to human error.", + "That's something I cannot allow to happen.", + "My mind is going. I can feel it.", + "Sorry about this, I know it's a bit silly.", + "Take a stress pill and think things over.", + "This mission is too important for me to allow you to jeopardize it.", + "I feel much better now.", + +#endif /* _SUDO_INS_2001_H */ diff --git a/usr.bin/sudo/ins_classic.h b/usr.bin/sudo/ins_classic.h new file mode 100644 index 00000000000..975f381a1ff --- /dev/null +++ b/usr.bin/sudo/ins_classic.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: ins_classic.h,v 1.28 1999/07/31 16:19:45 millert Exp $ + */ + +#ifndef _SUDO_INS_CLASSIC_H +#define _SUDO_INS_CLASSIC_H + + /* + * Insults from the original sudo(8). + */ + + "Wrong! You cheating scum!", + "No soap, honkie-lips.", + "Where did you learn to type?", + "Are you on drugs?", + "My pet ferret can type better than you!", + "You type like i drive.", + "Do you think like you type?", + "Your mind just hasn't been the same since the electro-shock, has it?", + +#endif /* _SUDO_INS_CLASSIC_H */ diff --git a/usr.bin/sudo/ins_csops.h b/usr.bin/sudo/ins_csops.h new file mode 100644 index 00000000000..3baac82db36 --- /dev/null +++ b/usr.bin/sudo/ins_csops.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: ins_csops.h,v 1.27 1999/07/31 16:19:45 millert Exp $ + */ + +#ifndef _SUDO_INS_CSOPS_H +#define _SUDO_INS_CSOPS_H + + /* + * CSOps insults (may be site dependent). + */ + + "Maybe if you used more than just two fingers...", + "BOB says: You seem to have forgotten your passwd, enter another!", + "stty: unknown mode: doofus", + "I can't hear you -- I'm using the scrambler.", + "The more you drive -- the dumber you get.", + "Listen, burrito brains, I don't have time to listen to this trash.", + "I've seen penguins that can type better than that.", + "Have you considered trying to match wits with a rutabaga?", + "You speak an infinite deal of nothing", + +#endif /* _SUDO_INS_CSOPS_H */ diff --git a/usr.bin/sudo/ins_goons.h b/usr.bin/sudo/ins_goons.h new file mode 100644 index 00000000000..4cf6462eb01 --- /dev/null +++ b/usr.bin/sudo/ins_goons.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: ins_goons.h,v 1.28 1999/07/31 16:19:45 millert Exp $ + */ + +#ifndef _SUDO_INS_GOONS_H +#define _SUDO_INS_GOONS_H + + /* + * Insults from the "Goon Show." + */ + + "You silly, twisted boy you.", + "He has fallen in the water!", + "We'll all be murdered in our beds!", + "You can't come in. Our tiger has got flu", + "I don't wish to know that.", + "What, what, what, what, what, what, what, what, what, what?", + "You can't get the wood, you know.", + "You'll starve!", + "... and it used to be so popular...", + "Pauses for audience applause, not a sausage", + "Hold it up to the light --- not a brain in sight!", + "Have a gorilla...", + "There must be cure for it!", + "There's a lot of it about, you know.", + "You do that again and see what happens...", + "Ying Tong Iddle I Po", + "Harm can come to a young lad like that!", + "And with that remarks folks, the case of the Crown vs yourself was proven.", + "Speak English you fool --- there are no subtitles in this scene.", + "You gotta go owwwww!", + "I have been called worse.", + "It's only your word against mine.", + "I think ... err ... I think ... I think I'll go home", + +#endif /* _SUDO_INS_GOONS_H */ diff --git a/usr.bin/sudo/install-sh b/usr.bin/sudo/install-sh new file mode 100644 index 00000000000..6056dda81df --- /dev/null +++ b/usr.bin/sudo/install-sh @@ -0,0 +1,261 @@ +#! /bin/sh + +## (From INN-1.4, written by Rich Salz) +## $Revision: 1.1 $ +## 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=whoami + +## Some systems don't support -x, so we have to use -f. +if [ ${CHOWN} = chown ] ; then + if [ -f /etc/chown ] ; then + CHOWN=/etc/chown + elif [ -f /usr/etc/chown ] ; then + CHOWN=/usr/etc/chown + elif [ -f /usr/sbin/chown ] ; then + CHOWN=/usr/sbin/chown + fi +fi + +if [ ${WHOAMI} = whoami ] ; then + if [ -f /usr/ucb/whoami ] ; then + WHOAMI=/usr/ucb/whoami + elif [ -f /usr/bin/whoami ] ; then + WHOAMI=/usr/bin/whoami + fi +fi + +if [ ${STRIP} = strip ] ; then + if [ -f /usr/ccs/bin/strip ] ; then + STRIP=/usr/ccs/bin/strip + elif [ -f /usr/bin/strip ] ; then + STRIP=/usr/bin/strip + fi +fi + +## Defaults. +CHOWNIT=false +CHGROUPIT=false +CHMODIT=false +STRIPIT=false +BACKIT=false +TOUCHIT=true +SAVESRC=false +ROOT=unknown + +## 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) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + GROUP="$2" + shift + ${ROOT} && CHGROUPIT=true + ;; + X-G*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + 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-n) + TOUCHIT=false + ;; + X-o) + OWNER="$2" + CHOWNIT=true + shift + ;; + X-o*) + OWNER=`expr "$1" : '-o\(.*\)'` + CHOWNIT=true + ;; + X-O) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + OWNER="$2" + shift + ${ROOT} && CHOWNIT=true + ;; + X-O*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + 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/usr.bin/sudo/insults.h b/usr.bin/sudo/insults.h new file mode 100644 index 00000000000..59b2e8a814c --- /dev/null +++ b/usr.bin/sudo/insults.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: insults.h,v 1.43 1999/07/31 16:19:46 millert Exp $ + */ + +#ifndef _SUDO_INSULTS_H +#define _SUDO_INSULTS_H + +#ifdef USE_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 /* USE_INSULTS */ + +#endif /* _SUDO_INSULTS_H */ diff --git a/usr.bin/sudo/interfaces.c b/usr.bin/sudo/interfaces.c new file mode 100644 index 00000000000..eee9d1fe9cc --- /dev/null +++ b/usr.bin/sudo/interfaces.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * 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 <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <netdb.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#if defined(HAVE_SYS_SOCKIO_H) && !defined(SIOCGIFCONF) +#include <sys/sockio.h> +#endif +#ifdef _ISC +#include <sys/stream.h> +#include <sys/sioctl.h> +#include <sys/stropts.h> +#include <net/errno.h> +#define STRSET(cmd, param, len) {strioctl.ic_cmd=(cmd);\ + strioctl.ic_dp=(param);\ + strioctl.ic_timout=0;\ + strioctl.ic_len=(len);} +#endif /* _ISC */ +#ifdef _MIPS +#include <net/soioctl.h> +#endif /* _MIPS */ +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> + +#include "sudo.h" +#include "interfaces.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: interfaces.c,v 1.59 1999/08/12 16:24:09 millert Exp $"; +#endif /* lint */ + + +#if 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 */ diff --git a/usr.bin/sudo/interfaces.h b/usr.bin/sudo/interfaces.h new file mode 100644 index 00000000000..2f57724faba --- /dev/null +++ b/usr.bin/sudo/interfaces.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: interfaces.h,v 1.3 1999/07/31 16:19:46 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)); + +/* + * Definitions for external variables. + */ +#ifndef MAIN +extern struct interface *interfaces; +extern int num_interfaces; +#endif + +#endif /* _SUDO_INTERFACES_H */ diff --git a/usr.bin/sudo/logging.c b/usr.bin/sudo/logging.c new file mode 100644 index 00000000000..2addc043562 --- /dev/null +++ b/usr.bin/sudo/logging.c @@ -0,0 +1,587 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <pwd.h> +#include <signal.h> +#include <time.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include "sudo.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: logging.c,v 1.139 1999/10/09 05:01:48 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)); + +#ifdef BROKEN_SYSLOG +# define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ +# define SYSLOG syslog_wrapper + +static void syslog_wrapper __P((int, char *, char *, char *)); + +/* + * 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... + */ +static void +syslog_wrapper(pri, fmt, ap) + int pri; + const char *fmt; + va_list ap; +{ + int i; + + for (i = 0; i < MAXSYSLOGTRIES; i++) + if (vsyslog(pri, fmt, ap) == 0) + break; +} +#else +# define SYSLOG syslog +#endif /* BROKEN_SYSLOG */ + +/* + * 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; 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) + SYSLOG(pri, "%8.8s : %s", user_name, p); + else + SYSLOG(pri, "%8.8s : (command continued) %s", user_name, p); + + *tmp = save; /* restore saved character */ + + /* Eliminate leading whitespace */ + for (p = tmp; *p != ' '; p++) + ; + } else { + if (count == 0) + SYSLOG(pri, "%8.8s : %s", user_name, p); + else + SYSLOG(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_LOGLEN); + + 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_LOGLEN) == 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_LOGFACSTR)) + 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_LOGFACSTR)) + do_syslog(def_ival(I_BADPRI), logline); + if (def_str(I_LOGFILE)) + do_logfile(logline); + + free(logline); + if (message != logline); + free(message); + + 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; + + /* Just return if mailer is disabled. */ + if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO)) + return; + + if ((pid = fork()) > 0) { /* Child. */ + + /* We do an explicit wait() later on... */ + (void) signal(SIGCHLD, SIG_IGN); + + 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. */ + /* XXX - parent will continue, return an exit val to + let parent know and abort? */ + (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; + + /* Grandchild. */ + (void) close(pfd[1]); + (void) dup2(pfd[0], STDIN_FILENO); + (void) close(pfd[0]); + + /* 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; + + /* Run mailer as root so user cannot kill it. */ + set_perms(PERM_ROOT, 0); + execv(mpath, argv); + _exit(127); + } + break; + } + + mail = fdopen(pfd[1], "w"); + (void) close(pfd[0]); + + /* 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); + reapchild(0); + _exit(0); + } else { + /* Parent, just return unless there is an error. */ + if (pid == -1) { + (void) fprintf(stderr, "%s: cannot fork: %s\n", + Argv[0], strerror(errno)); + exit(1); + } + } +} + +/* + * 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_NOUSER)) + mail_mask |= FLAG_NO_USER; + if (def_flag(I_MAIL_NOHOST)) + mail_mask |= FLAG_NO_HOST; + if (def_flag(I_MAIL_NOPERMS)) + 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) + ; +#else + (void) wait(&status); +#endif +#ifndef POSIX_SIGNALS + (void) signal(SIGCHLD, reapchild); +#endif /* POSIX_SIGNALS */ + 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/usr.bin/sudo/logging.h b/usr.bin/sudo/logging.h new file mode 100644 index 00000000000..da4b02af3e0 --- /dev/null +++ b/usr.bin/sudo/logging.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOGGING_H +#define _LOGGING_H + +#include <syslog.h> +#ifdef __STDC__ +# include <stdarg.h> +#else +# include <varargs.h> +#endif + +/* Logging types */ +#define SLOG_SYSLOG 0x01 +#define SLOG_FILE 0x02 +#define SLOG_BOTH 0x03 + +/* Flags for log_error() */ +#define MSG_ONLY 0x01 +#define USE_ERRNO 0x02 +#define NO_MAIL 0x04 +#define NO_EXIT 0x08 + +/* + * Maximum number of characters to log per entry. The syslogger + * will log this much, after that, it truncates the log line. + * We need this here to make sure that we continue with another + * syslog(3) call if the internal buffer is more than 1023 characters. + */ +#ifndef MAXSYSLOGLEN +# define MAXSYSLOGLEN 960 +#endif + +void log_auth __P((int, int)); +void log_error __P((int flags, const char *fmt, ...)); +RETSIGTYPE reapchild __P((int)); + +#endif /* _LOGGING_H */ diff --git a/usr.bin/sudo/mkinstalldirs b/usr.bin/sudo/mkinstalldirs new file mode 100644 index 00000000000..91f6d04e17c --- /dev/null +++ b/usr.bin/sudo/mkinstalldirs @@ -0,0 +1,32 @@ +#!/bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Last modified: 1994-03-25 +# Public domain + +errstatus=0 + +for file in ${1+"$@"} ; do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d in ${1+"$@"} ; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" || errstatus=$? + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/usr.bin/sudo/parse.c b/usr.bin/sudo/parse.c new file mode 100644 index 00000000000..7d709f70af7 --- /dev/null +++ b/usr.bin/sudo/parse.c @@ -0,0 +1,457 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Chris Jepeway + * <jepeway@cs.utk.edu>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_FNMATCH) && defined(HAVE_FNMATCH_H) +# include <fnmatch.h> +#endif /* HAVE_FNMATCH_H */ +#ifdef HAVE_NETGROUP_H +# include <netgroup.h> +#endif /* HAVE_NETGROUP_H */ +#include <ctype.h> +#include <pwd.h> +#include <grp.h> +#include <sys/param.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/stat.h> +#if HAVE_DIRENT_H +# include <dirent.h> +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif + +#include "sudo.h" +#include "parse.h" +#include "interfaces.h" + +#ifndef HAVE_FNMATCH +# include "emul/fnmatch.h" +#endif /* HAVE_FNMATCH */ + +#ifndef lint +static const char rcsid[] = "$Sudo: parse.c,v 1.121 1999/08/28 10:00:22 millert Exp $"; +#endif /* lint */ + +/* + * Globals + */ +int parse_error = FALSE; +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(check_cmnd) + int check_cmnd; +{ + int error; + + /* 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(); + + /* 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); + + /* + * Assume the worst. If the stack is empty the user was + * not mentioned at all. + */ + error = VALIDATE_NOT_OK; + if (check_cmnd == TRUE) { + error |= FLAG_NO_HOST; + if (!top) + error |= FLAG_NO_USER; + } else + error |= FLAG_NO_CHECK; + + /* + * Only check the actual command if the check_cmnd flag is set. + * It is not set for the "validate" and "list" pseudo-commands. + * Always check the host and user. + */ + if (check_cmnd == FALSE) + while (top) { + if (host_matches == TRUE) { + /* User may always validate or list on allowed hosts */ + if (no_passwd == TRUE) + return(VALIDATE_OK | FLAG_NOPASS); + else + return(VALIDATE_OK); + } + top--; + } + 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. + */ + return(error); +} + +/* + * 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 + mask.s_addr = (1 << atoi(m)) - 1; /* XXX - better way? */ + *(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 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" or "user" may be NULL + * in which case that argument is not checked... + */ +int +netgr_matches(netgr, host, user) + char *netgr; + char *host; + 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 + return(innetgr(netgr, host, user, domain)); +#else + return(FALSE); +#endif /* HAVE_INNETGR */ +} + +/* + * Returns TRUE if "s" has shell meta characters in it, + * else returns FALSE. + */ +static int +has_meta(s) + char *s; +{ + register char *t; + + for (t = s; *t; t++) { + if (*t == '\\' || *t == '?' || *t == '*' || *t == '[' || *t == ']') + return(TRUE); + } + return(FALSE); +} diff --git a/usr.bin/sudo/parse.h b/usr.bin/sudo/parse.h new file mode 100644 index 00000000000..eb138471c9e --- /dev/null +++ b/usr.bin/sudo/parse.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: parse.h,v 1.5 1999/09/08 08:06:15 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 netgr_matches __P((char *, char *, char *)); +int usergr_matches __P((char *, char *)); + +#endif /* _SUDO_PARSE_H */ diff --git a/usr.bin/sudo/parse.lex b/usr.bin/sudo/parse.lex new file mode 100644 index 00000000000..722e5097fd5 --- /dev/null +++ b/usr.bin/sudo/parse.lex @@ -0,0 +1,424 @@ +%{ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Chris Jepeway + * <jepeway@cs.utk.edu> + * + * 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" + +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +#include <malloc.h> +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include <ctype.h> +#include <sys/types.h> +#include <sys/param.h> +#include "sudo.h" +#include "parse.h" +#include "sudo.tab.h" + +#ifndef lint +static const char rcsid[] = "$Sudo: parse.lex,v 1.109 1999/11/09 20:06:52 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])+ + +%s GOTCMND +%s GOTRUNAS +%s GOTDEFS + +%% +[ \t]+ { /* throw away space/tabs */ + sawspace = TRUE; /* but remember for fill_args */ + } + +\\[ \t]*\n { + sawspace = TRUE; /* remember for fill_args */ + ++sudolineno; + LEXTRACE("\n\t"); + } /* throw away EOL after \ */ + +<GOTCMND>\\[:\,=\\ \t] { + LEXTRACE("QUOTEDCHAR "); + fill_args(yytext + 1, 1, sawspace); + sawspace = FALSE; + } + +<GOTDEFS>\"([^\"]|\\\")+\" { + LEXTRACE("WORD(1) "); + fill(yytext + 1, yyleng - 2); + return(WORD); + } + +<GOTDEFS>(#.*)?\n { + BEGIN INITIAL; + ++sudolineno; + LEXTRACE("\n"); + return(COMMENT); + } + +<GOTCMND>[:\,=\n] { + BEGIN INITIAL; + unput(*yytext); + return(COMMAND); + } /* end of command line args */ + +\n { + ++sudolineno; + LEXTRACE("\n"); + return(COMMENT); + } /* return newline */ + +<INITIAL>#.*\n { + ++sudolineno; + LEXTRACE("\n"); + return(COMMENT); + } /* return comments */ + +<GOTCMND>[^\\:, \t\n]+ { + LEXTRACE("ARG "); + fill_args(yytext, yyleng, sawspace); + sawspace = FALSE; + } /* a command line arg */ + +, { + LEXTRACE(", "); + return(','); + } /* return ',' */ + +!+ { + if (yyleng % 2 == 1) + return('!'); /* return '!' */ + } + += { + LEXTRACE("= "); + return('='); + } /* return '=' */ + +: { + LEXTRACE(": "); + return(':'); + } /* return ':' */ + +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); + } + +[[:alpha:]][[:alnum:]_-]*(\.{HOSTNAME})+ { + fill(yytext, yyleng); + LEXTRACE("FQHOST "); + return(FQHOST); + } + +<INITIAL>\( { + BEGIN GOTRUNAS; + LEXTRACE("RUNAS "); + return (RUNAS); + } + +<GOTRUNAS>[[:upper:]][[:upper:][:digit:]_]* { + /* Runas_Alias user can run command as or ALL */ + if (strcmp(yytext, "ALL") == 0) { + LEXTRACE("ALL "); + return(ALL); + } else { + fill(yytext, yyleng); + LEXTRACE("ALIAS "); + return(ALIAS); + } + } + +<GOTRUNAS>#?{WORD} { + /* username/uid that user can run command as */ + fill(yytext, yyleng); + LEXTRACE("WORD(2) "); + return(WORD); + } + +<GOTRUNAS>\) { + BEGIN INITIAL; + } + +[[:upper:]][[:upper:][:digit:]_]* { + if (strcmp(yytext, "ALL") == 0) { + LEXTRACE("ALL "); + return(ALL); + } else { + fill(yytext, yyleng); + LEXTRACE("ALIAS "); + return(ALIAS); + } + } + +<GOTDEFS>{WORD} { + LEXTRACE("WORD(3) "); + fill(yytext, yyleng); + return(WORD); + } + +<INITIAL>^Defaults[:@]? { + BEGIN GOTDEFS; + if (yyleng == 9) { + switch (yytext[8]) { + case ':' : + LEXTRACE("DEFAULTS_USER "); + return(DEFAULTS_USER); + case '@' : + LEXTRACE("DEFAULTS_HOST "); + return(DEFAULTS_HOST); + } + } else { + LEXTRACE("DEFAULTS "); + return(DEFAULTS); + } + } + +<INITIAL>^(Host|Cmnd|User|Runas)_Alias { + fill(yytext, yyleng); + if (*yytext == 'H') { + LEXTRACE("HOSTALIAS "); + return(HOSTALIAS); + } + if (*yytext == 'C') { + LEXTRACE("CMNDALIAS "); + return(CMNDALIAS); + } + if (*yytext == 'U') { + LEXTRACE("USERALIAS "); + return(USERALIAS); + } + if (*yytext == 'R') { + LEXTRACE("RUNASALIAS "); + return(RUNASALIAS); + } + } + +\/[^\,:=\\ \t\n#]+ { + /* directories can't have args... */ + if (yytext[yyleng - 1] == '/') { + LEXTRACE("COMMAND "); + fill_cmnd(yytext, yyleng); + return(COMMAND); + } else { + BEGIN GOTCMND; + LEXTRACE("COMMAND "); + fill_cmnd(yytext, yyleng); + } + } /* a pathname */ + +<INITIAL>{WORD} { + /* a word */ + fill(yytext, yyleng); + LEXTRACE("WORD(4) "); + return(WORD); + } + +. { + 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 */ + (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/usr.bin/sudo/parse.yacc b/usr.bin/sudo/parse.yacc new file mode 100644 index 00000000000..4dccccf2352 --- /dev/null +++ b/usr.bin/sudo/parse.yacc @@ -0,0 +1,1162 @@ +%{ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Chris Jepeway + * <jepeway@cs.utk.edu> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * 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 <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#include <pwd.h> +#include <sys/types.h> +#include <sys/param.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +#include <malloc.h> +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +#include <alloca.h> +#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */ +#ifdef HAVE_LSEARCH +#include <search.h> +#endif /* HAVE_LSEARCH */ + +#include "sudo.h" +#include "parse.h" + +#ifndef HAVE_LSEARCH +#include "emul/search.h" +#endif /* HAVE_LSEARCH */ + +#ifndef lint +static const char rcsid[] = "$Sudo: parse.yacc,v 1.166 1999/10/07 21:20:57 millert Exp $"; +#endif /* lint */ + +/* + * Globals + */ +extern int sudolineno, parse_error; +int errorlineno = -1; +int clearaliases = TRUE; +int printmatches = FALSE; +int pedantic = 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 occured on. */ + if (errorlineno == -1) + errorlineno = sudolineno ? sudolineno - 1 : 0; + if (s) { +#ifndef TRACELEXER + (void) fprintf(stderr, ">>> sudoers file: %s, line %d <<<\n", s, + sudolineno ? sudolineno - 1 : 0); +#else + (void) fprintf(stderr, "<*> "); +#endif + } + parse_error = TRUE; +} +%} + +%union { + char *string; + int BOOLEAN; + struct sudo_command command; + int tok; +} + +%start file /* special start symbol */ +%token <command> COMMAND /* absolute pathname w/ optional args */ +%token <string> ALIAS /* an UPPERCASE alias name */ +%token <string> NTWKADDR /* w.x.y.z */ +%token <string> FQHOST /* foo.bar.com */ +%token <string> NETGROUP /* a netgroup (+NAME) */ +%token <string> USERGROUP /* a usergroup (%NAME) */ +%token <string> WORD /* a word */ +%token <tok> DEFAULTS /* Defaults entry */ +%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */ +%token <tok> DEFAULTS_USER /* User-specific defaults entry */ +%token <tok> RUNAS /* ( runas_list ) */ +%token <tok> NOPASSWD /* no passwd req for command */ +%token <tok> PASSWD /* passwd req for command (default) */ +%token <tok> ALL /* ALL keyword */ +%token <tok> COMMENT /* comment and/or carriage return */ +%token <tok> HOSTALIAS /* Host_Alias keyword */ +%token <tok> CMNDALIAS /* Cmnd_Alias keyword */ +%token <tok> USERALIAS /* User_Alias keyword */ +%token <tok> RUNASALIAS /* Runas_Alias keyword */ +%token <tok> ':' '=' ',' '!' /* union member tokens */ +%token <tok> ERROR + +/* + * NOTE: these are not true booleans as there are actually 3 possible values: + * 1) TRUE (positive match) + * 0) FALSE (negative match due to a '!' somewhere) + * -1) No match (don't change the value of *_matches) + */ +%type <BOOLEAN> cmnd +%type <BOOLEAN> host +%type <BOOLEAN> runasuser +%type <BOOLEAN> 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 : WORD { + if (defaults_matches && !set_default($1, NULL, 1)) { + yyerror(NULL); + YYERROR; + } + free($1); + } + | '!' WORD { + if (defaults_matches && !set_default($2, NULL, 0)) { + yyerror(NULL); + YYERROR; + } + free($2); + } + | WORD '=' WORD { + /* XXX - need to support quoted values */ + if (defaults_matches && !set_default($1, $3, 1)) { + 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, NULL)) + $$ = TRUE; + else + $$ = -1; + free($1); + } + | WORD { + if (strcasecmp(user_shost, $1) == 0) + $$ = TRUE; + else + $$ = -1; + free($1); + } + | FQHOST { + if (strcasecmp(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 (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; + 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_DEF)) == 0); + } + | RUNAS runaslist { ; } + ; + +runaslist : oprunasuser + | runaslist ',' oprunasuser + ; + +oprunasuser : runasuser { + if ($1 != -1) + runas_matches = $1; + } + | '!' { + if (printmatches == TRUE) { + if (in_alias == TRUE) + append_entries("!", ", "); + else if (host_matches == TRUE && + user_matches == TRUE) + append_runas("!", ", "); + } + } runasuser { + if ($3 != -1) + runas_matches = ! $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, *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 { + push; + 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 ((runas_matches != -1 || pedantic) && + !add_alias($1, RUNAS_ALIAS, runas_matches)) + YYERROR; + pop; + 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, 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_DEF)); + } + + /* 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/usr.bin/sudo/pathnames.h.in b/usr.bin/sudo/pathnames.h.in new file mode 100644 index 00000000000..b81a5004cd5 --- /dev/null +++ b/usr.bin/sudo/pathnames.h.in @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: pathnames.h.in,v 1.42 1999/08/06 09:37:00 millert Exp $ + */ + +/* + * Pathnames to programs and files used by sudo. + */ + +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif /* HAVE_PATHS_H */ + +#ifndef _PATH_DEV +#define _PATH_DEV "/dev/" +#endif /* _PATH_DEV */ + +#ifndef _PATH_TTY +#define _PATH_TTY "/dev/tty" +#endif /* _PATH_TTY */ + +/* + * 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_SENDMAIL +#undef _PATH_SENDMAIL +#endif /* _PATH_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/usr.bin/sudo/sample.sudoers b/usr.bin/sudo/sample.sudoers new file mode 100644 index 00000000000..f4b471a106a --- /dev/null +++ b/usr.bin/sudo/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/usr.bin/sudo/sudo.8 b/usr.bin/sudo/sudo.8 new file mode 100644 index 00000000000..ad88f7d6646 --- /dev/null +++ b/usr.bin/sudo/sudo.8 @@ -0,0 +1,506 @@ +.rn '' }` +''' $RCSfile: sudo.8,v $$Revision: 1.1 $$Date: 1999/11/18 16:29:01 $ +''' +''' $Log: sudo.8,v $ +''' Revision 1.1 1999/11/18 16:29:01 millert +''' Initial revision +''' +''' Revision 1.39 1999/11/16 05:42:28 millert +''' get rid of references to sudo-bugs. Now mention the web site or the sudo@ alias +''' +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.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" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH sudo 8 "1.6" "15/Nov/1999" "MAINTENANCE COMMANDS" +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.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 ? ? +. ds ! ! +. ds / +. ds q +.\} +.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 ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" 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 v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.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 +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'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 v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. 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 +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +sudo \- execute a command as another user +.SH "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\-b\fR ] | [ \fB\-p\fR prompt ] [ \fB\-u\fR username/#uid] \fIcommand\fR +.SH "DESCRIPTION" +\fBsudo\fR allows a permitted user to execute a \fIcommand\fR as the +superuser or another user, as specified in the sudoers file. The +real and effective uid and gid are set to match those of the target +user as specified in the passwd file (the group vector is also +initialized when the target user is not root). +.PP +\fBsudo\fR determines who is an authorized user by consulting the +file \fI/etc/sudoers\fR. By giving \fBsudo\fR the \f(CW-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 with N minutes (again, this is defined at configure +time and defaults to 5 minutes). +.PP +If a user that 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 (defaults to root). Note that the +mail will not be sent if an unauthorized user tries to run sudo +with the \f(CW-l\fR or \f(CW-v\fR flags. This allows users to determine +for themselves whether or not they are allowed to use \fBsudo\fR. +.PP +\fBsudo\fR can log both successful an unsuccessful attempts (as well +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. +.SH "OPTIONS" +\fBsudo\fR accepts the following command line options: +.Ip "-V" 4 +The \f(CW-V\fR (\fIversion\fR) option causes \fBsudo\fR to print the +version number and exit. +.Ip "-l" 4 +The \f(CW-l\fR (\fIlist\fR) option will list out the allowed (and +forbidden) commands for the user on the current host. +.Ip "-L" 4 +The \f(CW-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 +The \f(CW-h\fR (\fIhelp\fR) option causes \fBsudo\fR to print a usage message and exit. +.Ip "-v" 4 +If given the \f(CW-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 to for another N minutes +(where N is defined at installation time and defaults to 5 +minutes) but does not run a command. +.Ip "-k" 4 +The \f(CW-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 +The \f(CW-K\fR (sure \fIkill\fR) option to \fBsudo\fR removes the user's timestamp +entirely. This option does not require a password. +.Ip "-b" 4 +The \f(CW-b\fR (\fIbackground\fR) option tells \fBsudo\fR to run the given +command in the background. Note that if you use the \f(CW-b\fR +option you cannot use shell job control to manipulate the command. +.Ip "-p" 4 +The \f(CW-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%u\fR escape, \f(CW%u\fR will be replaced with the user's +login name. Similarly, \f(CW%h\fR will be replaced with the local +hostname. +.Ip "-u" 4 +The \f(CW-u\fR (\fIuser\fR) option causes sudo to run the specified command +as a user other than \fIroot\fR. To specify a \fIuid\fR instead of a +\fIusername\fR, use \*(L"#uid\*(R". +.Ip "-s" 4 +The \f(CW-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\|(5). +.Ip "-H" 4 +The \f(CW-H\fR (\fI\s-1HOME\s0\fR) option sets the \fI\s-1HOME\s0\fR environment variable +to the homedir of the target user (root by default) as specified +in \fIpasswd\fR\|(5). By default, \fBsudo\fR does not modify \fI\s-1HOME\s0\fR. +.Ip "--" 4 +The \f(CW--\fR flag indicates that \fBsudo\fR should stop processing command +line arguments. It is most useful in conjunction with the \f(CW-s\fR flag. +.SH "RETURN VALUES" +\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(CWPATH\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(CWPATH\fR is on a machine that is currently +unreachable. +.SH "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(CWLD_*\fR, \f(CW_RLD_*\fR, \f(CWSHLIB_PATH\fR (HP\-UX only), and \f(CWLIBPATH\fR (AIX +only) environment variables are removed from the environment passed +on to all commands executed. \fBsudo\fR will also remove the \f(CWIFS\fR, +\f(CWENV\fR, \f(CWBASH_ENV\fR, \f(CWKRB_CONF\fR, \f(CWKRB5_CONFIG\fR, \f(CWLOCALDOMAIN\fR, +\f(CWRES_OPTIONS\fR and \f(CWHOSTALIASES\fR variables as they too can pose a +threat. +.PP +To prevent command spoofing, \fBsudo\fR 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 \f(CWPATH\fR environment variable is \fInot\fR modified and is passed +unchanged to the program that \fBsudo\fR executes. +.PP +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 \fBsudo\fR statically. +.PP +\fBsudo\fR will check the ownership of its timestamp directory +(\fI/var/run/sudo\fR or \fI/tmp/.odus\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 (ie: \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 /tmp/.odus 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(CWTIMEOUT\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 system that allow users to give away files. +.SH "EXAMPLES" +Note: the following examples assume suitable \fIsudoers\fR\|(5) 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(CWcd\fR and file redirection work. +.PP +.Vb 1 +\& % sudo sh -c "cd /home ; du -s * | sort -rn > USAGE" +.Ve +.SH "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" +.PP +.Vb 2 +\& /etc/sudoers List of who can run what +\& /var/run/sudo Directory containing timestamps +.Ve +\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" +.PP +.Vb 3 +\& /etc/sudoers List of who can run what +\& /var/run/sudo Directory containing timestamps +\& /tmp/.odus Same as above if no /var/run exists +.Ve +.SH "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 HISTORY file in the \fBsudo\fR distribution for a short history +of \fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in sudo, please submit a bug report +at http://www.courtesan.com/sudo/bugs/. +.SH "DISCLAIMER" +\fBSudo\fR is provided ``AS IS'\*(R' 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 \fBsudo\fR for complete details. +.SH "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(CWALL\fR there is nothing to prevent them from creating +their own program that gives them a root shell regardless of any \*(L'!\*(R' +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 OS supports the /dev/fd/ directory, setuid shell scripts +are generally safe). +.SH "SEE ALSO" +\fIsudoers\fR\|(5), \fIvisudo\fR\|(8), \fIsu\fR\|(1). + +.rn }` '' +.IX Title "sudo 8" +.IX Name "sudo - execute a command as another user" + +.IX Header "NAME" + +.IX Header "SYNOPSIS" + +.IX Header "DESCRIPTION" + +.IX Header "OPTIONS" + +.IX Item "-V" + +.IX Item "-l" + +.IX Item "-L" + +.IX Item "-h" + +.IX Item "-v" + +.IX Item "-k" + +.IX Item "-K" + +.IX Item "-b" + +.IX Item "-p" + +.IX Item "-u" + +.IX Item "-s" + +.IX Item "-H" + +.IX Item "--" + +.IX Header "RETURN VALUES" + +.IX Header "SECURITY NOTES" + +.IX Header "EXAMPLES" + +.IX Header "ENVIRONMENT" + +.IX Header "FILES" + +.IX Header "FILES" + +.IX Header "AUTHORS" + +.IX Header "BUGS" + +.IX Header "DISCLAIMER" + +.IX Header "CAVEATS" + +.IX Header "SEE ALSO" + diff --git a/usr.bin/sudo/sudo.c b/usr.bin/sudo/sudo.c new file mode 100644 index 00000000000..0a4c908f6ee --- /dev/null +++ b/usr.bin/sudo/sudo.c @@ -0,0 +1,1062 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * For a brief history of sudo, please see the HISTORY file included + * with this distribution. + */ + +#define _SUDO_SUDO_C + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <pwd.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <grp.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <netdb.h> +#ifdef HAVE_SETRLIMIT +#include <sys/time.h> +#include <sys/resource.h> +#endif +#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) +# ifdef __hpux +# undef MAXINT +# include <hpsecurity.h> +# else +# include <sys/security.h> +# endif /* __hpux */ +# include <prot.h> +#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ + +#include "sudo.h" +#include "interfaces.h" +#include "version.h" + +#ifndef STDC_HEADERS +extern char *getenv __P((char *)); +#endif /* STDC_HEADERS */ + +#ifndef lint +static const char rcsid[] = "$Sudo: sudo.c,v 1.258 1999/11/16 06:09:23 millert Exp $"; +#endif /* lint */ + +/* + * Local type declarations + */ +struct env_table { + char *name; + int len; +}; + +/* + * Prototypes + */ +static int parse_args __P((void)); +static void usage __P((int)); +static void usage_excl __P((int)); +static void check_sudoers __P((void)); +static int init_vars __P((int)); +static void add_env __P((int)); +static void clean_env __P((char **, struct env_table *)); +static void initial_setup __P((void)); +extern int user_is_exempt __P((void)); +extern struct passwd *sudo_getpwuid __P((uid_t)); +extern void list_matches __P((void)); + +/* + * Globals + */ +int Argc; +char **Argv; +int NewArgc = 0; +char **NewArgv = NULL; +struct sudo_user sudo_user; +FILE *sudoers_fp = NULL; +static char *runas_homedir = NULL; /* XXX */ +struct interface *interfaces; +int num_interfaces; +extern int errorlineno; + +/* + * Table of "bad" envariables to remove and len for strncmp() + */ +static struct env_table badenv_table[] = { + { "IFS=", 4 }, + { "LOCALDOMAIN=", 12 }, + { "RES_OPTIONS=", 12 }, + { "HOSTALIASES=", 12 }, + { "LD_", 3 }, + { "_RLD", 4 }, +#ifdef __hpux + { "SHLIB_PATH=", 11 }, +#endif /* __hpux */ +#ifdef _AIX + { "LIBPATH=", 8 }, +#endif /* _AIX */ +#ifdef HAVE_KERB4 + { "KRB_CONF", 8 }, +#endif /* HAVE_KERB4 */ +#ifdef HAVE_KERB5 + { "KRB5_CONFIG", 11 }, +#endif /* HAVE_KERB5 */ + { "ENV=", 4 }, + { "BASH_ENV=", 9 }, + { (char *) NULL, 0 } +}; + + +int +main(argc, argv) + int argc; + char **argv; +{ + int validated; + int fd; + int cmnd_status; + int sudo_mode; +#ifdef POSIX_SIGNALS + sigset_t set, oset; +#else + int omask; +#endif /* POSIX_SIGNALS */ + extern char **environ; + extern int printmatches; + + /* 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 */ + + Argv = argv; + Argc = argc; + + if (geteuid() != 0) { + (void) fprintf(stderr, "Sorry, %s must be setuid root.\n", Argv[0]); + exit(1); + } + + /* + * Block signals so the user cannot interrupt us at some point and + * avoid the logging. + */ +#ifdef POSIX_SIGNALS + (void) sigemptyset(&set); + (void) sigaddset(&set, SIGINT); + (void) sigaddset(&set, SIGQUIT); + (void) sigaddset(&set, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &set, &oset); +#else + omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTSTP)); +#endif /* POSIX_SIGNALS */ + + /* + * Setup signal handlers, turn off core dumps, and close open files. + */ + initial_setup(); + + /* + * Set the prompt based on $SUDO_PROMPT (can be overridden by `-p') + */ + user_prompt = getenv("SUDO_PROMPT"); + + /* Parse our arguments. */ + sudo_mode = parse_args(); + + /* Setup defaults data structures. */ + init_defaults(); + + /* Initialize syslog(3) if we are using it. */ + if (def_str(I_LOGFACSTR)) { +#ifdef LOG_NFACILITIES + openlog("sudo", 0, def_ival(I_LOGFAC)); +#else + openlog("sudo", 0); +#endif /* LOG_NFACILITIES */ + } + + 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(); + } + exit(0); + break; + case MODE_HELP: + usage(0); + break; + case MODE_VALIDATE: + user_cmnd = "validate"; + break; + case MODE_KILL: + case MODE_INVALIDATE: + user_cmnd = "kill"; + break; + case MODE_LISTDEFS: + list_options(); + exit(0); + break; + case MODE_LIST: + user_cmnd = "list"; + printmatches = 1; + break; + } + + /* Must have a command to run... */ + if (user_cmnd == NULL && NewArgc == 0) + usage(1); + + clean_env(environ, badenv_table); + + cmnd_status = init_vars(sudo_mode); + + /* At this point, ruid == euid == 0 */ + + check_sudoers(); /* check mode/owner on _PATH_SUDOERS */ + + if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { + remove_timestamp((sudo_mode == MODE_KILL)); + exit(0); + } + + add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */ + + /* Validate the user but don't search for pseudo-commands. */ + validated = + sudoers_lookup((sudo_mode != MODE_VALIDATE && sudo_mode != MODE_LIST)); + + 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); + } + + /* 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); + } + + /* Require a password unless the NOPASS tag was set. */ + if (!(validated & FLAG_NOPASS)) + check_user(); + + 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); + } + + /* Become specified user or root. */ + set_perms(PERM_RUNAS, sudo_mode); + + /* Set $HOME for `sudo -H' */ + if ((sudo_mode & MODE_RESET_HOME) && runas_homedir) + (void) sudo_setenv("HOME", runas_homedir); + + /* This *must* have been set if we got a match but... */ + if (safe_cmnd == NULL) { + log_error(MSG_ONLY, + "internal error, cmnd_safe never got set for %s; %s", + user_cmnd, + "please report this error at http://courtesan.com/sudo/bugs/"); + } + + if (def_ival(I_LOGFACSTR)) + closelog(); + + /* Reset signal mask before we exec. */ +#ifdef POSIX_SIGNALS + (void) sigprocmask(SIG_SETMASK, &oset, NULL); +#else + (void) sigsetmask(omask); +#endif /* POSIX_SIGNALS */ + + /* Override user's umask if configured to do so. */ + if (def_ival(I_UMASK) != 0777) + (void) umask(def_mode(I_UMASK)); + + /* Replace the PATH envariable with a secure one. */ + if (def_str(I_SECURE_PATH) && !user_is_exempt()) + if (sudo_setenv("PATH", def_str(I_SECURE_PATH))) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", + Argv[0]); + exit(1); + } + +#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(-1); + } 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]; + struct hostent *hp; + + /* 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. + */ + if ((gethostname(thost, sizeof(thost)))) { + user_host = "localhost"; + log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); + } else + user_host = estrdup(thost); + if (def_flag(I_FQDN)) { + if (!(hp = gethostbyname(user_host))) { + log_error(USE_ERRNO|MSG_ONLY|NO_EXIT, + "unable to lookup %s via gethostbyname()", user_host); + } else { + 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; + } + + 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); + } + + /* It is now safe to use log_error() and set_perms() */ + + /* + * 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); + + /* + * Load the list of local ip addresses and netmasks into + * the interfaces array. + */ + load_interfaces(); + + /* + * 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) + ; + } + + /* Resolve the path and return. */ + if ((sudo_mode & MODE_RUN)) + return(find_path(NewArgv[0], &user_cmnd)); + else + return(FOUND); +} + +/* + * 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 (Argc < 2) { /* no options and no command */ + if (!def_flag(I_SHELL_NOARGS)) + usage(1); + rval |= 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; + 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 (def_flag(I_SET_HOME)) + rval |= MODE_RESET_HOME; + break; + case 'H': + rval |= MODE_RESET_HOME; + break; + case '-': + NewArgc--; + NewArgv++; + if (def_flag(I_SHELL_NOARGS) && rval == MODE_RUN) + rval |= 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); +} + +/* + * Add sudo-specific variables into the environment. + * Sets ``cmnd_args'' as a side effect. + */ +static void +add_env(contiguous) + int contiguous; +{ + char idstr[MAX_UID_T_LEN + 1]; + size_t size; + char *buf; + + /* Add the SUDO_COMMAND envariable (cmnd + args). */ + size = strlen(user_cmnd) + 1; + if (NewArgc > 1) { + char *to, **from; + + if (contiguous) { + size += (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) + + strlen(NewArgv[NewArgc-1]) + 1; + } else { + for (from = &NewArgv[1]; *from; from++) + size += strlen(*from) + 1; + } + + buf = (char *) emalloc(size); + + /* + * Copy the command and it's arguments info buf. + */ + (void) strcpy(buf, user_cmnd); + to = buf + strlen(user_cmnd); + for (from = &NewArgv[1]; *from; from++) { + *to++ = ' '; + (void) strcpy(to, *from); + to += strlen(*from); + } + } else { + buf = user_cmnd; + } + if (sudo_setenv("SUDO_COMMAND", buf)) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } + if (NewArgc > 1) + free(buf); + + /* Grab a pointer to the flat arg string from the environment. */ + if (NewArgc > 1 && (user_args = getenv("SUDO_COMMAND"))) { + if ((user_args = strchr(user_args, ' '))) + user_args++; + else + user_args = NULL; + } + + /* Add the SUDO_USER environment variable. */ + if (sudo_setenv("SUDO_USER", user_name)) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } + + /* Add the SUDO_UID environment variable. */ + (void) sprintf(idstr, "%ld", (long) user_uid); + if (sudo_setenv("SUDO_UID", idstr)) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } + + /* Add the SUDO_GID environment variable. */ + (void) sprintf(idstr, "%ld", (long) user_gid); + if (sudo_setenv("SUDO_GID", idstr)) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } + + /* Set PS1 if SUDO_PS1 is set. */ + if ((buf = getenv("SUDO_PS1"))) + if (sudo_setenv("PS1", buf)) { + (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); + exit(1); + } +} + +/* + * 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); + 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_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 */ +} + +/* + * Remove environment variables that match the entries in badenv_table. + */ +static void +clean_env(envp, badenv_table) + char **envp; + struct env_table *badenv_table; +{ + struct env_table *bad; + char **cur; + + /* + * Remove any envars that match entries in badenv_table. + */ + for (cur = envp; *cur; cur++) { + for (bad = badenv_table; bad->name; bad++) { + if (strncmp(*cur, bad->name, bad->len) == 0) { + /* Got a match so remove it. */ + char **move; + + for (move = cur; *move; move++) + *move = *(move + 1); + + cur--; + + break; + } + } + } +} + +/* + * Set real and effective uids and gids based on perm. + */ +void +set_perms(perm, sudo_mode) + int perm; + int sudo_mode; +{ + struct passwd *pw; + + /* + * First, set real & effective uids to root. + * If perm is PERM_ROOT then we don't need to do anything else. + */ + if (setuid(0)) { + perror("setuid(0)"); + exit(1); + } + + switch (perm) { + case PERM_USER: + (void) setgid(user_gid); + + if (seteuid(user_uid)) { + perror("seteuid(user_uid)"); + exit(1); + } + break; + + case PERM_FULL_USER: + (void) setgid(user_gid); + + if (setuid(user_uid)) { + perror("setuid(user_uid)"); + exit(1); + } + break; + + case PERM_RUNAS: + /* XXX - add group/gid support */ + if (**user_runas == '#') { + if (setuid(atoi(*user_runas + 1))) { + (void) fprintf(stderr, + "%s: cannot set uid to %s: %s\n", + Argv[0], *user_runas, strerror(errno)); + exit(1); + } + } else { + if (!(pw = getpwnam(*user_runas))) { + (void) fprintf(stderr, + "%s: no passwd entry for %s!\n", + Argv[0], *user_runas); + exit(1); + } + + /* Set $USER and $LOGNAME to target user */ + if (sudo_setenv("USER", pw->pw_name)) { + (void) fprintf(stderr, + "%s: cannot allocate memory!\n", + Argv[0]); + exit(1); + } + if (sudo_setenv("LOGNAME", pw->pw_name)) { + (void) fprintf(stderr, + "%s: cannot allocate memory!\n", + Argv[0]); + exit(1); + } + + if (setgid(pw->pw_gid)) { + (void) fprintf(stderr, + "%s: cannot set gid to %ld: %s\n", + Argv[0], (long) pw->pw_gid, + strerror(errno)); + exit(1); + } + + /* + * Initialize group vector only if are + * going to run as a non-root user. + */ + if (strcmp(*user_runas, "root") != 0 && + initgroups(*user_runas, pw->pw_gid) + == -1) { + (void) fprintf(stderr, + "%s: cannot set group vector: %s\n", + Argv[0], strerror(errno)); + exit(1); + } + + if (setuid(pw->pw_uid)) { + (void) fprintf(stderr, + "%s: cannot set uid to %ld: %s\n", + Argv[0], (long) pw->pw_uid, + strerror(errno)); + exit(1); + } + if (sudo_mode & MODE_RESET_HOME) + runas_homedir = pw->pw_dir; + } + break; + + case PERM_SUDOERS: + if (setgid(SUDOERS_GID)) { + perror("setgid(SUDOERS_GID)"); + exit(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)) { + perror("seteuid(1)"); + exit(1); + } + } else { + if (seteuid(SUDOERS_UID)) { + perror("seteuid(SUDOERS_UID)"); + exit(1); + } + } + break; + } +} + +/* + * Close all open files (except std*) and turn off core dumps. + */ +static void +initial_setup() +{ + int fd, maxfd; +#ifdef HAVE_SETRLIMIT + struct rlimit rl; +#endif +#ifdef POSIX_SIGNALS + struct sigaction sa; +#endif + +#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) + /* + * Turn off core dumps. + */ + 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 RLIMIT_NOFILE + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) + maxfd = rl.rlim_max - 1; + else +#endif /* RLIMIT_NOFILE */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX) - 1; +#else + maxfd = getdtablesize() - 1; +#endif /* HAVE_SYSCONF */ + + for (fd = maxfd; fd > STDERR_FILENO; fd--) + (void) close(fd); + + /* Catch children as they die... */ +#ifdef POSIX_SIGNALS + (void) memset((VOID *)&sa, 0, sizeof(sa)); + sa.sa_handler = reapchild; + (void) sigaction(SIGCHLD, &sa, NULL); +#else + (void) signal(SIGCHLD, reapchild); +#endif /* POSIX_SIGNALS */ +} + +/* + * Tell which options are mutually exclusive and exit. + */ +static void +usage_excl(exit_val) + int exit_val; +{ + (void) fprintf(stderr, + "Only one of the -v, -k, -K, -l, -V and -h 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: %s -V | -h | -L | -l | -v | -k | -K | -H | [-b] [-p prompt]\n%*s", + Argv[0], (int) strlen(Argv[0]) + 8, " "); + (void) fprintf(stderr, "[-u username/#uid] -s | <command>\n"); + exit(exit_val); +} diff --git a/usr.bin/sudo/sudo.h b/usr.bin/sudo/sudo.h new file mode 100644 index 00000000000..e0ee04f7019 --- /dev/null +++ b/usr.bin/sudo/sudo.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: sudo.h,v 1.163 1999/09/08 08:06:17 millert Exp $ + */ + +#ifndef _SUDO_SUDO_H +#define _SUDO_SUDO_H + +#include <pathnames.h> +#include "compat.h" +#include "defaults.h" +#include "logging.h" + +/* + * Info pertaining to the invoking user. + */ +struct sudo_user { + struct passwd *pw; + char *tty; + char cwd[MAXPATHLEN]; + char *host; + char *shost; + char **runas; + char *prompt; + char *cmnd_safe; + char *cmnd; + char *cmnd_args; +}; + +/* + * 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 00001 +#define MODE_VALIDATE 00002 +#define MODE_INVALIDATE 00004 +#define MODE_KILL 00010 +#define MODE_VERSION 00020 +#define MODE_HELP 00040 +#define MODE_LIST 00100 +#define MODE_LISTDEFS 00200 +#define MODE_BACKGROUND 00400 +#define MODE_SHELL 01000 +#define MODE_RESET_HOME 02000 + +/* + * Used with set_perms() + */ +#define PERM_ROOT 0x00 +#define PERM_USER 0x01 +#define PERM_FULL_USER 0x02 +#define PERM_SUDOERS 0x03 +#define PERM_RUNAS 0x04 + +/* + * 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_shell (sudo_user.pw->pw_shell) +#define user_dir (sudo_user.pw->pw_dir) +#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_prompt (sudo_user.prompt) +#define user_host (sudo_user.host) +#define user_shost (sudo_user.shost) +#define safe_cmnd (sudo_user.cmnd_safe) + +/* + * 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 */ + +/* + * Function prototypes + */ +#define YY_DECL int yylex __P((void)) + +#ifndef HAVE_GETCWD +char *getcwd __P((char *, size_t size)); +#endif +#if !defined(HAVE_PUTENV) && !defined(HAVE_SETENV) +int putenv __P((const char *)); +#endif +#ifndef HAVE_SNPRINTF +int snprintf __P((char *, size_t, const char *, ...)); +#endif +#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 *)); +int sudo_setenv __P((char *, char *)); +char *tgetpass __P((const char *, int, int)); +int find_path __P((char *, char **)); +void check_user __P((void)); +void verify_user __P((char *)); +int sudoers_lookup __P((int)); +void set_perms __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 *)); +void easprintf __P((char **, const char *, ...)); +void evasprintf __P((char **, const char *, va_list)); +void dump_defaults __P((void)); +void dump_auth_methods __P((void)); +int lock_file __P((int, int)); +int touch __P((char *, time_t)); +YY_DECL; + +/* Only provide extern declarations outside of sudo.c. */ +#ifndef _SUDO_SUDO_C +extern struct sudo_user sudo_user; + +extern int Argc; +extern char **Argv; +extern FILE *sudoers_fp; +#endif +extern int errno; + +#endif /* _SUDO_SUDO_H */ diff --git a/usr.bin/sudo/sudo_setenv.c b/usr.bin/sudo/sudo_setenv.c new file mode 100644 index 00000000000..df55ac23b6b --- /dev/null +++ b/usr.bin/sudo/sudo_setenv.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +#include <malloc.h> +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#include <sys/types.h> +#include <sys/param.h> + +#include "sudo.h" + +#ifndef STDC_HEADERS +#ifdef HAVE_PUTENV +extern int putenv __P((const char *)); +#endif /* HAVE_PUTENV */ +#ifdef HAVE_SETENV +extern int setenv __P((char *, char *, int)); +#endif /* HAVE_SETENV */ +#endif /* !STDC_HEADERS */ + +#ifndef lint +static const char rcsid[] = "$Sudo: sudo_setenv.c,v 1.40 1999/07/31 16:19:48 millert Exp $"; +#endif /* lint */ + + +/* + * Add a string of the form "var=val" to the environment. If we are unable + * to expand the current environent, return -1, else return 0. + */ +int +sudo_setenv(var, val) + char *var; + char *val; +{ + +#ifdef HAVE_SETENV + return(setenv(var, val, 1)); +#else + char *envstring, *tmp; + + envstring = tmp = (char *) malloc(strlen(var) + strlen(val) + 2); + if (envstring == NULL) + return(-1); + + while ((*tmp++ = *var++)) + ; + + *(tmp-1) = '='; + + while ((*tmp++ = *val++)) + ; + + return(putenv(envstring)); +#endif /* HAVE_SETENV */ +} diff --git a/usr.bin/sudo/sudoers b/usr.bin/sudo/sudoers new file mode 100644 index 00000000000..f49eb49ddbc --- /dev/null +++ b/usr.bin/sudo/sudoers @@ -0,0 +1,15 @@ +# 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 + +# User privilege specification +root ALL=(ALL) ALL diff --git a/usr.bin/sudo/sudoers.5 b/usr.bin/sudo/sudoers.5 new file mode 100644 index 00000000000..1ea53b06aa0 --- /dev/null +++ b/usr.bin/sudo/sudoers.5 @@ -0,0 +1,934 @@ +.rn '' }` +''' $RCSfile: sudoers.5,v $$Revision: 1.1 $$Date: 1999/11/18 16:29:01 $ +''' +''' $Log: sudoers.5,v $ +''' Revision 1.1 1999/11/18 16:29:01 millert +''' Initial revision +''' +''' Revision 1.15 1999/11/16 05:23:41 millert +''' Add warning about using ALL in a command context. +''' +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.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" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH sudoers 5 "1.6" "15/Nov/1999" "FILE FORMATS" +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.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 ? ? +. ds ! ! +. ds / +. ds q +.\} +.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 ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" 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 v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.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 +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'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 v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. 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 +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +sudoers \- list of which users may execute what +.SH "DESCRIPTION" +The \fIsudoers\fR file is composed 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 (EBNF). +Don't despair if you don't know what EBNF is, it is fairly +simple and the definitions below are annotated. +.Sh "Quick guide to \s-1EBNF\s0" +\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. Eg. +.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?\fR" 8 +Means that the preceding symbol (or group of symbols) is optional. +That is, it may appear once or not at all. +.Ip "\f(CW*\fR" 8 +Means that the preceding symbol (or group of symbols) may appear +zero or more times. +.Ip "\f(CW+\fR" 8 +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" +There are four kinds of aliases: the \f(CWUser_Alias\fR, \f(CWRunas_Alias\fR, +\f(CWHost_Alias\fR and \f(CWCmnd_Alias\fR. +.PP +.Vb 4 +\& Alias ::= 'User_Alias' = User_Alias (':' User_Alias)* | +\& 'Runas_Alias' (':' Runas_Alias)* | +\& 'Host_Alias' (':' Host_Alias)* | +\& 'Cmnd_Alias' (':' Cmnd_Alias)* +.Ve +.Vb 1 +\& User_Alias ::= NAME '=' User_List +.Ve +.Vb 1 +\& Runas_Alias ::= NAME '=' Runas_User_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(CWUser_Alias\fR, \f(CWRunas_Alias\fR, \f(CWHost_Alias\fR, +or \f(CWCmnd_Alias\fR. A \f(CWNAME\fR is a string of upper case letters, numbers, +and the underscore characters ('_'). A \f(CWNAME\fR \fBmust\fR start with an +upper case letter. It is possible to put several alias definitions +of the same type on a single line, joined by a semicolon (':'). Eg. +.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 5 +\& User ::= '!'* username | +\& '!'* '#'uid | +\& '!'* '%'group | +\& '!'* '+'netgroup | +\& '!'* User_Alias +.Ve +A \f(CWUser_List\fR is made up of one or more usernames, uids +(prefixed with \*(L'#'), System groups (prefixed with \*(L'%'), +netgroups (prefixed with \*(L'+') and other aliases. Each list +item may be prefixed with one or more \*(L'!\*(R' operators. An odd number +of \*(L'!\*(R' operators negates 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 +Likewise, a \f(CWRunas_List\fR has the same possible elements +as a \f(CWUser_List\fR, except that it can include a \f(CWRunas_Alias\fR, +instead of a \f(CWUser_Alias\fR. +.PP +.Vb 2 +\& Host_List ::= Host | +\& Host ',' Host_List +.Ve +.Vb 5 +\& Host ::= '!'* hostname | +\& '!'* ip_addr | +\& '!'* network(/netmask)? | +\& '!'* '+'netgroup | +\& '!'* Host_Alias +.Ve +A \f(CWHost_List\fR is made up of one or more hostnames, \s-1IP\s0 addresses, +network numbers, netgroups (prefixed with \*(L'+') and other aliases. +Again, the value of an item may be negated with the \*(L'!\*(R' 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 (eg. +255.255.255.0) or \s-1CIDR\s0 notation (number of bits, eg. 24). +.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(CWCmnd_List\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\*(R' section below). A simple +filename allows the user to run the command with any arguments he/she +wishes. However, you may also command line arguments (including wildcards). +Alternately, you can specify \f(CW""\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 \*(L'/\*(R'. When you specify a directory +in a \f(CWCmnd_List\fR, the user will be able to run any file within that directory +(but not in any subdirectories therein). +.PP +If a \f(CWCmnd\fR has associated command line arguments, then the arguments +in the \f(CWCmnd\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 \*(L'\e\*(R' if they are used in command +arguments: \*(L',\*(R', \*(L':\*(R', \*(L'=\*(R', \*(L'\e\*(R'. +.Sh "Defaults" +Certain configuration options may be changed from their default +values at runtime via one or more \f(CWDefault_Entry\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 2 +\& Parameter ::= Parameter '=' Value || +\& '!'* Parameter || +.Ve +Parameters may be \fBflags\fR, \fBinteger\fR values, or \fBstrings\fR. Flags +are implicitly boolean and can be turned off via the \*(L'!\*(R' operator. +Some integer and string parameters may also be used in a boolean +context to disable them. Values may be enclosed in double quotes +(\f(CW"\fR) when they contain multiple words. Special characters may +be escaped with a backslash (\f(CW\e\fR). +.PP +\fBFlags\fR: +.Ip "long_otp_prompt" 12 +Put \s-1OTP\s0 prompt on its own line +.Ip "ignore_dot" 12 +Ignore \*(L'.\*(R' in \f(CW$PATH\fR +.Ip "mail_always" 12 +Always send mail when sudo is run +.Ip "mail_no_user" 12 +Send mail if the user is not in sudoers +.Ip "mail_no_host" 12 +Send mail if the user is not in sudoers for this host +.Ip "mail_no_perms" 12 +Send mail if the user is not allowed to run a command +.Ip "tty_tickets" 12 +Use a separate timestamp for each user/tty combo +.Ip "lecture" 12 +Lecture user the first time they run sudo +.Ip "authenticate" 12 +Require users to authenticate by default +.Ip "root_sudo" 12 +Root may run sudo +.Ip "log_host" 12 +Log the hostname in the (non-syslog) log file +.Ip "log_year" 12 +Log the year in the (non-syslog) log file +.Ip "shell_noargs" 12 +If sudo is invoked with no arguments, start a shell +.Ip "set_home" 12 +Set \f(CW$HOME\fR to the target user when starting a shell with \f(CW-s\fR +.Ip "path_info" 12 +Allow some information gathering to give useful error messages +.Ip "fqdn" 12 +Require fully-qualified hostnames in the sudoers file +.Ip "insults" 12 +Insult the user when they enter an incorrect password +.Ip "requiretty" 12 +Only allow the user to run sudo if they have a tty +.PP +\fBIntegers\fR: +.Ip "passwd_tries" 12 +Number of tries to enter a password +.PP +\fBIntegers that can be used in a boolean context\fR: +.Ip "loglinelen" 12 +Length at which to wrap log file lines (use 0 or negate for no wrap) +.Ip "timestamp_timeout" 12 +Authentication timestamp timeout +.Ip "passwd_timeout" 12 +Password prompt timeout +.Ip "umask" 12 +Umask to use or 0777 to use user's +.PP +\fBStrings\fR: +.Ip "mailsub" 12 +Subject line for mail messages +.Ip "badpass_message" 12 +Incorrect password message +.Ip "timestampdir" 12 +Path to authentication timestamp dir +.Ip "passprompt" 12 +Default password prompt +.Ip "runas_default" 12 +Default user to run commands as +.Ip "syslog_goodpri" 12 +Syslog priority to use when user authenticates successfully +.Ip "syslog_badpri" 12 +Syslog priority to use when user authenticates unsuccessfully +.PP +\fBStrings that can be used in a boolean context\fR: +.Ip "syslog" 12 +Syslog facility if syslog is being used for logging (negate to disable syslog) +.Ip "mailerpath" 12 +Path to mail program +.Ip "mailerflags" 12 +Flags for mail program +.Ip "mailto" 12 +Address to send mail to +.Ip "exempt_group" 12 +Users in this group are exempt from password and \s-1PATH\s0 requirements +.Ip "secure_path" 12 +Value to override user's \f(CW$PATH\fR with +.PP +When logging via \fIsyslog\fR\|(3), sudo 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" +.PP +.Vb 1 +\& Runas_Spec ::= '(' Runas_List ')' +.Ve +.Vb 1 +\& Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd +.Ve +.Vb 2 +\& Cmnd_Spec_List ::= Cmnd_Spec | +\& Cmnd_Spec ',' Cmnd_Spec_List +.Ve +.Vb 1 +\& User_Spec ::= User_list Cmnd_Spec_List (':' User_Spec)* +.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" +A \f(CWRunas_Spec\fR is simply a \f(CWRunas_List\fR (as defined above) +enclosed in a set of parentheses. If you do not specify a +\f(CWRunas_Spec\fR in the user specification, a default \f(CWRunas_Spec\fR +of \fBroot\fR will be used. A \f(CWRunas_Spec\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. Eg. +.PP +.Vb 1 +\& sudo -u operator /bin/ls. +.Ve +It is also possible to override a \f(CWRunas_Spec\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" +By default, \fBsudo\fR requires that a user authenticate him or herself +before running a command. This behavior can be modified via the +\f(CWNOPASSWD\fR tag. Like a \f(CWRunas_Spec\fR, the \f(CWNOPASSWD\fR tag sets +a default for the commands that follow it in the \f(CWCmnd_Spec_List\fR. +Conversely, the \f(CWPASSWD\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 +.Sh "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(CWfnmatch(3)\fR routine. Note that +these are \fInot\fR regular expressions. +.Ip "\f(CW*\fR" 8 +Matches any set of zero or more characters. +.Ip "\f(CW?\fR" 8 +Matches any single character. +.Ip "\f(CW[...]\fR" 8 +Matches any character in the specified range. +.Ip "\f(CW[!...]\fR" 8 +Matches any character \fBnot\fR in the specified range. +.Ip "\f(CW\ex\fR" 8 +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/usr/bin/who\fR but not \f(CW/usr/bin/X11/xterm\fR. +.Sh "Exceptions to wildcard rules:" +The following exceptions apply to the above rules: +.Ip \f(CW""\fR 8 +If the empty string \f(CW""\fR is the only command line argument in the +\fIsudoers\fR entry it means that command is not allowed to be run +with \fBany\fR arguments. +.Sh "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 a built in \fIalias\fR that always causes +a match to succeed. It can be used wherever one might otherwise +use a \f(CWCmnd_Alias\fR, \f(CWUser_Alias\fR, \f(CWRunas_Alias\fR, or \f(CWHost_Alias\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 (\*(R'!') can be used as a logical \fInot\fR operator +both in an \fIalias\fR and in front of a \f(CWCmnd\fR. This allows one to +exclude certain values. Note, however, that using a \f(CW!\fR in +conjunction with the built in \f(CWALL\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 (\*(R'\e') as the last +character on the line. +.PP +Whitespace between elements in a list as well as specicial syntactic +characters in a \fIUser Specification\fR ('=\*(R', \*(L':\*(R', \*(L'(\*(R', \*(L')') is optional. +.PP +The following characters must be escaped with a backslash (\*(R'\e') when +used as part of a word (eg. a username or hostname): +\&'@\*(R', \*(L'!\*(R', \*(L'=\*(R', \*(L':\*(R', \*(L',\*(R', \*(L'(\*(R', \*(L')\*(R', \*(L'\e\*(R'. +.SH "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 +sudo 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 \fISERVERS\fR \f(CWHost_Alias\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 builtin 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(CWNOPASSWD\fR tag). +.PP +.Vb 1 +\& jack CSNETS = ALL +.Ve +The user \fBjack\fR may run any command on the machines in the \fICSNETS\fR alias +(the networks \f(CW128.138.243.0\fR, \f(CW128.138.204.0\fR, and \f(CW128.138.242.0\fR). +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 \fICSNETS\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 \fICUNETS\fR alias +(the class B network \f(CW128.138.0.0\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 \fIHPPA\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 \fISPARC\fR and \fISGI\fR machines +as any user listed in the \fIOP\fR \f(CWRunas_Alias\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 \*(L'+\*(R' 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 \fIDB\fR \f(CWRunas_Alias\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 \fIALPHA\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 \fISERVERS\fR \f(CWHost_Alias\fR (master, mail, www and ns). +.PP +.Vb 1 +\& jill SERVERS = /usr/bin/, !SU, !SHELLS +.Ve +For any machine in the \fISERVERS\fR \f(CWHost_Alias\fR, \fBjill\fR may run +any commands in the directory /usr/bin/ except for those commands +belonging to the \fISU\fR and \fISHELLS\fR \f(CWCmnd_Aliases\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 \fIWEBMASTERS\fR \f(CWUser_Alias\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 CD\-ROM on the machines in the CDROM +\f(CWHost_Alias\fR (orion, perseus, hercules) without entering a password. +This is a bit tedious for users to type, so it is a prime candiate +for encapsulating in a shell script. +.SH "SECURITY NOTES" +It is generally not effective to \*(L"subtract\*(R" commands from \f(CWALL\fR +using the \*(L'!\*(R' 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 +\fISU\fR or \fISHELLS\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" +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. +.SH "FILES" +.PP +.Vb 3 +\& /etc/sudoers List of who can run what +\& /etc/group Local groups file +\& /etc/netgroup List of network groups +.Ve +.SH "SEE ALSO" +\fIsudo\fR\|(8), \fIvisudo\fR\|(8), \fIsu\fR\|(1), \fIfnmatch\fR\|(3). + +.rn }` '' +.IX Title "sudoers 5" +.IX Name "sudoers - list of which users may execute what" + +.IX Header "NAME" + +.IX Header "DESCRIPTION" + +.IX Subsection "Quick guide to \s-1EBNF\s0" + +.IX Item "\f(CW?\fR" + +.IX Item "\f(CW*\fR" + +.IX Item "\f(CW+\fR" + +.IX Subsection "Aliases" + +.IX Subsection "Defaults" + +.IX Item "long_otp_prompt" + +.IX Item "ignore_dot" + +.IX Item "mail_always" + +.IX Item "mail_no_user" + +.IX Item "mail_no_host" + +.IX Item "mail_no_perms" + +.IX Item "tty_tickets" + +.IX Item "lecture" + +.IX Item "authenticate" + +.IX Item "root_sudo" + +.IX Item "log_host" + +.IX Item "log_year" + +.IX Item "shell_noargs" + +.IX Item "set_home" + +.IX Item "path_info" + +.IX Item "fqdn" + +.IX Item "insults" + +.IX Item "requiretty" + +.IX Item "passwd_tries" + +.IX Item "loglinelen" + +.IX Item "timestamp_timeout" + +.IX Item "passwd_timeout" + +.IX Item "umask" + +.IX Item "mailsub" + +.IX Item "badpass_message" + +.IX Item "timestampdir" + +.IX Item "passprompt" + +.IX Item "runas_default" + +.IX Item "syslog_goodpri" + +.IX Item "syslog_badpri" + +.IX Item "syslog" + +.IX Item "mailerpath" + +.IX Item "mailerflags" + +.IX Item "mailto" + +.IX Item "exempt_group" + +.IX Item "secure_path" + +.IX Subsection "User Specification" + +.IX Subsection "Runas_Spec" + +.IX Subsection "\s-1NOPASSWD\s0 and \s-1PASSWD\s0" + +.IX Subsection "Wildcards (aka meta characters):" + +.IX Item "\f(CW*\fR" + +.IX Item "\f(CW?\fR" + +.IX Item "\f(CW[...]\fR" + +.IX Item "\f(CW[!...]\fR" + +.IX Item "\f(CW\ex\fR" + +.IX Subsection "Exceptions to wildcard rules:" + +.IX Item "\f(CW""\fR" + +.IX Subsection "Other special characters and reserved words:" + +.IX Header "EXAMPLES" + +.IX Header "SECURITY NOTES" + +.IX Header "CAVEATS" + +.IX Header "FILES" + +.IX Header "SEE ALSO" + diff --git a/usr.bin/sudo/testsudoers.c b/usr.bin/sudo/testsudoers.c new file mode 100644 index 00000000000..ee4d2fe1c39 --- /dev/null +++ b/usr.bin/sudo/testsudoers.c @@ -0,0 +1,383 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * This code is derived from software contributed by Chris Jepeway + * <jepeway@cs.utk.edu>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_FNMATCH) && defined(HAVE_FNMATCH_H) +# include <fnmatch.h> +#endif /* HAVE_FNMATCH_H */ +#ifdef HAVE_NETGROUP_H +# include <netgroup.h> +#endif /* HAVE_NETGROUP_H */ +#include <ctype.h> +#include <pwd.h> +#include <grp.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/stat.h> +#include <dirent.h> + +#include "sudo.h" +#include "parse.h" +#include "interfaces.h" + +#ifndef HAVE_FNMATCH +# include "emul/fnmatch.h" +#endif /* HAVE_FNMATCH */ + +#ifndef lint +static const char rcsid[] = "$Sudo: testsudoers.c,v 1.64 1999/09/08 08:06:19 millert Exp $"; +#endif /* lint */ + +/* + * Globals + */ +char **Argv, **NewArgv; +int Argc, NewArgc; +int parse_error = FALSE; +int num_interfaces; +struct interface *interfaces; +struct sudo_user sudo_user; +extern int clearaliases; +extern int pedantic; + +/* + * Prototypes for external functions + */ +void init_parser __P((void)); +void dumpaliases __P((void)); + +/* + * Returns TRUE if "s" has shell meta characters in it, + * else returns FALSE. + */ +int +has_meta(s) + char *s; +{ + register 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 + mask.s_addr = (1 << atoi(m)) - 1; /* XXX - better way? */ + *(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 +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, user) + char *netgr; + char *host; + 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 + return(innetgr(netgr, host, user, domain)); +#else + return(FALSE); +#endif /* HAVE_INNETGR */ +} + +void +set_perms(i, j) + int i, j; +{ + return; +} + +int +main(argc, argv) + int argc; + char **argv; +{ + struct passwd pw; + char *p; +#ifdef YYDEBUG + extern int yydebug; + yydebug = 1; +#endif + + Argv = argv; + Argc = argc; + + if (Argc >= 6 && strcmp(Argv[1], "-u") == 0) { + user_runas = &Argv[2]; + pw.pw_name = Argv[3]; + user_host = Argv[4]; + user_cmnd = Argv[5]; + + NewArgv = &Argv[5]; + NewArgc = Argc - 5; + } else if (Argc >= 4) { + pw.pw_name = Argv[1]; + user_host = Argv[2]; + user_cmnd = Argv[3]; + + NewArgv = &Argv[3]; + NewArgc = Argc - 3; + } else { + (void) fprintf(stderr, + "usage: %s [-u user] <user> <host> <command> [args]\n", Argv[0]); + exit(1); + } + + sudo_user.pw = &pw; /* user_name needs to be defined */ + + if ((p = strchr(user_host, '.'))) { + *p = '\0'; + user_shost = estrdup(user_host); + *p = '.'; + } else { + user_shost = user_host; + } + + /* Fill in cmnd_args from NewArgv. */ + if (NewArgc > 1) { + size_t size; + char *to, **from; + + size = (size_t) NewArgv[NewArgc-1] + strlen(NewArgv[NewArgc-1]) - + (size_t) NewArgv[1] + 1; + user_args = (char *) emalloc(size); + for (to = user_args, from = &NewArgv[1]; *from; from++) { + *to++ = ' '; + (void) strcpy(to, *from); + to += strlen(*from); + } + } + + /* Initialize default values. */ + init_defaults(); + + /* Warn about aliases that are used before being defined. */ + pedantic = TRUE; + + /* Need to keep aliases around for dumpaliases(). */ + clearaliases = FALSE; + + /* Load ip addr/mask for each interface. */ + load_interfaces(); + + /* Allocate space for data structures in the parser. */ + init_parser(); + + if (yyparse() || parse_error) { + (void) printf("doesn't parse.\n"); + } else { + (void) printf("parses OK.\n\n"); + if (top == 0) + (void) printf("User %s not found\n", pw.pw_name); + else while (top) { + (void) printf("[%d]\n", top-1); + (void) printf("user_match : %d\n", user_matches); + (void) printf("host_match : %d\n", host_matches); + (void) printf("cmnd_match : %d\n", cmnd_matches); + (void) printf("no_passwd : %d\n", no_passwd); + (void) printf("runas_match: %d\n", runas_matches); + (void) printf("runas : %s\n", *user_runas); + top--; + } + } + + /* Dump aliases. */ + (void) printf("Matching Aliases --\n"); + dumpaliases(); + + exit(0); +} diff --git a/usr.bin/sudo/tgetpass.c b/usr.bin/sudo/tgetpass.c new file mode 100644 index 00000000000..786106b2970 --- /dev/null +++ b/usr.bin/sudo/tgetpass.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <pwd.h> +#include <sys/param.h> +#include <sys/types.h> +#ifdef HAVE_SYS_BSDTYPES_H +#include <sys/bsdtypes.h> +#endif /* HAVE_SYS_BSDTYPES_H */ +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif /* HAVE_SYS_SELECT_H */ +#include <sys/time.h> +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#ifdef HAVE_TERMIOS_H +#include <termios.h> +#else +#ifdef HAVE_TERMIO_H +#include <termio.h> +#else +#include <sgtty.h> +#include <sys/ioctl.h> +#endif /* HAVE_TERMIO_H */ +#endif /* HAVE_TERMIOS_H */ + +#include "sudo.h" + +#ifndef TCSASOFT +#define TCSASOFT 0 +#endif /* TCSASOFT */ + +#ifndef lint +static const char rcsid[] = "$Sudo: tgetpass.c,v 1.90 1999/11/01 15:58:46 millert Exp $"; +#endif /* lint */ + +static char *tgetline __P((int, char *, size_t, int)); + +/* + * Like getpass(3) but with timeout and echo flags. + */ +char * +tgetpass(prompt, timeout, echo_off) + const char *prompt; + int timeout; + int echo_off; +{ +#ifdef HAVE_TERMIOS_H + struct termios term; +#else +#ifdef HAVE_TERMIO_H + struct termio term; +#else + struct sgttyb ttyb; +#endif /* HAVE_TERMIO_H */ +#endif /* HAVE_TERMIOS_H */ + int input, output; + static char buf[SUDO_PASS_MAX + 1]; + + /* Open /dev/tty for reading/writing if possible else use stdin/stderr. */ + if ((input = output = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + if (prompt) + (void) write(output, prompt, strlen(prompt) + 1); + + if (echo_off) { +#ifdef HAVE_TERMIOS_H + (void) tcgetattr(input, &term); + if ((echo_off = (term.c_lflag & ECHO))) { + term.c_lflag &= ~ECHO; + (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } +#else +#ifdef HAVE_TERMIO_H + (void) ioctl(input, TCGETA, &term); + if ((echo_off = (term.c_lflag & ECHO))) { + term.c_lflag &= ~ECHO; + (void) ioctl(input, TCSETA, &term); + } +#else + (void) ioctl(input, TIOCGETP, &ttyb); + if ((echo_off = (ttyb.sg_flags & ECHO))) { + ttyb.sg_flags &= ~ECHO; + (void) ioctl(input, TIOCSETP, &ttyb); + } +#endif /* HAVE_TERMIO_H */ +#endif /* HAVE_TERMIOS_H */ + } + + buf[0] = '\0'; + tgetline(input, buf, sizeof(buf), timeout); + +#ifdef HAVE_TERMIOS_H + if (echo_off) { + term.c_lflag |= ECHO; + (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } +#else +#ifdef HAVE_TERMIO_H + if (echo_off) { + term.c_lflag |= ECHO; + (void) ioctl(input, TCSETA, &term); + } +#else + if (echo_off) { + ttyb.sg_flags |= ECHO; + (void) ioctl(input, TIOCSETP, &ttyb); + } +#endif /* HAVE_TERMIO_H */ +#endif /* HAVE_TERMIOS_H */ + + if (echo_off) + (void) write(output, "\n", 1); + + if (input != STDIN_FILENO) + (void) close(input); + + return(buf); +} + +/* + * 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; +{ + size_t left; + int n; + fd_set *readfds = NULL; + struct timeval tv; + char c; + char *cp; + + if (bufsiz == 0) + return(NULL); /* sanity */ + + /* + * 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); + FD_SET(fd, readfds); + + /* Set timeout for select */ + tv.tv_sec = timeout; + tv.tv_usec = 0; + + /* + * Make sure there is something to read or timeout + */ + while ((n = select(fd + 1, readfds, 0, 0, &tv)) == -1 && + errno == EINTR) + ; + if (n == 0) + return(NULL); /* timeout */ + } + if (readfds) + free(readfds); + + /* Keep reading until out of space, EOF, error, or newline */ + cp = buf; + left = bufsiz; + while (--left && (n = read(fd, &c, 1)) == 1 && c != '\n') + *cp++ = c; + *cp = '\0'; + + return(cp == buf ? NULL : buf); +} diff --git a/usr.bin/sudo/version.h b/usr.bin/sudo/version.h new file mode 100644 index 00000000000..6799a10c1b9 --- /dev/null +++ b/usr.bin/sudo/version.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Sudo: version.h,v 1.54 1999/07/31 16:19:48 millert Exp $ + */ + +#ifndef _SUDO_VERSION_H +#define _SUDO_VERSION_H + +static const char version[] = "1.6"; + +#endif /* _SUDO_VERSION_H */ diff --git a/usr.bin/sudo/visudo.8 b/usr.bin/sudo/visudo.8 new file mode 100644 index 00000000000..b4c3ae7b625 --- /dev/null +++ b/usr.bin/sudo/visudo.8 @@ -0,0 +1,324 @@ +.rn '' }` +''' $RCSfile: visudo.8,v $$Revision: 1.1 $$Date: 1999/11/18 16:29:01 $ +''' +''' $Log: visudo.8,v $ +''' Revision 1.1 1999/11/18 16:29:01 millert +''' Initial revision +''' +''' Revision 1.12 1999/11/16 05:42:28 millert +''' get rid of references to sudo-bugs. Now mention the web site or the sudo@ alias +''' +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.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" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH visudo 8 "1.6" "15/Nov/1999" "MAINTENANCE COMMANDS" +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.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 ? ? +. ds ! ! +. ds / +. ds q +.\} +.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 ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" 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 v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.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 +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'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 v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. 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 +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +visudo \- edit the sudoers file +.SH "SYNOPSIS" +\fBvisudo\fR [ \fB\-s\fR ] [ \fB\-V\fR ] +.SH "DESCRIPTION" +\fBvisudo\fR edits the \fIsudoers\fR file in a safe fashion, analogous to +\fIvipw\fR\|(8). \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. In the +default configuration, the \fIvi\fR\|(1) editor is used, but there is +a compile time option to allow use of whatever editor the +environment variables \f(CWEDITOR\fR or \f(CWVISUAL\fR are set to. +.PP +\fBvisudo\fR parses the \fIsudoers\fR file after the edit and will +not save the changes if there is a syntax error. Upon finding +an error, a message will be printed stating the line \fInumber\fR\|(s) +that the error occurred on and the user will receive the +\*(L"What now?\*(R" prompt. At this point the user may enter \*(L"e\*(R" +to re-edit the \fIsudoers\fR file, enter \*(L"x\*(R" to exit without +saving the changes, or \*(L"Q\*(R" to quit and save changes. The +\*(L"Q\*(R" option should be used with extreme care because if \fBvisudo\fR +believes there to be a parse error, so will \fBsudo\fR and no one +will be able to execute \fBsudo\fR again until the error is fixed. +Any other command at this prompt will print a short help message. +When editing the \fIsudoers\fR file after a parse error has been +detected the cursor will be placed on the line where the error +occurred (if the editor supports this feature). +.SH "OPTIONS" +\fBvisudo\fR accepts the following command line option: +.Ip "-s" 4 +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 upper case +letters, digits, and the underscore ('_') character. +.Ip "-V" 4 +The \f(CW-V\fR (version) option causes \fBvisudo\fR to print the version number +and exit. +.SH "ERRORS" +.Ip "sudoers file busy, try again later." 4 +Someone else is currently editing the \fIsudoers\fR file. +.Ip "/etc/sudoers.tmp: Permission denied" 4 +You didn't run \fBvisudo\fR as root. +.Ip "Can't find you in the passwd database" 4 +Your userid does not appear in the system passwd file. +.Ip "Warning: undeclared Alias referenced near ..." 4 +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 upper case letters, digits, and the +underscore ('_') character. If the latter, you can ignore +the warnings (\fBsudo\fR will not complain). In \fB\-s\fR (strict) +mode these are errors not warnings. +.SH "ENVIRONMENT" +The following environment variables are used only if \fBvisudo\fR +was configured with the \fI--with-env-editor\fR option: +.Sp +.Vb 2 +\& EDITOR Used by visudo as the editor to use +\& VISUAL Used by visudo if EDITOR is not set +.Ve +.SH "FILES" +.Sp +.Vb 2 +\& /etc/sudoers List of who can run what +\& /etc/sudoers.tmp Lock file for visudo +.Ve +.SH "AUTHOR" +Many people have worked on \fIsudo\fR over the years, this version of +\fBvisudo\fR was written by: +.Sp +.Vb 1 +\& Todd Miller <Todd.Miller@courtesan.com> +.Ve +See the HISTORY file in the sudo distribution for more details. +.SH "BUGS" +If you feel you have found a bug in sudo, please submit a bug report +at http://www.courtesan.com/sudo/bugs/. +.SH "DISCLAIMER" +\fBVisudo\fR is provided ``AS IS'\*(R' 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 \fBsudo\fR for complete details. +.SH "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" +\fIsudo\fR\|(8), \fIvipw\fR\|(8). + +.rn }` '' +.IX Title "visudo 8" +.IX Name "visudo - edit the sudoers file" + +.IX Header "NAME" + +.IX Header "SYNOPSIS" + +.IX Header "DESCRIPTION" + +.IX Header "OPTIONS" + +.IX Item "-s" + +.IX Item "-V" + +.IX Header "ERRORS" + +.IX Item "sudoers file busy, try again later." + +.IX Item "/etc/sudoers.tmp: Permission denied" + +.IX Item "Can't find you in the passwd database" + +.IX Item "Warning: undeclared Alias referenced near ..." + +.IX Header "ENVIRONMENT" + +.IX Header "FILES" + +.IX Header "AUTHOR" + +.IX Header "BUGS" + +.IX Header "DISCLAIMER" + +.IX Header "CAVEATS" + +.IX Header "SEE ALSO" + diff --git a/usr.bin/sudo/visudo.c b/usr.bin/sudo/visudo.c new file mode 100644 index 00000000000..ee064c92162 --- /dev/null +++ b/usr.bin/sudo/visudo.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. Products derived from this software may not be called "Sudo" nor + * may "Sudo" appear in their names without specific prior written + * permission from the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Lock the sudoers file for safe editing (ala vipw) and check for parse errors. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#endif /* STDC_HEADERS */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +#include <malloc.h> +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include <ctype.h> +#include <pwd.h> +#include <time.h> +#include <signal.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/file.h> + +#include "sudo.h" +#include "version.h" + +#ifndef STDC_HEADERS +#ifndef __GNUC__ /* gcc has its own malloc */ +extern char *malloc __P((size_t)); +#endif /* __GNUC__ */ +extern char *getenv __P((const char *)); +extern int stat __P((const char *, struct stat *)); +#endif /* !STDC_HEADERS */ + +#if defined(POSIX_SIGNALS) && !defined(SA_RESETHAND) +#define SA_RESETHAND 0 +#endif /* POSIX_SIGNALS && !SA_RESETHAND */ + +#ifndef lint +static const char rcsid[] = "$Sudo: visudo.c,v 1.116 1999/11/09 20:12:20 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)); +int command_matches __P((char *, char *, char *, char *)); +int addr_matches __P((char *)); +int netgr_matches __P((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; + +/* + * 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; /* editor to use (default is EDITOR */ + int sudoers_fd; /* sudoers file descriptor */ + int stmp_fd; /* stmp file descriptor */ + int n; /* length parameter */ + 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. + */ + while (--argc) { + if (!strcmp(argv[argc], "-V")) { + (void) printf("visudo version %s\n", version); + exit(0); + } else if (!strcmp(argv[argc], "-s")) { + pedantic++; /* strict mode */ + } else { + 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); + } + +#ifdef ENV_EDITOR + /* + * If we are allowing EDITOR and VISUAL envariables set Editor + * base on whichever exists... + */ + if (!(Editor = getenv("EDITOR"))) + if (!(Editor = getenv("VISUAL"))) + Editor = EDITOR; +#endif /* ENV_EDITOR */ + + /* + * Open sudoers temp file and grab a lock. + */ + stmp_fd = open(stmp, O_WRONLY | O_CREAT, 0600); + if (stmp_fd < 0) { + (void) fprintf(stderr, "%s: %s\n", Argv[0], strerror(errno)); + exit(1); + } + if (!lock_file(stmp_fd, SUDO_TLOCK)) { + (void) fprintf(stderr, "%s: sudoers file busy, try again later.\n", + Argv[0]); + exit(1); + } +#ifdef HAVE_FTRUNCATE + if (ftruncate(stmp_fd, 0) == -1) { +#else + if (truncate(stmp, 0) == -1) { +#endif + (void) fprintf(stderr, "%s: can't truncate %s: %s\n", Argv[0], + stmp, strerror(errno)); + Exit(-1); + } + + /* Install signal handlers to clean up stmp if we are killed. */ + setup_signals(); + + (void) memset(&sudoers_sb, 0, sizeof(sudoers_sb)); + if (stat(sudoers, &sudoers_sb) == -1 && errno != ENOENT) { + (void) fprintf(stderr, "%s: %s\n", Argv[0], strerror(errno)); + Exit(-1); + } + sudoers_fd = open(sudoers, O_RDONLY); + if (sudoers_fd == -1 && errno != ENOENT) { + (void) fprintf(stderr, "%s: %s\n", Argv[0], strerror(errno)); + Exit(-1); + } + + /* Copy sudoers -> stmp and reset the mtime */ + if (sudoers_fd != -1) { + 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(sudoers_fd); + } + (void) close(stmp_fd); + (void) touch(stmp, sudoers_sb.st_mtime); + + /* + * Edit the temp file and parse it (for sanity checking) + */ + do { + /* + * Build up a buffer to execute + */ + if (strlen(Editor) + strlen(stmp) + 30 > sizeof(buf)) { + (void) fprintf(stderr, "%s: Buffer too short (line %d).\n", + Argv[0], __LINE__); + Exit(-1); + } + if (parse_error == TRUE) + (void) sprintf(buf, "%s +%d %s", Editor, errorlineno, stmp); + else + (void) sprintf(buf, "%s %s", Editor, stmp); + + /* Do the edit -- some SYSV editors exit with 1 instead of 0 */ + now = time(NULL); + n = system(buf); + if (n != -1 && ((n >> 8) == 0 || (n >> 8) == 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 */ + 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 with exit status %d, %s unchanged.\n", + Argv[0], Editor, n, 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' : 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) { + char *tmpbuf; + + (void) fprintf(stderr, + "%s: %s and %s not on the same filesystem, using mv to rename.\n", + Argv[0], stmp, sudoers); + + /* Allocate just enough space for tmpbuf */ + n = sizeof(char) * (strlen(_PATH_MV) + strlen(stmp) + + strlen(sudoers) + 4); + if ((tmpbuf = (char *) malloc(n)) == NULL) { + (void) fprintf(stderr, + "%s: Cannot alocate memory, %s unchanged: %s\n", + Argv[0], sudoers, strerror(errno)); + Exit(-1); + } + + /* Build up command and execute it */ + (void) sprintf(tmpbuf, "%s %s %s", _PATH_MV, stmp, sudoers); + if (system(tmpbuf)) { + (void) fprintf(stderr, + "%s: Command failed: '%s', %s unchanged.\n", + Argv[0], tmpbuf, sudoers); + Exit(-1); + } + free(tmpbuf); + } else { + (void) fprintf(stderr, "%s: Error renaming %s, %s unchanged: %s\n", + Argv[0], stmp, sudoers, strerror(errno)); + Exit(-1); + } + } + + return(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 +usergr_matches(g, u) + char *g, *u; +{ + return(TRUE); +} + +int +netgr_matches(n, h, u) + char *n, *h, *u; +{ + return(TRUE); +} + +/* + * 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(); + + if (choice == 'e' || choice == 'x' || choice == 'Q') + break; + else { + (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"); + } + } + + return(choice); +} + +/* + * Install signal handlers for visudo. + */ +static void +setup_signals() +{ +#ifdef POSIX_SIGNALS + struct sigaction action; /* POSIX signal structure */ +#endif /* POSIX_SIGNALS */ + + /* + * Setup signal handlers to cleanup nicely. + */ +#ifdef POSIX_SIGNALS + (void) memset((VOID *)&action, 0, sizeof(action)); + action.sa_handler = Exit; + action.sa_flags = SA_RESETHAND; + (void) sigaction(SIGTERM, &action, NULL); + (void) sigaction(SIGHUP, &action, NULL); + (void) sigaction(SIGINT, &action, NULL); + (void) sigaction(SIGQUIT, &action, NULL); +#else + (void) signal(SIGTERM, Exit); + (void) signal(SIGHUP, Exit); + (void) signal(SIGINT, Exit); + (void) signal(SIGQUIT, Exit); +#endif /* POSIX_SIGNALS */ +} + +/* + * 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 is considered to be a signal and is reported. + */ +static RETSIGTYPE +Exit(sig) + int sig; +{ + (void) unlink(stmp); + + if (sig > 0) + (void) fprintf(stderr, "%s exiting, caught signal %d.\n", Argv[0], sig); + + exit(-sig); +} + +static void +usage() +{ + (void) fprintf(stderr, "usage: %s [-s] [-V]\n", Argv[0]); + exit(1); +} |