Imported Upstream version 1.7.2 upstream/1.7.2
authorBdale Garbee <bdale@gag.com>
Wed, 15 Jul 2009 06:48:52 +0000 (00:48 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 15 Jul 2009 06:48:52 +0000 (00:48 -0600)
65 files changed:
ChangeLog
INSTALL
LICENSE
Makefile.in
README
TROUBLESHOOTING
WHATSNEW
aclocal.m4
alias.c
audit.c [new file with mode: 0644]
auth/aix_auth.c
auth/pam.c
auth/sudo_auth.c
auth/sudo_auth.h
bsm_audit.c [new file with mode: 0644]
bsm_audit.h [new file with mode: 0644]
check.c
config.h.in
configure
configure.in
def_data.c
def_data.h
def_data.in
env.c
fileops.c
glob.c
gram.c
gram.y
interfaces.c
lbuf.c
ldap.c
logging.c
logging.h
match.c
nonunix.h [new file with mode: 0644]
parse.c
parse.h
pathnames.h.in
pwutil.c
redblack.c
set_perms.c
sudo.c
sudo.cat
sudo.h
sudo.man.in
sudo.pod
sudo_nss.c
sudo_nss.h
sudo_usage.h.in
sudoers.cat
sudoers.ldap.cat
sudoers.ldap.man.in
sudoers.ldap.pod
sudoers.man.in
sudoers.pod
term.c [new file with mode: 0644]
testsudoers.c
tgetpass.c
toke.c
toke.l
vasgroups.c [new file with mode: 0644]
version.h [deleted file]
visudo.c
visudo.cat
visudo.man.in

index 63023fc1c1d6e5d1ca669c6905c600df072eb6a3..5c61070320939558f7389324e6ff2d7dedbf48e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,586 @@
+2009-06-30 08:41  millert
+
+       * sudoers.cat, sudoers.man.in, sudoers.pod: Add missing single
+         quotes around a colon in Runas_Spec definition.  From Elias
+         Benali.
+
+2009-06-29 09:36  millert
+
+       * redblack.c: In rbrepair, re-color the root or the first non-block
+         node we find to be black.  Re-coloring the root is probably not
+         needed but won't hurt.
+
+2009-06-29 09:35  millert
+
+       * sudo.cat, sudoers.cat, sudo.man.in, sudoers.man.in: regen
+
+2009-06-26 16:40  millert
+
+       * redblack.c: When repairing the tree, don't touch the root node.
+
+2009-06-25 08:44  millert
+
+       * set_perms.c: Protect call to setegid in runas_setup with #ifdef
+         HAVE_SETEUID.  Reported by Josef Schmid.
+
+2009-06-23 14:29  millert
+
+       * sudoers.pod: Document that we accept env_pam-style environment
+         files
+
+2009-06-23 14:24  millert
+
+       * env.c: Adapt to accept pam_env-style /etc/environment which
+         allows shell-style lines such as: export EDITOR="/usr/bin/vi"
+
+2009-06-23 12:22  millert
+
+       * sudoers.pod: Make it clear that env_delete only works when
+         !env_reset.  From Loïc Minier
+
+2009-06-15 17:19  millert
+
+       * sudo.pod, sudoers.pod: Add non-unix group bits, adapted from
+         Quest
+
+2009-06-15 17:18  millert
+
+       * Makefile.in: build the .cat page in the current working dir, not
+         the src dir
+
+2009-06-15 09:10  millert
+
+       * env.c: Return EINVAL in setenv() if var is NULL or the empty
+         string to match glibc behavior.
+
+2009-06-13 16:52  millert
+
+       * configure, configure.in: Use AS_HELP_STRING for AC_ARG_WITH and
+         AC_ARG_ENABLE
+
+2009-06-11 16:29  millert
+
+       * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+         sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+         regen
+
+2009-06-09 10:08  millert
+
+       * INSTALL: Document --with-libvas and --with-libvas-rpath
+
+2009-05-29 09:43  millert
+
+       * ldap.c, sudoers.ldap.pod: For netscape-derived LDAP SDKs the cert
+         and key paths may be a directory or a file.  However, version 5.0
+         of the SDK only seems to support using a directory.  If
+         ldapssl_clientauth_init fails and the cert or key paths look like
+         they could be files, strip off the last path element and try
+         again.
+
+2009-05-29 09:40  millert
+
+       * Makefile.in: Add non-Unix group .o to COMMON_OBJS and substitute
+         in path to flex.
+
+2009-05-26 20:49  millert
+
+       * configure, configure.in, match.c, sudo.c, vasgroups.c: Update
+         non-Unix group support from Quest, as reworked by me.
+
+2009-05-26 20:47  millert
+
+       * toke.c: regen
+
+2009-05-26 20:46  millert
+
+       * toke.l: Add support for escaped hex chars in names, e.g. \x20 for
+         space.
+
+2009-05-25 08:02  millert
+
+       * LICENSE, Makefile.in, aclocal.m4, alias.c, check.c, env.c,
+         fileops.c, glob.c, gram.y, interfaces.c, lbuf.c, ldap.c,
+         logging.c, logging.h, match.c, parse.c, parse.h, pathnames.h.in,
+         pwutil.c, set_perms.c, sudo.c, sudo.h, sudo.pod, sudo_nss.c,
+         sudo_nss.h, sudo_usage.h.in, sudoers.ldap.pod, sudoers.pod,
+         testsudoers.c, tgetpass.c, toke.l, visudo.c, auth/aix_auth.c,
+         auth/pam.c, auth/sudo_auth.c, auth/sudo_auth.h: Update copyright
+         years.
+
+2009-05-24 08:33  millert
+
+       * interfaces.c, lbuf.c: Minor fixes for Minix-3
+
+2009-05-22 06:37  millert
+
+       * set_perms.c: Handle getgroups() returning 0.  Also add missing
+         check for HAVE_GETGROUPS.
+
+2009-05-19 17:24  millert
+
+       * Makefile.in, config.h.in, configure, configure.in, sudo.c,
+         version.h, visudo.c: Replace version.h with PACKAGE_VERSION set
+         via AC_INIT in configure.
+
+2009-05-18 06:33  millert
+
+       * set_perms.c: Remove group setting code in setusercontext case, we
+         will do it ourselves later on in runas_setup.  Set the gid after
+         initgroups/setgroups is called, since on Mac OS X it seems to
+         change the egid.
+
+2009-05-17 18:19  millert
+
+       * LICENSE, Makefile.in, config.h.in, match.c, nonunix.h, sudo.c,
+         vasgroups.c: Initial bits of non-unix group support using Quest
+         Authentication Services
+
+2009-05-17 16:52  millert
+
+       * toke.c, toke.l: Accept %:foo as a non-Unix group
+
+2009-05-17 16:22  millert
+
+       * toke.c, toke.l: Allow user/group to be double quoted in the case
+         of non-Unix groups which contain spaces.
+
+2009-05-11 12:47  millert
+
+       * match.c: Don't allow the user to specify the default runas user
+         if their sudoers entry only allows them to run as a group.
+
+2009-05-10 07:59  millert
+
+       * sudo.c: Must call audit_success before we change uids.
+
+2009-05-10 07:52  millert
+
+       * logging.c, set_perms.c, sudo.h, testsudoers.c: Add option for
+         set_perm to not exit on failure and use this in the logging
+         routines.
+
+2009-05-10 07:33  millert
+
+       * parse.c: In -l mode, if the user is only allowed to run as a
+         group, display the user's name, not root's before the allowed
+         group.
+
+2009-05-09 21:00  millert
+
+       * sudo.c: Fix -g mode, broken by rev 1.503 which had the side
+         effect of setting the runas user to root unilaterally.
+
+2009-05-08 16:19  millert
+
+       * fileops.c: When unlocking a file with fcntl, use F_SETLK, not
+         F_SETLKW.
+
+2009-05-08 13:07  millert
+
+       * pwutil.c: Only cache by the method we fetched for pwd and grp
+         lookups.  Previously we cached both by namd and id but this can
+         cause problems for entries that share the same id.  Also add more
+         info in the error message in case the insert fails (which should
+         now be impossible).
+
+2009-04-30 15:04  millert
+
+       * sudoers.pod: Add a clarification from Nick Sieger
+
+2009-04-25 12:49  millert
+
+       * env.c: Inline the setting of the environment string.
+
+2009-04-24 14:53  millert
+
+       * env.c: setenv(3) in Linux treats a NUL value as the empty string
+         setenv(3) in BSD doesn't return an error if the name has '=' in
+         it, it just treats the '=' as end of string.
+
+2009-04-22 16:32  millert
+
+       * toke.c, toke.l: Not all systems have d_namlen
+
+2009-04-20 13:53  millert
+
+       * sudoers.pod: Fix up some pod2html issues.
+
+2009-04-19 14:09  millert
+
+       * interfaces.c: Check for NULL ifa_addr and ifa_netmask.  Adapted
+         from a diff from Quest Software.
+
+2009-04-19 09:01  millert
+
+       * sudoers.pod: Ignore files ending in '~' in sudo.d (emacs backup
+         files)
+
+2009-04-19 08:56  millert
+
+       * toke.c, toke.l: Ignore files ending in '~' in sudo.d (emacs
+         backup files)
+
+2009-04-18 19:37  millert
+
+       * sudoers.cat, sudoers.man.in, sudoers.pod, toke.c, toke.l: For
+         #includedir, ignore any file containing a dot
+
+2009-04-18 19:25  millert
+
+       * Makefile.in, version.h: Bump version
+
+2009-04-18 19:25  millert
+
+       * gram.c, gram.y, parse.c, parse.h, sudo.c, sudo.h, sudoers.cat,
+         sudoers.man.in, sudoers.pod, testsudoers.c, toke.c, toke.l,
+         visudo.c: Implement #includedir directive.  Files in an
+         includedir are not edited by visudo unless they contain a syntax
+         error.
+
+2009-04-18 12:06  millert
+
+       * ChangeLog: sync
+
+2009-04-18 10:27  millert
+
+       * WHATSNEW: Forgot umask_override
+
+2009-04-18 09:25  millert
+
+       * ChangeLog, TODO: sync
+
+2009-04-16 08:22  millert
+
+       * visudo.c: Rewind stream if we fdopen sudoers since it may not be
+         at the beginning.  Set the keepopen flag on already-open files
+         too so the lexer doesn't close them out from under us.
+
+2009-04-16 08:18  millert
+
+       * visudo.c: Print the proper file name when there is a parse error
+         in an include file.
+
+2009-04-11 07:45  millert
+
+       * WHATSNEW: Sync
+
+2009-04-10 16:59  millert
+
+       * configure, configure.in: Fix a warning when --without-ldap is
+         specified.
+
+2009-04-05 12:25  millert
+
+       * alias.c, parse.h, visudo.c: Store aliases that we remove during
+         check_aliases in a freelist and free them at the end so we don't
+         leak memory.
+
+2009-03-28 09:30  millert
+
+       * visudo.c: Check aliases in -c mode too.
+
+2009-03-28 09:09  millert
+
+       * alias.c, parse.h, visudo.c: Make alias_remove return the alias
+         struct instead of freeing it directly.  Fixes a use after free in
+         alias_remove_recursive, the only consumer.
+
+2009-03-28 09:07  millert
+
+       * alias.c, match.c, parse.c, parse.h, visudo.c: Rename find_alias
+         -> alias_find for consistency.
+
+2009-03-27 19:29  millert
+
+       * visudo.c: When checking for unused aliases, recurse if the alias
+         points to another alias.
+
+2009-03-16 12:11  millert
+
+       * ldap.c: Back out rev 1.105 for now.  Real ldapux_client.conf
+         support will be done later after some refactoring.
+
+2009-03-14 12:02  millert
+
+       * ldap.c: Treat ldap_hostport the same as "host" for ldapux.
+
+2009-03-13 21:04  millert
+
+       * configure, configure.in: Only check for
+         ldap_sasl_interactive_bind_s if we can find sasl.h.  Fixes
+         compilation with ldapux.
+
+2009-03-11 20:03  millert
+
+       * fileops.c: fix char subscript
+
+2009-03-11 19:19  millert
+
+       * Makefile.in: remove errant carriage returns
+
+2009-03-11 19:01  millert
+
+       * audit.c, env.c: fix K&R compilation
+
+2009-03-11 12:12  millert
+
+       * sudo.man.in, sudo.cat, sudoers.cat, sudoers.ldap.cat,
+         sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+         regen
+
+2009-03-10 17:34  millert
+
+       * config.h.in: Add missing HAVE_BSM_AUDIT
+
+2009-03-10 17:21  millert
+
+       * WHATSNEW: Add 1.7.1 features
+
+2009-03-10 17:10  millert
+
+       * INSTALL: Mention --with-netsvc
+
+2009-03-10 17:08  millert
+
+       * sudoers.ldap.pod: Document netsvc.conf support
+
+2009-03-10 16:44  millert
+
+       * configure, configure.in, pathnames.h.in, sudo.c, sudo_nss.c,
+         sudo_nss.h: Add support for AIX netsvc.conf (like nsswitch.conf).
+
+2009-03-08 16:57  millert
+
+       * configure, config.h.in, configure.in, env.c: Add
+         --enable-env-debug flag to enable environment sanity checks.
+
+2009-03-08 11:51  millert
+
+       * sudoers.ldap.pod, sudoers.pod: Work around some pod2html issue.
+
+2009-03-07 17:10  millert
+
+       * env.c: Only sync environ for putenv, setenv, and unsetenv.  We
+         need to make sure that sudo_putenv and sudo_setenv only modify
+         env.envp, not environ.
+
+2009-03-02 14:19  millert
+
+       * env.c: Really fix UNSETENV_VOID
+
+2009-03-02 14:18  millert
+
+       * env.c: Fix unsetenv when UNSETENV_VOID
+
+2009-03-02 08:00  millert
+
+       * aclocal.m4, configure: Fix SUDO_FUNC_PUTENV_CONST
+
+2009-03-02 07:36  millert
+
+       * ldap.c: tivoli-based ldap does not have ldapssl_err2string
+
+2009-03-02 07:30  millert
+
+       * configure: regen
+
+2009-03-01 16:20  millert
+
+       * config.h.in, configure, configure.in, ldap.c: Add support for
+         Tivoli-based LDAP start TLS as seen in AIX.  Untested.
+
+2009-03-01 08:52  millert
+
+       * env.c: Add sanity checks for setenv/unsetenv
+
+2009-02-28 20:17  millert
+
+       * Makefile.in: Include bsm_audit.h in the tarball
+
+2009-02-28 20:00  millert
+
+       * Makefile.in, version.h: bump version for sudo 1.7.1
+
+2009-02-28 19:58  millert
+
+       * aclocal.m4, config.h.in, configure, configure.in, env.c, ldap.c,
+         sudo.h, auth/aix_auth.c: Replace sudo_setenv/sudo_unsetenv with
+         calls to setenv/unsetenv and provide our own
+         setenv/unsetenv/putenv that operates on own env pointer.  Make
+         sync_env() inline in setenv/unsetenv/putenv functions.
+
+2009-02-25 07:33  millert
+
+       * sudo.c: Make "sudoedit -h" work as expected
+
+2009-02-25 07:21  millert
+
+       * auth/pam.c: Make sure def_prompt is always defined.  This is a
+         workaround for pam configs that prompt for a password in the
+         session but don't have an auth line.  A better fix is to expand
+         the sudo prompt earlier and set def_prompt to that when
+         initializing.
+
+2009-02-25 06:17  millert
+
+       * sudo.pod: Mention that the helper for -A may be graphical.
+
+2009-02-25 06:16  millert
+
+       * TROUBLESHOOTING: Document what happens if there is no tty.
+
+2009-02-25 06:05  millert
+
+       * sudo.c: cosmetic changes
+
+2009-02-25 05:47  millert
+
+       * term.c: Fix term_restore
+
+2009-02-24 20:23  millert
+
+       * sudo.c: Fix "sudo -k" with no other args
+
+2009-02-24 08:04  millert
+
+       * check.c, sudo.c, sudo.pod, sudo_usage.h.in: Allow the -k flag to
+         be specified in conjunction with a command or another option that
+         may require authentication.
+
+2009-02-23 09:18  millert
+
+       * configure, configure.in: Remove unneeded AC_CANONICAL_TARGET;
+         from Diego E. 'Flameeyes'
+
+2009-02-23 09:15  millert
+
+       * Makefile.in: Parallel make fix.  From Diego E. 'Flameeyes'
+
+2009-02-21 17:03  millert
+
+       * def_data.c, def_data.h, def_data.in, sudo.c, sudoers.pod:
+         Implement umask_override
+
+2009-02-21 16:51  millert
+
+       * toke.c: regen
+
+2009-02-21 16:49  millert
+
+       * sudoers.pod, toke.l, visudo.c: Implement %h escape in sudoers
+         include filenames.
+
+2009-02-21 08:43  millert
+
+       * audit.c: Need to include compat.h
+
+2009-02-21 08:37  millert
+
+       * Makefile.in, audit.c, bsm_audit.c, bsm_audit.h, logging.h,
+         sudo.c: Make audit_success and audit_failure generic functions in
+         preparation for integrating linux audit support.
+
+2009-02-21 08:06  millert
+
+       * term.c: remove duplicate include
+
+2009-02-20 16:13  millert
+
+       * bsm_audit.c: Add missing include
+
+2009-02-20 15:55  millert
+
+       * sudo.c: May need to update the runas user after parsing
+         command-based defaults.
+
+2009-02-18 10:53  millert
+
+       * glob.c: Add missing pair of braces introduced with character
+         class support.
+
+2009-02-15 15:53  millert
+
+       * def_data.c, def_data.h, def_data.in, sudoers.pod, tgetpass.c:
+         Rename pwstars to pwfeedback
+
+2009-02-10 20:25  millert
+
+       * bsm_audit.c, bsm_audit.h: Add const to make MacOS happy.
+
+2009-02-10 20:18  millert
+
+       * Makefile.in, bsm_audit.c, bsm_audit.h, configure, configure.in,
+         sudo.c, auth/sudo_auth.c: Add bsm audit support from Christian
+         S.J. Peron
+
+2009-02-10 19:58  millert
+
+       * term.c: This is new code, no DARPA notice.
+
+2009-02-10 14:04  millert
+
+       * def_data.c, def_data.h, def_data.in, match.c, sudoers.pod: Rename
+         simple_glob -> fast_glob
+
+2009-02-10 09:39  millert
+
+       * match.c: g/c unused var
+
+2009-02-10 08:09  millert
+
+       * def_data.c, def_data.h, def_data.in, match.c, sudoers.pod: Add
+         simple_glob option to use fnmatch() instead of glob().  This is
+         useful when you need to specify patterns that reference network
+         file systems.
+
+2009-02-10 07:58  millert
+
+       * tgetpass.c: add term_* proto
+
+2009-02-10 07:51  millert
+
+       * sudoers.pod: mention glob()
+
+2009-02-09 07:59  millert
+
+       * tgetpass.c: Delete any pwstars we wrote after the user hits
+         return.  That way there is no record on screen as to the user's
+         password length.
+
+2009-02-08 10:27  millert
+
+       * term.c: Move terminal setting bits from tgetpass.c to term.c
+
+2009-02-07 19:50  millert
+
+       * Makefile.in, def_data.c, def_data.h, def_data.in, sudoers.pod,
+         tgetpass.c: Add pwstars sudoers option that causes sudo to print
+         a star every time the user presses a key.
+
+2009-02-03 10:10  millert
+
+       * Makefile.in: Fix up F<> brokenness for visudo.man.in and
+         sudoers.ldap.man.in.
+
+2009-01-27 11:54  millert
+
+       * ldap.c: For ldap_search_ext_s() the sizelimit param should be 0,
+         not -1, to indicate no limit.  From Mark Janssen.
+
+2009-01-17 17:36  millert
+
+       * toke.c, toke.l: Comments that begin with #- should not be parsed
+         as uids.
+
+2009-01-08 19:13  millert
+
+       * sudo.c: Do not try to set the close on exec flag if we didn't
+         actually open sudoers.
+
+2008-12-19 12:40  millert
+
+       * ChangeLog: regen
+
 2008-12-14 17:40  millert
 
        * TODO: sync
 2004-10-01 10:58  millert
 
        * sample.pam, sample.sudoers, sample.syslog.conf, sudoers: Add
-         $Sudo: ChangeLog,v 1.19 2008/12/19 17:40:39 millert Exp $ tags.
+         $Sudo: ChangeLog,v 1.22 2009/07/12 01:12:29 millert Exp $ tags.
 
 2004-10-01 10:47  millert
 
diff --git a/INSTALL b/INSTALL
index 2ffb8f214b1580574e77781c92541a0641047b38..b58852b98761763a8cce00c5855463a4a6525e5d 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -195,6 +195,11 @@ Special features/options:
        If nsswitch is disabled but LDAP is enabled, sudo will check
        LDAP first, then the sudoers file.
 
+  --with-netsvc[=filename]
+        Path to netsvc.conf or "no" to disable netsvc.conf support.
+        If specified, sudo uses this file instead of /etc/netsvc.conf
+        on AIX systems.
+
   --with-aixauth
        Enable support for the AIX 4.x general authentication function.
        This will use the authentication scheme specified for the user
@@ -330,6 +335,16 @@ Special features/options:
        Enable support for role based access control (RBAC) on
        systems that support SELinux.
 
+  --with-libvas=[NAME]
+        Enable non-Unix group support using Quest Authentication
+        Services.  If NAME is specified, it should be the name of
+       the shared library providing QAS support (libvas.so by default).
+
+  --with-libvas-rpath=[PATH]
+       The path to search when loading libvas.so (or an alternate
+       name as specified by --with-libvas).  This option only has
+       an effect when --with-libvas is specified.
+
 The following options are also configurable at runtime:
 
   --with-long-otp-prompt
diff --git a/LICENSE b/LICENSE
index 786b7a096eee5a953eaf9e9ad528c38d567fbce7..0632e0bf1781850b6dba69c29b827879a1418244 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 Sudo is distributed under the following ISC-style license:
 
-   Copyright (c) 1994-1996, 1998-2008
+   Copyright (c) 1994-1996, 1998-2009
         Todd C. Miller <Todd.Miller@courtesan.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -48,3 +48,31 @@ bear the following UCB license:
    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.
+
+nonunix.h and vasgroups.c bear the following license:
+
+   Copyright (c) 2006 Quest Software, Inc.  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 Quest Software, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. 
index c097af7eee1be95871e24e93f5373c6ad1bce6c1..c7fc8d91ef7c8d5d4051399bdd07d7e517696057 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1996, 1998-2005, 2007-2008
+# Copyright (c) 1996, 1998-2005, 2007-2009
 #      Todd C. Miller <Todd.Miller@courtesan.com>
 #
 # Permission to use, copy, modify, and distribute this software for any
@@ -21,7 +21,7 @@
 #
 # @configure_input@
 #
-# $Sudo: Makefile.in,v 1.326 2008/12/03 20:40:47 millert Exp $
+# $Sudo: Makefile.in,v 1.340 2009/06/15 21:18:53 millert Exp $
 #
 
 #### Start of system configuration section. ####
@@ -33,7 +33,7 @@ top_builddir = .
 
 # Compiler & tools to use
 CC = @CC@
-LEX = flex
+FLEX = @FLEX@
 YACC = @YACC@
 NROFF = nroff -Tascii
 LIBTOOL = @LIBTOOL@
@@ -102,36 +102,37 @@ SHELL = /bin/sh
 
 PROGS = @PROGS@
 
-SRCS = aix.c alias.c alloc.c check.c closefrom.c def_data.c defaults.c env.c \
-       error.c fileops.c find_path.c fnmatch.c getcwd.c getprogname.c \
-       getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y interfaces.c \
-       isblank.c lbuf.c ldap.c list.c logging.c match.c mkstemp.c memrchr.c \
-       parse.c pwutil.c  set_perms.c sigaction.c snprintf.c strcasecmp.c \
-       strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c sudo_edit.c \
-       sudo_nss.c testsudoers.c tgetpass.c toke.c toke.l tsgetgrpw.c utimes.c \
-       visudo.c zero_bytes.c redblack.c selinux.c sesh.c $(AUTH_SRCS)
+SRCS = aix.c alias.c alloc.c audit.c bsm_audit.c check.c closefrom.c \
+       def_data.c defaults.c env.c error.c fileops.c find_path.c fnmatch.c \
+       getcwd.c getprogname.c getspwuid.c gettime.c glob.c goodpath.c gram.c \
+       gram.y interfaces.c isblank.c lbuf.c ldap.c list.c logging.c match.c \
+       mkstemp.c memrchr.c parse.c pwutil.c  set_perms.c sigaction.c \
+       snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c \
+       sudo_noexec.c sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c \
+       toke.c toke.l tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c \
+       redblack.c selinux.c sesh.c $(AUTH_SRCS)
 
 AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
            auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
            auth/secureware.c auth/securid.c auth/securid5.c auth/sia.c \
            auth/sudo_auth.c
 
-HDRS = compat.h def_data.h defaults.h error.h ins_2001.h ins_classic.h \
-       ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h list.h \
-       logging.h parse.h sudo.h sudo_nss.h gram.h version.h auth/sudo_auth.h \
-       emul/charclass.h emul/fnmatch.h emul/glob.h emul/timespec.h \
-       emul/utime.h redblack.h
+HDRS = bsm_audit.h compat.h def_data.h defaults.h error.h ins_2001.h \
+       ins_classic.h ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h \
+       list.h logging.h nonunix.h redblack.h parse.h sudo.h sudo_nss.h gram.h \
+       auth/sudo_auth.h emul/charclass.h emul/fnmatch.h emul/glob.h \
+       emul/timespec.h emul/utime.h
 
 AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
 
 # Note: gram.o must come first here
 COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o list.o match.o \
-             toke.o redblack.o zero_bytes.o
+             toke.o redblack.o zero_bytes.o @NONUNIX_GROUPS_IMPL@
 
-SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ check.o env.o \
+SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ audit.o check.o env.o \
            getspwuid.o gettime.o goodpath.o fileops.o find_path.o \
            interfaces.o lbuf.o logging.o parse.o pwutil.o set_perms.o \
-           sudo.o sudo_edit.o sudo_nss.o tgetpass.o
+           sudo.o sudo_edit.o sudo_nss.o term.o tgetpass.o
 
 VISUDO_OBJS = $(COMMON_OBJS) visudo.o fileops.o gettime.o goodpath.o \
              find_path.o pwutil.o
@@ -140,7 +141,7 @@ TEST_OBJS = $(COMMON_OBJS) interfaces.o testsudoers.o tsgetgrpw.o tspwutil.o
 
 LIB_OBJS = @LIBOBJS@
 
-VERSION = 1.7.0
+VERSION = @PACKAGE_VERSION@
 
 DISTFILES = $(SRCS) $(HDRS) ChangeLog HISTORY INSTALL INSTALL.configure \
             LICENSE Makefile.in PORTING README README.LDAP TROUBLESHOOTING \
@@ -181,8 +182,8 @@ all: $(PROGS)
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $<
 
 .man.cat:
-       @rm -f $(srcdir)/$@
-       sed '1s/^/.if n .ll 78n/' $< | $(NROFF) -man > $(srcdir)/$@
+       @rm -f $@
+       sed '1s/^/.if n .ll 78n/' $< | $(NROFF) -man > $@
 
 sudo: $(SUDO_OBJS) $(LIB_OBJS)
        $(CC) -o $@ $(SUDO_OBJS) $(LIB_OBJS) $(SUDO_LDFLAGS) $(SUDO_LIBS)
@@ -211,7 +212,7 @@ $(devdir)/gram.c: $(srcdir)/gram.y
 
 # Uncomment the lines before -@true if you intend to modify toke.l
 $(devdir)/toke.c: $(srcdir)/toke.l
-@DEV@  $(LEX) $(srcdir)/toke.l
+@DEV@  $(FLEX) $(srcdir)/toke.l
 @DEV@  mv -f lex.yy.c toke.c
        -@true
 
@@ -226,6 +227,10 @@ alias.o: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdi
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alias.c
 alloc.o: $(srcdir)/alloc.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alloc.c
+audit.o: $(srcdir)/audit.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/audit.c
+bsm_audit.o: $(srcdir)/bsm_audit.c $(SUDODEP) bsm_audit.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/bsm_audit.c
 check.o: $(srcdir)/check.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/check.c
 closefrom.o: $(srcdir)/closefrom.c config.h
@@ -296,7 +301,7 @@ strlcpy.o: $(srcdir)/strlcpy.c $(srcdir)/compat.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/strlcpy.c
 selinux.o: $(srcdir)/selinux.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/selinux.c
-sudo.o: $(srcdir)/sudo.c $(SUDODEP) sudo_usage.h $(srcdir)/interfaces.h $(srcdir)/version.h
+sudo.o: $(srcdir)/sudo.c $(SUDODEP) sudo_usage.h $(srcdir)/interfaces.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo.c
 sudo_edit.o: $(srcdir)/sudo_edit.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_edit.c
@@ -304,6 +309,8 @@ sudo_noexec.o: $(srcdir)/sudo_noexec.c $(srcdir)/compat.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_noexec.c
 sudo_nss.o: $(srcdir)/sudo_nss.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_nss.c
+term.o: $(srcdir)/term.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/term.c
 testsudoers.o: $(srcdir)/testsudoers.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/testsudoers.c
 tgetpass.o: $(srcdir)/tgetpass.c $(SUDODEP)
@@ -314,7 +321,9 @@ tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tsgetgrpw.c
 utimes.o: $(srcdir)/utimes.c $(srcdir)/compat.h $(srcdir)/emul/utime.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/utimes.c
-visudo.o: $(srcdir)/visudo.c $(SUDODEP) $(srcdir)/version.h $(devdir)/gram.h
+vasgroups.o: $(srcdir)/vasgroups.c $(srcdir)/nonunix.h $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/vasgroups.c
+visudo.o: $(srcdir)/visudo.c $(SUDODEP) $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/visudo.c
 zero_bytes.o: $(srcdir)/zero_bytes.c $(srcdir)/compat.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/zero_bytes.c
@@ -365,7 +374,7 @@ sudo.cat: sudo.man
 
 visudo.man.in: $(srcdir)/visudo.pod
        @rm -f $(srcdir)/$@
-       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' visudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' visudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@ )
 
 visudo.man: visudo.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
@@ -383,7 +392,7 @@ sudoers.cat: sudoers.man
 
 sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.pod
        @rm -f $(srcdir)/$@
-       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudoers.ldap.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.ldap.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudoers.ldap.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.ldap.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@ )
 
 sudoers.ldap.man:: sudoers.ldap.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
@@ -407,22 +416,22 @@ install-dirs:
            $(DESTDIR)$(mandirsu) $(DESTDIR)$(mandirform) \
            $(DESTDIR)$(noexecdir)
 
-install-binaries: $(PROGS)
+install-binaries: install-dirs $(PROGS)
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 4111 -s sudo $(DESTDIR)$(sudodir)/sudo
        rm -f $(DESTDIR)$(sudodir)/sudoedit
        ln $(DESTDIR)$(sudodir)/sudo $(DESTDIR)$(sudodir)/sudoedit
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s visudo $(DESTDIR)$(visudodir)/visudo
 @SELINUX@      $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s sesh $(DESTDIR)$(libexecdir)/sesh
 
-install-noexec: sudo_noexec.la
+install-noexec: install-dirs sudo_noexec.la
        test -f .libs/$(noexecfile) && $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0755 .libs/$(noexecfile) $(DESTDIR)$(noexecdir)
 
-install-sudoers:
+install-sudoers: install-dirs
        test -f $(DESTDIR)$(sudoersdir)/sudoers || \
            $(INSTALL) -O $(sudoers_uid) -G $(sudoers_gid) -M $(sudoers_mode) \
                $(srcdir)/sudoers $(DESTDIR)$(sudoersdir)/sudoers
 
-install-man:
+install-man: install-dirs
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(mansectsu)
        @rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)
        ln $(DESTDIR)$(mandirsu)/sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)
diff --git a/README b/README
index 301ca5517586737da92f08ca5390394dffb15f15..bf7522fb7e967ca03821d1e1e30aab08a11b2906 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This is Sudo version 1.7.0
+This is Sudo version 1.7.2
 
 The sudo philosophy
 ===================
index a90b5eb9ff67c70be25f0b34487e13972411d474..8ca20805808201dea810c452b058b2031bb59c13 100644 (file)
@@ -177,6 +177,14 @@ A) The default user sudo tries to run things as is always root, even if
     Defaults:bob       runas_default=oracle
    would achieve the desired result ofr the preceding sudoers fragment.
 
+Q) When I try to run sudo via ssh, I get the error:
+    sudo: no tty present and no askpass program specified
+A) ssh does not allocate a tty by default when running a remote command.
+   Without a tty, sudo cannot disable echo when prompting for a password.
+   You can use ssh's "-t" option to force it to allocate a tty.
+   Alternately, if you do not mind your password being echoed to the
+   screen, you can use the "visiblepw" sudoers option to allow this.
+
 Q) How do you pronounce `sudo'?
 A) The official pronunciation is soo-doo (for su "do").  However, an
    alternate pronunciation, a homophone of "pseudo", is also common.
index 2d36f065289dbe1ddad30f66876413ac19df6c91..657fd29a5b8bbb042c5cb271710d4e2ed97e1db8 100644 (file)
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,3 +1,73 @@
+What's new in Sudo 1.7.2?
+
+ * A new #includedir directive is available in sudoers.  This can be
+   used to implement an /etc/sudo.d directory.  Files in an includedir
+   are not edited by visudo unless they contain a syntax error.
+
+ * The -g option did not work properly when only setting the group
+   (and not the user).  Also, in -l mode the wrong user was displayed
+   for sudoers entries where only the group was allowed to be set.
+
+ * Fixed a problem with the alias checking in visudo which
+   could prevent visudo from exiting.
+
+ * Sudo will now correctly parse the shell-style /etc/environment
+   file format used by pam_env on Linux.
+
+ * When doing password and group database lookups, sudo will only
+   cache an entry by name or by id, depending on how the entry was
+   looked up.  Previously, sudo would cache by both name and id
+   from a single lookup, but this breaks sites that have multiple
+   password or group database names that map to the same uid or
+   gid.
+
+ * User and group names in sudoers may now be enclosed in double
+   quotes to avoid having to escape special characters.
+
+ * BSM audit fixes when changing to a non-root uid.
+
+ * Experimental non-Unix group support.  Currently only works with
+   Quest Authorization Services and allows Active Directory groups
+   fixes for Minix-3.
+
+ * For Netscape/Mozilla-derived LDAP SDKs the certificate and key
+   paths may be specified as a directory or a file.  However, version
+   5.0 of the SDK only appears to support using a directory (despite
+   documentation to the contrary).  If SSL client initialization
+   fails and the certificate or key paths look like they could be
+   default file name, strip off the last path element and try again.
+
+ * A setenv() compatibility fix for Linux systems, where a NULL
+   value is treated the same as an empty string and the variable
+   name is checked against the NULL pointer.
+
+What's new in Sudo 1.7.1?
+
+ * A new Defaults option "pwfeedback" will cause sudo to provide visual
+   feedback when the user is entering a password.
+
+ * A new Defaults option "fast_glob" will cause sudo to use the fnmatch()
+   function for file name globbing instead of glob().  When this option
+   is enabled, sudo will not check the file system when expanding wildcards.
+   This is faster but a side effect is that relative paths with wildcard
+   will no longer work.
+
+ * New BSM audit support for systems that support it such as FreeBSD
+   and Mac OS X.
+
+ * The file name specified with the #include directive may now include
+   a %h escape which is expanded to the short form of hostname.
+
+ * The -k flag may now be specified along with a command, causing the
+   user's timestamp file to be ignored.
+
+ * New support for Tivoli-based LDAP START_TLS, present in AIX.
+
+ * New support for /etc/netsvc.conf on AIX.
+
+ * The unused alias checks in visudo now handle the case of an alias
+   referring to another alias.
+
 What's new in Sudo 1.7.0?
 
  * Rewritten parser that converts sudoers into a set of data structures.
@@ -77,3 +147,7 @@ What's new in Sudo 1.7.0?
 
  * visudo will now check the sudoers file owner and mode in -c (check)
    mode when the -s (strict) flag is specified.
+
+ * A new Defaults option "umask_override" will cause sudo to set the
+   umask specified in sudoers even if it is more permissive than the
+   invoking user's umask.
index 13089f0901268a802c7fd02a01af47ba7e052c23..1a6d9904931fa66f450f84d43fa17b448c99ec50 100644 (file)
@@ -1,6 +1,7 @@
 dnl Local m4 macros for autoconf (used by sudo)
 dnl
-dnl Copyright (c) 1994-1996,1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl Copyright (c) 1994-1996, 1998-2005, 2007-2009
+dnl    Todd C. Miller <Todd.Miller@courtesan.com>
 dnl
 dnl XXX - should cache values in all cases!!!
 dnl
@@ -219,7 +220,7 @@ dnl
 dnl check for isblank(3)
 dnl
 AC_DEFUN([SUDO_FUNC_ISBLANK],
-  [AC_CACHE_CHECK([for isblank], sudo_cv_func_isblank,
+  [AC_CACHE_CHECK([for isblank], [sudo_cv_func_isblank],
     [AC_TRY_LINK([#include <ctype.h>], [return (isblank('a'));],
     sudo_cv_func_isblank=yes, sudo_cv_func_isblank=no)])
 ] [
@@ -230,6 +231,43 @@ AC_DEFUN([SUDO_FUNC_ISBLANK],
   fi
 ])
 
+dnl
+dnl check unsetenv() return value
+dnl
+AC_DEFUN([SUDO_FUNC_UNSETENV_VOID],
+  [AC_CACHE_CHECK([whether unsetenv returns void], [sudo_cv_func_unsetenv_void],
+    [AC_RUN_IFELSE([AC_LANG_PROGRAM(
+      [AC_INCLUDES_DEFAULT
+        int unsetenv();
+      ], [
+        [return unsetenv("FOO") != 0;]
+      ])
+    ],
+    [sudo_cv_func_unsetenv_void=no],
+    [sudo_cv_func_unsetenv_void=yes],
+    [sudo_cv_func_unsetenv_void=yes])])
+    if test $sudo_cv_func_unsetenv_void = yes; then
+      AC_DEFINE(UNSETENV_VOID, 1,
+        [Define to 1 if the `unsetenv' function returns void instead of `int'.])
+    fi
+  ])
+
+dnl
+dnl check putenv() argument for const
+dnl
+AC_DEFUN([SUDO_FUNC_PUTENV_CONST],
+[AC_CACHE_CHECK([whether putenv has a const argument],
+sudo_cv_func_putenv_const,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+int putenv(const char *string) {return 0;}], [])],
+    [sudo_cv_func_putenv_const=yes],
+    [sudo_cv_func_putenv_const=no])
+  ])
+  if test $sudo_cv_func_putenv_const = yes; then
+    AC_DEFINE(PUTENV_CONST, 1, [Define to 1 if the `putenv' has a const argument.])
+  fi
+])
+
 dnl
 dnl check for sa_len field in struct sockaddr
 dnl
diff --git a/alias.c b/alias.c
index 9a030690ed54f9769a033277d4b53e1d7f1b2c62..e8fec56c07e59dfda2b28f3ab6ffc3e261882022 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005m, 2007-2008
+ * Copyright (c) 2004-2005m, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -47,7 +47,7 @@
 #include <gram.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: alias.c,v 1.14 2008/11/18 13:29:58 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: alias.c,v 1.18 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 /*
@@ -56,17 +56,11 @@ __unused static const char rcsid[] = "$Sudo: alias.c,v 1.14 2008/11/18 13:29:58
 struct rbtree *aliases;
 unsigned int alias_seqno;
 
-/*
- * Local protoypes
- */
-static int   alias_compare     __P((const void *, const void *));
-static void  alias_free                __P((void *));
-
 /*
  * Comparison function for the red-black tree.
  * Aliases are sorted by name with the type used as a tie-breaker.
  */
-static int
+int
 alias_compare(v1, v2)
     const void *v1, *v2;
 {
@@ -88,7 +82,7 @@ alias_compare(v1, v2)
  * Returns a pointer to the alias structure or NULL if not found.
  */
 struct alias *
-find_alias(name, type)
+alias_find(name, type)
     char *name;
     int type;
 {
@@ -161,7 +155,7 @@ no_aliases()
 /*
  * Free memory used by an alias struct and its members.
  */
-static void
+void
 alias_free(v)
     void *v;
 {
@@ -185,9 +179,9 @@ alias_free(v)
 }
 
 /*
- * Find the named alias, delete it from the tree and recover its resources.
+ * Find the named alias, remove it from the tree and return it.
  */
-int
+struct alias *
 alias_remove(name, type)
     char *name;
     int type;
@@ -198,10 +192,9 @@ alias_remove(name, type)
     key.name = name;
     key.type = type;
     if ((node = rbfind(aliases, &key)) == NULL)
-       return(FALSE);
+       return(NULL);
     a = rbdelete(aliases, node);
-    alias_free(a);
-    return(TRUE);
+    return(a);
 }
 
 void
diff --git a/audit.c b/audit.c
new file mode 100644 (file)
index 0000000..59ea526
--- /dev/null
+++ b/audit.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "compat.h"
+#include "logging.h"
+
+#ifdef HAVE_BSM_AUDIT
+# include "bsm_audit.h"
+#endif
+
+void
+#ifdef __STDC__
+audit_success(char **exec_args)
+#else
+audit_success(exec_args)
+    const char **exec_args;
+#endif
+{
+#ifdef HAVE_BSM_AUDIT
+    bsm_audit_success(exec_args);
+#endif
+}
+
+void
+#ifdef __STDC__
+audit_failure(char **exec_args, char const *const fmt, ...)
+#else
+audit_failure(exec_args, fmt, va_alist)
+    const char **exec_args;
+    char const *const fmt;
+    va_dcl
+#endif
+{
+    va_list ap;
+
+#ifdef __STDC__
+    va_start(ap, fmt);
+#else
+    va_start(ap);
+#endif
+#ifdef HAVE_BSM_AUDIT
+    bsm_audit_failure(exec_args, fmt, ap);
+#endif
+    va_end(ap);
+}
index 14343efb0146005d49c2c1ae04d7180fc5ec7f5a..853ceb8b1acc9390886b044fe35d84a35ccf7a02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005, 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -47,7 +47,7 @@
 #include "sudo_auth.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: aix_auth.c,v 1.25 2008/11/09 14:13:13 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: aix_auth.c,v 1.27 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
 /*
@@ -82,7 +82,7 @@ aixauth_cleanup(pw, auth)
     sudo_auth *auth;
 {
     /* Unset AUTHSTATE as it may not be correct for the runas user. */
-    sudo_unsetenv("AUTHSTATE");
+    unsetenv("AUTHSTATE");
 
     return(AUTH_SUCCESS);
 }
index cefb6d55516c0c5358210efa96f9a7f0f9883bec..47820ba8a842a516c04f231883d54b02abd43daf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005, 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #endif
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: pam.c,v 1.66 2008/12/09 23:48:19 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: pam.c,v 1.68 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
 static int sudo_conv __P((int, PAM_CONST struct pam_message **,
                          struct pam_response **, void *));
-static char *def_prompt;
+static char *def_prompt = "Password:";
 static int gotintr;
 
 #ifndef PAM_DATA_SILENT
index 509f26ff5b00a746259a877b143221b65fd6e5d5..fa1419f28c56e4210de1324e5e1bcf47c7fecfd2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005, 2008-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -53,7 +53,7 @@
 #include "insults.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: sudo_auth.c,v 1.38 2008/11/07 17:45:52 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: sudo_auth.c,v 1.40 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
 sudo_auth auth_switch[] = {
@@ -100,6 +100,9 @@ verify_user(pw, prompt)
     char *p;
     sudo_auth *auth;
     sigaction_t sa, osa;
+#ifdef HAVE_BSM_AUDIT
+    extern char **NewArgv;
+#endif
 
     /* Enable suspend during password entry. */
     sigemptyset(&sa.sa_mask);
@@ -108,11 +111,15 @@ verify_user(pw, prompt)
     (void) sigaction(SIGTSTP, &sa, &osa);
 
     /* Make sure we have at least one auth method. */
-    if (auth_switch[0].name == NULL)
+    if (auth_switch[0].name == NULL) {
+#ifdef HAVE_BSM_AUDIT
+       audit_failure(NewArgv, "no authentication methods");
+#endif
        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)
@@ -127,8 +134,12 @@ verify_user(pw, prompt)
            status = (auth->init)(pw, &prompt, auth);
            if (status == AUTH_FAILURE)
                CLR(auth->flags, FLAG_CONFIGURED);
-           else if (status == AUTH_FATAL)      /* XXX log */
+           else if (status == AUTH_FATAL) {    /* XXX log */
+#ifdef HAVE_BSM_AUDIT
+               audit_failure(NewArgv, "authentication failure");
+#endif
                exit(1);                /* assume error msg already printed */
+           }
 
            if (NEEDS_USER(auth))
                set_perms(PERM_ROOT);
@@ -145,8 +156,12 @@ verify_user(pw, prompt)
                status = (auth->setup)(pw, &prompt, auth);
                if (status == AUTH_FAILURE)
                    CLR(auth->flags, FLAG_CONFIGURED);
-               else if (status == AUTH_FATAL)  /* XXX log */
+               else if (status == AUTH_FATAL) {/* XXX log */
+#ifdef HAVE_BSM_AUDIT
+                   audit_failure(NewArgv, "authentication failure");
+#endif
                    exit(1);            /* assume error msg already printed */
+               }
 
                if (NEEDS_USER(auth))
                    set_perms(PERM_ROOT);
@@ -193,8 +208,12 @@ cleanup:
                set_perms(PERM_USER);
 
            status = (auth->cleanup)(pw, auth);
-           if (status == AUTH_FATAL)   /* XXX log */
+           if (status == AUTH_FATAL) { /* XXX log */
+#ifdef HAVE_BSM_AUDIT
+               audit_failure(NewArgv, "authentication failure");
+#endif
                exit(1);                /* assume error msg already printed */
+           }
 
            if (NEEDS_USER(auth))
                set_perms(PERM_ROOT);
@@ -212,12 +231,18 @@ cleanup:
                    flags = 0;
                else
                    flags = NO_MAIL;
+#ifdef HAVE_BSM_AUDIT
+               audit_failure(NewArgv, "authentication failure");
+#endif
                log_error(flags, "%d incorrect password attempt%s",
                    def_passwd_tries - counter,
                    (def_passwd_tries - counter == 1) ? "" : "s");
            }
            /* FALLTHROUGH */
        case AUTH_FATAL:
+#ifdef HAVE_BSM_AUDIT
+           audit_failure(NewArgv, "authentication failure");
+#endif
            exit(1);
     }
     /* NOTREACHED */
index ed1545f40e871187e1fc6d0184150b3b150d28e2..42ac49b167d1617021dbf56819baab15233f3cb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005, 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Sudo: sudo_auth.h,v 1.28 2008/12/02 17:30:39 millert Exp $
+ * $Sudo: sudo_auth.h,v 1.29 2009/05/25 12:02:42 millert Exp $
  */
 
 #ifndef SUDO_AUTH_H
diff --git a/bsm_audit.c b/bsm_audit.c
new file mode 100644 (file)
index 0000000..054d621
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2009 Christian S.J. Peron
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <errno.h>
+#include <unistd.h>
+
+void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__));
+
+static int
+audit_sudo_selected(int sf)
+{
+       auditinfo_addr_t ainfo_addr;
+       struct au_mask *mask;
+       auditinfo_t ainfo;
+       int rc, sorf;
+
+       if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
+               if (errno == ENOSYS) {
+                       if (getaudit(&ainfo) < 0)
+                               log_error(0, "getaudit: failed");
+                       mask = &ainfo.ai_mask;
+               } else
+                       log_error(0, "getaudit: failed");
+        } else
+               mask = &ainfo_addr.ai_mask;
+       sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
+       rc = au_preselect(AUE_sudo, mask, sorf, AU_PRS_REREAD);
+        return (rc);
+}
+
+void
+bsm_audit_success(char **exec_args)
+{
+       auditinfo_addr_t ainfo_addr;
+       auditinfo_t ainfo;
+       token_t *tok;
+       au_id_t auid;
+       long au_cond;
+       int aufd;
+       pid_t pid;
+
+       pid = getpid();
+       /*
+        * If we are not auditing, don't cut an audit record; just return.
+        */
+       if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
+               if (errno == ENOSYS)
+                       return;
+               log_error(0, "Could not determine audit condition");
+       }
+       if (au_cond == AUC_NOAUDIT)
+               return;
+       /*
+        * Check to see if the preselection masks are interested in seeing
+        * this event.
+        */
+       if (!audit_sudo_selected(0))
+               return;
+       if (getauid(&auid) < 0)
+               log_error(0, "getauid failed");
+       if ((aufd = au_open()) == -1)
+               log_error(0, "au_open: failed");
+       if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
+               tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
+                   getuid(), pid, pid, &ainfo_addr.ai_termid);
+       } else if (errno == ENOSYS) {
+               /*
+                * NB: We should probably watch out for ERANGE here.
+                */
+               if (getaudit(&ainfo) < 0)
+                       log_error(0, "getaudit: failed");
+               tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
+                   getuid(), pid, pid, &ainfo.ai_termid);
+       } else
+               log_error(0, "getaudit: failed");
+       if (tok == NULL)
+               log_error(0, "au_to_subject: failed");
+       au_write(aufd, tok);
+       tok = au_to_exec_args(exec_args);
+       if (tok == NULL)
+               log_error(0, "au_to_exec_args: failed");
+       au_write(aufd, tok);
+       tok = au_to_return32(0, 0);
+       if (tok == NULL)
+               log_error(0, "au_to_return32: failed");
+       au_write(aufd, tok);
+       if (au_close(aufd, 1, AUE_sudo) == -1)
+               log_error(0, "unable to commit audit record");
+}
+
+void
+bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
+{
+       auditinfo_addr_t ainfo_addr;
+       auditinfo_t ainfo;
+       char text[256];
+       token_t *tok;
+       long au_cond;
+       au_id_t auid;
+       pid_t pid;
+       int aufd;
+
+       pid = getpid();
+       /*
+        * If we are not auditing, don't cut an audit record; just return.
+        */
+       if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+               if (errno == ENOSYS)
+                       return;
+               log_error(0, "Could not determine audit condition");
+       }
+       if (au_cond == AUC_NOAUDIT)
+               return;
+       if (!audit_sudo_selected(1))
+               return;
+       if (getauid(&auid) < 0)
+               log_error(0, "getauid: failed");
+       if ((aufd = au_open()) == -1)
+               log_error(0, "au_open: failed");
+       if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { 
+               tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
+                   getuid(), pid, pid, &ainfo_addr.ai_termid);
+       } else if (errno == ENOSYS) {
+               if (getaudit(&ainfo) < 0) 
+                       log_error(0, "getaudit: failed");
+               tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
+                   getuid(), pid, pid, &ainfo.ai_termid);
+       } else
+               log_error(0, "getaudit: failed");
+       if (tok == NULL)
+               log_error(0, "au_to_subject: failed");
+       au_write(aufd, tok);
+       tok = au_to_exec_args(exec_args);
+       if (tok == NULL)
+               log_error(0, "au_to_exec_args: failed");
+       au_write(aufd, tok);
+       (void) vsnprintf(text, sizeof(text), fmt, ap);
+       tok = au_to_text(text);
+       if (tok == NULL)
+               log_error(0, "au_to_text: failed");
+       au_write(aufd, tok);
+       tok = au_to_return32(EPERM, 1);
+       if (tok == NULL)
+               log_error(0, "au_to_return32: failed");
+       au_write(aufd, tok);
+       if (au_close(aufd, 1, AUE_sudo) == -1)
+               log_error(0, "unable to commit audit record");
+}
diff --git a/bsm_audit.h b/bsm_audit.h
new file mode 100644 (file)
index 0000000..6ccb79d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2009 Christian S.J. Peron
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SUDO_BSM_AUDIT_H
+#define        _SUDO_BSM_AUDIT_H
+
+void   bsm_audit_success(char **);
+void   bsm_audit_failure(char **, char const * const, va_list);
+
+#endif /* _SUDO_BSM_AUDIT_H */
diff --git a/check.c b/check.c
index fedc91640af8fc1b99b51c113c0a4ba5a825e22b..bdce34e23b7d719266399ebdd23552f151797325 100644 (file)
--- a/check.c
+++ b/check.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1993-1996,1998-2005, 2007-2008
+ * Copyright (c) 1993-1996,1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -59,7 +59,7 @@
 #include "sudo.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: check.c,v 1.245 2008/11/25 17:01:34 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: check.c,v 1.247 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 /* Status codes for timestamp_status() */
@@ -84,24 +84,29 @@ static void  update_timestamp       __P((char *, char *));
  * verify who he/she is.
  */
 void
-check_user(validated, interactive)
+check_user(validated, mode)
     int validated;
-    int interactive;
+    int mode;
 {
     char *timestampdir = NULL;
     char *timestampfile = NULL;
     char *prompt;
     int status;
 
-    if (user_uid == 0 || user_uid == runas_pw->pw_uid || user_is_exempt())
-       return;
+    if (mode & MODE_INVALIDATE) {
+       /* do not check or update timestamp */
+       status = TS_ERROR;
+    } else {
+       if (user_uid == 0 || user_uid == runas_pw->pw_uid || user_is_exempt())
+           return;
 
-    build_timestamp(&timestampdir, &timestampfile);
-    status = timestamp_status(timestampdir, timestampfile, user_name,
+       build_timestamp(&timestampdir, &timestampfile);
+       status = timestamp_status(timestampdir, timestampfile, user_name,
        TS_MAKE_DIRS);
+    }
     if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) {
        /* Bail out if we are non-interactive and a password is required */
-       if (!interactive)
+       if (ISSET(mode, MODE_NONINTERACTIVE))
            errorx(1, "sorry, a password is required to run %s", getprogname());
 
        /* If user specified -A, make sure we have an askpass helper. */
@@ -139,7 +144,6 @@ check_user(validated, interactive)
 
 /*
  * Standard sudo lecture.
- * TODO: allow the user to specify a file name instead.
  */
 static void
 lecture(status)
index 70de108a3b6bbc00b14906b00760f334134c62f5..18698f4f92bc34840a8cb75d9d1ce252b89c96c2 100644 (file)
@@ -32,6 +32,9 @@
 /* A colon-separated list of pathnames to be used as the editor for visudo. */
 #undef EDITOR
 
+/* Define to enable environment debugging. */
+#undef ENV_DEBUG
+
 /* Define to 1 if you want visudo to honor the EDITOR and VISUAL env
    variables. */
 #undef ENV_EDITOR
@@ -70,6 +73,9 @@
 /* Define to 1 if you use BSD authentication. */
 #undef HAVE_BSD_AUTH_H
 
+/* Define to 1 to enable BSM auditing. */
+#undef HAVE_BSM_AUDIT
+
 /* Define to 1 if you have the `closefrom' function. */
 #undef HAVE_CLOSEFROM
 
@@ -92,6 +98,9 @@
 /* Define to 1 if you have the `dispcrypt' function. */
 #undef HAVE_DISPCRYPT
 
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
 /* Define to 1 if your glob.h defines the GLOB_BRACE and GLOB_TILDE flags. */
 #undef HAVE_EXTENDED_GLOB
 
 /* Define to 1 if you have the `ldap_search_ext_s' function. */
 #undef HAVE_LDAP_SEARCH_EXT_S
 
+/* Define to 1 if you have the `ldap_ssl_client_init' function. */
+#undef HAVE_LDAP_SSL_CLIENT_INIT
+
 /* Define to 1 if you have the <ldap_ssl.h> header file. */
 #undef HAVE_LDAP_SSL_H
 
 /* Define to 1 if you have the `ldap_start_tls_s' function. */
 #undef HAVE_LDAP_START_TLS_S
 
+/* Define to 1 if you have the `ldap_start_tls_s_np' function. */
+#undef HAVE_LDAP_START_TLS_S_NP
+
 /* Define to 1 if you have the `ldap_str2dn' function. */
 #undef HAVE_LDAP_STR2DN
 
 /* Define to 1 to enable SELinux RBAC support. */
 #undef HAVE_SELINUX
 
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
 /* Define to 1 if you have the `seteuid' function. */
 #undef HAVE_SETEUID
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
 /* Define to 1 if you have the `utimes' function. */
 #undef HAVE_UTIMES
 
 /* The message given when a bad password is entered. */
 #undef INCORRECT_PASSWORD
 
+/* The name of libvas.so */
+#undef LIBVAS_SO
+
 /* The syslog facility sudo will use. */
 #undef LOGFAC
 
 /* Define to 1 if root should not be allowed to use sudo. */
 #undef NO_ROOT_SUDO
 
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
 /* The default password prompt. */
 #undef PASSPROMPT
 
 /* The syslog priority sudo will use for successful attempts. */
 #undef PRI_SUCCESS
 
+/* Define to 1 if the `putenv' has a const argument.  */
+#undef PUTENV_CONST
+
 /* Define as the return type of signal handlers (`int' or `void'). */
 #undef RETSIGTYPE
 
 /* The number of tries a user gets to enter their password. */
 #undef TRIES_FOR_PASSWORD
 
+/* Define to 1 if the `unsetenv' function returns void instead of `int'. */
+#undef UNSETENV_VOID
+
 /* Define to 1 if you want to insult the user for entering an incorrect
    password. */
 #undef USE_INSULTS
 /* Define to 1 if you want a different ticket file for each tty. */
 #undef USE_TTY_TICKETS
 
+/* Define to 1 if using a non-unix group lookup implementation. */
+#undef USING_NONUNIX_GROUPS
+
 /* Define to avoid using the passwd/shadow file for authentication. */
 #undef WITHOUT_PASSWD
 
index 0bf4e23cf85afae991b60ba2825d13955efdb1ca..1d45b2118a18c1df9b8d3c9375a433ed3e81f674 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for sudo 1.7.
+# Generated by GNU Autoconf 2.61 for sudo 1.7.2.
+#
+# Report bugs to <http://www.sudo.ws/bugs/>.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -722,9 +724,9 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='sudo'
 PACKAGE_TARNAME='sudo'
-PACKAGE_VERSION='1.7'
-PACKAGE_STRING='sudo 1.7'
-PACKAGE_BUGREPORT=''
+PACKAGE_VERSION='1.7.2'
+PACKAGE_STRING='sudo 1.7.2'
+PACKAGE_BUGREPORT='http://www.sudo.ws/bugs/'
 
 # Factoring default headers for most tests.
 ac_includes_default="\
@@ -799,6 +801,7 @@ LIBS
 build_alias
 host_alias
 target_alias
+HAVE_BSM_AUDIT
 LIBTOOL
 CFLAGS
 PROGS
@@ -835,6 +838,7 @@ BSDAUTH_USAGE
 SELINUX_USAGE
 LDAP
 LOGINCAP_USAGE
+NONUNIX_GROUPS_IMPL
 timedir
 timeout
 password_timeout
@@ -864,6 +868,7 @@ path_info
 ldap_conf
 ldap_secret
 nsswitch_conf
+netsvc_conf
 EGREPPROG
 CC
 ac_ct_CC
@@ -878,10 +883,6 @@ host
 host_cpu
 host_vendor
 host_os
-target
-target_cpu
-target_vendor
-target_os
 SED
 GREP
 EGREP
@@ -897,6 +898,7 @@ TRPROG
 NROFFPROG
 YACC
 YFLAGS
+FLEX
 LIBOBJS
 KRB5CONFIG
 LTLIBOBJS'
@@ -1414,7 +1416,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures sudo 1.7 to adapt to many kinds of systems.
+\`configure' configures sudo 1.7.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1474,13 +1476,12 @@ _ACEOF
 System types:
   --build=BUILD     configure for building on BUILD [guessed]
   --host=HOST       cross-compile to build programs to run on HOST [BUILD]
-  --target=TARGET   configure for building compilers for TARGET [HOST]
 _ACEOF
 fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sudo 1.7:";;
+     short | recursive ) echo "Configuration of sudo 1.7.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1499,6 +1500,7 @@ Optional Features:
   --enable-shell-sets-home
                           Set $HOME to target user in shell mode
   --disable-path-info     Print 'command not allowed' not 'command not found'
+  --enable-env-debug      Whether to enable environment debugging.
   --enable-gss-krb5-ccache-name
                           Use GSS-API to set the Kerberos V cred cache name
   --enable-static[=PKGS]  build static libraries [default=no]
@@ -1517,6 +1519,7 @@ Optional Packages:
   --with-CC               C compiler to use
   --with-rpath            pass -R flag in addition to -L for lib paths
   --with-blibpath=PATH    pass -blibpath flag to ld for additional lib paths
+  --with-bsm-audit        enable BSM audit support
   --with-incpath          additional places to look for include files
   --with-libpath          additional places to look for libraries
   --with-libraries        additional libraries to link with
@@ -1527,10 +1530,10 @@ Optional Packages:
   --with-skey=DIR         enable S/Key support
   --with-opie=DIR         enable OPIE support
   --with-long-otp-prompt  use a two line OTP (skey/opie) prompt
-  --with-SecurID[=DIR]    enable SecurID support
-  --with-fwtk[=DIR]       enable FWTK AuthSRV support
-  --with-kerb4[=DIR]      enable Kerberos IV support
-  --with-kerb5[=DIR]      enable Kerberos V support
+  --with-SecurID=DIR      enable SecurID support
+  --with-fwtk=DIR         enable FWTK AuthSRV support
+  --with-kerb4=DIR        enable Kerberos IV support
+  --with-kerb5=DIR        enable Kerberos V support
   --with-aixauth          enable AIX general authentication support
   --with-pam              enable PAM support
   --with-AFS              enable AFS support
@@ -1546,7 +1549,8 @@ Optional Packages:
   --with-logpath          path to the sudo log file
   --with-loglen           maximum length of a log file line (default is 80)
   --with-ignore-dot       ignore '.' in the PATH
-  --without-mail-if-no-user do not send mail if user not in sudoers
+  --without-mail-if-no-user
+                          do not send mail if user not in sudoers
   --with-mail-if-no-host  send mail if user in sudoers but not for this host
   --with-mail-if-noperms  send mail if user not allowed to run command
   --with-mailto           who should get sudo mail (default is "root")
@@ -1555,20 +1559,23 @@ Optional Packages:
   --with-badpass-message  message the user sees when the password is wrong
   --with-fqdn             expect fully qualified hosts in sudoers
   --with-timedir          path to the sudo timestamp dir
-  --with-sendmail=path    set path to sendmail
+  --with-sendmail         set path to sendmail
   --without-sendmail      do not send mail at all
   --with-sudoers-mode     mode of sudoers file (defaults to 0440)
   --with-sudoers-uid      uid that owns sudoers file (defaults to 0)
   --with-sudoers-gid      gid that owns sudoers file (defaults to 0)
-  --with-umask            umask with which the prog should run (default is 022)
+  --with-umask            umask with which the prog should run (default is
+                          022)
   --without-umask         Preserves the umask of the user invoking sudo.
   --with-runas-default    User to run commands as (default is "root")
   --with-exempt=group     no passwd needed for users in this group
   --with-editor=path      Default editor for visudo (defaults to vi)
   --with-env-editor       Use the environment variable EDITOR for visudo
   --with-passwd-tries     number of tries to enter password (default is 3)
-  --with-timeout          minutes before sudo asks for passwd again (def is 5 minutes)
-  --with-password-timeout passwd prompt timeout in minutes (default is 5 minutes)
+  --with-timeout          minutes before sudo asks for passwd again (def is 5
+                          minutes)
+  --with-password-timeout passwd prompt timeout in minutes (default is 5
+                          minutes)
   --with-tty-tickets      use a different ticket file for each tty
   --with-insults          insult the user for entering an incorrect password
   --with-all-insults      include all the sudo insult sets
@@ -1576,20 +1583,26 @@ Optional Packages:
   --with-csops-insults    include CSOps insults
   --with-hal-insults      include 2001-like insults
   --with-goons-insults    include the insults from the "Goon Show"
-  --with-nsswitch[=PATH]  path to nsswitch.conf
-  --with-ldap[=DIR]       enable LDAP support
+  --with-nsswitch=PATH    path to nsswitch.conf
+  --with-ldap=DIR         enable LDAP support
   --with-ldap-conf-file   path to LDAP configuration file
   --with-ldap-secret-file path to LDAP secret password file
-  --with-pc-insults       replace politically incorrect insults with less offensive ones
+  --with-pc-insults       replace politically incorrect insults with less
+                          offensive ones
   --with-secure-path      override the user's path with a built-in one
   --without-interfaces    don't try to read the ip addr of ether interfaces
   --with-stow             properly handle GNU stow packaging
   --with-askpass=PATH     Fully qualified pathname of askpass helper
+  --with-libvas=NAME      Name of the libvas shared library
+                          (default=libvas.so)
+  --with-libvas-rpath=PATH
+                          Path to look for libvas in [default=/opt/quest/lib]
   --with-selinux          enable SELinux support
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
   --with-noexec=PATH      fully qualified pathname of sudo_noexec.so
+  --with-netsvc=PATH      path to netsvc.conf
 
 Some influential environment variables:
   CC          C compiler command
@@ -1609,6 +1622,7 @@ Some influential environment variables:
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
+Report bugs to <http://www.sudo.ws/bugs/>.
 _ACEOF
 ac_status=$?
 fi
@@ -1669,7 +1683,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sudo configure 1.7
+sudo configure 1.7.2
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1683,7 +1697,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by sudo $as_me 1.7, which was
+It was created by sudo $as_me 1.7.2, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2038,8 +2052,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 ac_config_headers="$ac_config_headers config.h pathnames.h"
 
-{ echo "$as_me:$LINENO: Configuring Sudo version 1.7" >&5
-echo "$as_me: Configuring Sudo version 1.7" >&6;}
+{ echo "$as_me:$LINENO: Configuring Sudo version $PACKAGE_VERSION" >&5
+echo "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;}
+
+
+
 
 
 
@@ -2235,6 +2252,26 @@ fi
 
 
 
+# Check whether --with-bsm-audit was given.
+if test "${with_bsm_audit+set}" = set; then
+  withval=$with_bsm_audit; case $with_bsm_audit in
+    yes)       cat >>confdefs.h <<\_ACEOF
+#define HAVE_BSM_AUDIT 1
+_ACEOF
+
+               SUDO_LIBS="${SUDO_LIBS} -lbsm"
+               SUDO_OBJS="${SUDO_OBJS} bsm_audit.o"
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:$LINENO: error: \"--with-bsm-audit does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-bsm-audit does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi
+
+
+
 # Check whether --with-incpath was given.
 if test "${with_incpath+set}" = set; then
   withval=$with_incpath; case $with_incpath in
@@ -3579,21 +3616,12 @@ if test "${with_nsswitch+set}" = set; then
 esac
 fi
 
-if test ${with_nsswitch-"yes"} != "no"; then
-    cat >>confdefs.h <<EOF
-#define _PATH_NSSWITCH_CONF "${with_nsswitch-/etc/nsswitch.conf}"
-EOF
-
-    nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
-else
-    nsswitch_conf='/etc/nsswitch.conf'
-fi
 
 
 # Check whether --with-ldap was given.
 if test "${with_ldap+set}" = set; then
   withval=$with_ldap; case $with_ldap in
-    no)                with_ldap="";;
+    no)                ;;
     *)         cat >>confdefs.h <<\_ACEOF
 #define HAVE_LDAP 1
 _ACEOF
@@ -3770,6 +3798,44 @@ fi
 
 
 
+# Check whether --with-libvas was given.
+if test "${with_libvas+set}" = set; then
+  withval=$with_libvas; case $with_libvas in
+    yes)       with_libvas=libvas.so
+               ;;
+    no)                ;;
+    *)
+cat >>confdefs.h <<_ACEOF
+#define LIBVAS_SO "$with_with_libvas"
+_ACEOF
+
+               ;;
+esac
+if test X"$with_libvas" != X"no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LIBVAS_SO "$with_libvas"
+_ACEOF
+
+    cat >>confdefs.h <<\_ACEOF
+#define USING_NONUNIX_GROUPS 1
+_ACEOF
+
+    NONUNIX_GROUPS_IMPL="vasgroups.o"
+
+# Check whether --with-libvas-rpath was given.
+if test "${with_libvas_rpath+set}" = set; then
+  withval=$with_libvas_rpath; LIBVAS_RPATH=$withval
+else
+  LIBVAS_RPATH=/opt/quest/lib
+fi
+
+fi
+
+fi
+
+
+
 { echo "$as_me:$LINENO: checking whether to do user authentication by default" >&5
 echo $ECHO_N "checking whether to do user authentication by default... $ECHO_C" >&6; }
 # Check whether --enable-authentication was given.
@@ -4014,6 +4080,34 @@ echo "${ECHO_T}no" >&6; }
 fi
 
 
+{ echo "$as_me:$LINENO: checking whether to enable environment debugging" >&5
+echo $ECHO_N "checking whether to enable environment debugging... $ECHO_C" >&6; }
+# Check whether --enable-env_debug was given.
+if test "${enable_env_debug+set}" = set; then
+  enableval=$enable_env_debug;  case "$enableval" in
+    yes)       { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+               cat >>confdefs.h <<\_ACEOF
+#define ENV_DEBUG 1
+_ACEOF
+
+               ;;
+    no)                { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+               ;;
+    *)         { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+               { echo "$as_me:$LINENO: WARNING: Ignoring unknown argument to --enable-env-debug: $enableval" >&5
+echo "$as_me: WARNING: Ignoring unknown argument to --enable-env-debug: $enableval" >&2;}
+               ;;
+  esac
+
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
 
 # Check whether --with-selinux was given.
 if test "${with_selinux+set}" = set; then
@@ -5441,49 +5535,6 @@ IFS=$ac_save_IFS
 case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
-{ echo "$as_me:$LINENO: checking target system type" >&5
-echo $ECHO_N "checking target system type... $ECHO_C" >&6; }
-if test "${ac_cv_target+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "x$target_alias" = x; then
-  ac_cv_target=$ac_cv_host
-else
-  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
-    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5
-echo "${ECHO_T}$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5
-echo "$as_me: error: invalid value of canonical target" >&2;}
-   { (exit 1); exit 1; }; };;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
-  test "$program_prefix$program_suffix$program_transform_name" = \
-    NONENONEs,x,x, &&
-  program_prefix=${target_alias}-
 # Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then
   enableval=$enable_static; p=${PACKAGE-default}
@@ -5509,6 +5560,8 @@ fi
 
 
 
+
+
 # Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then
   enableval=$enable_shared; p=${PACKAGE-default}
@@ -6209,7 +6262,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6212 "configure"' > conftest.$ac_ext
+  echo '#line 6265 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6759,7 +6812,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -7971,7 +8029,7 @@ echo "${ECHO_T}$lt_cv_ld_exported_symbols_list" >&6; }
   esac
 
 
-enable_dlopen=no
+enable_dlopen=yes
 enable_win32_dll=no
 
 # Check whether --enable-libtool-lock was given.
@@ -8068,11 +8126,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8071: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8129: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8075: \$? = $ac_status" >&5
+   echo "$as_me:8133: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8358,11 +8416,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8361: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8419: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8365: \$? = $ac_status" >&5
+   echo "$as_me:8423: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8462,11 +8520,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8465: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8523: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8469: \$? = $ac_status" >&5
+   echo "$as_me:8527: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10822,7 +10880,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10825 "configure"
+#line 10883 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10922,7 +10980,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10925 "configure"
+#line 10983 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11949,6 +12007,22 @@ done
 
                fi
 
+               # AIX analog of nsswitch.conf, enabled by default
+
+# Check whether --with-netsvc was given.
+if test "${with_netsvc+set}" = set; then
+  withval=$with_netsvc; case $with_netsvc in
+                   no)         ;;
+                   yes)        with_netsvc="/etc/netsvc.conf"
+                               ;;
+                   *)          ;;
+               esac
+fi
+
+               if test -z "$with_nsswitch" -a -z "$with_netsvc"; then
+                   with_netsvc="/etc/netsvc.conf"
+               fi
+
                # AIX-specific functions
 
 for ac_func in getuserattr
@@ -12062,6 +12136,66 @@ done
                if test "x$ac_cv_prog_cc_c89" = "xno"; then
                    with_noexec=no
                fi
+
+               # Use the +DAportable flag if it is supported
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS +DAportable"
+               { echo "$as_me:$LINENO: checking whether $CC understands +DAportable" >&5
+echo $ECHO_N "checking whether $CC understands +DAportable... $ECHO_C" >&6; }
+if test "${sudo_cv_var_daportable+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  sudo_cv_var_daportable=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       sudo_cv_var_daportable=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $sudo_cv_var_daportable" >&5
+echo "${ECHO_T}$sudo_cv_var_daportable" >&6; }
+               if test X"$sudo_cv_var_daportable" != X"yes"; then
+                   CFLAGS="$_CFLAGS"
+               fi
+
                case "$host" in
                        *-*-hpux1-8.*)
                            cat >>confdefs.h <<\_ACEOF
 done
 test -n "$YACC" || YACC="yacc"
 
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_FLEX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $FLEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_FLEX="$FLEX" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_FLEX="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_FLEX" && ac_cv_path_FLEX="flex"
+  ;;
+esac
+fi
+FLEX=$ac_cv_path_FLEX
+if test -n "$FLEX"; then
+  { echo "$as_me:$LINENO: result: $FLEX" >&5
+echo "${ECHO_T}$FLEX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
 { echo "$as_me:$LINENO: checking for mv" >&5
 echo $ECHO_N "checking for mv... $ECHO_C" >&6; }
 if test -f "/usr/bin/mv"; then
@@ -13724,7 +13899,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -13927,7 +14107,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -14070,7 +14255,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -14212,7 +14402,12 @@ echo "$as_me: WARNING: project.h:     section \"Present But Cannot Be Compiled\"
 echo "$as_me: WARNING: project.h: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: project.h: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: project.h: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for project.h" >&5
@@ -15629,9 +15824,10 @@ LIBS=$ac_save_LIBS
 
 
 
+
 for ac_func in strchr strrchr memchr memcpy memset sysconf tzset \
               strftime setrlimit initgroups getgroups fstat gettimeofday \
-              setlocale getaddrinfo setsid
+              setlocale getaddrinfo setsid setenv
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -15724,9 +15920,8 @@ _ACEOF
 fi
 done
 
-if test -z "$SKIP_SETRESUID"; then
 
-for ac_func in setresuid
+for ac_func in unsetenv
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -15815,20 +16010,13 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
- SKIP_SETREUID=yes
-fi
-done
-
-fi
-if test -z "$SKIP_SETREUID"; then
-
-for ac_func in setreuid
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking whether unsetenv returns void" >&5
+echo $ECHO_N "checking whether unsetenv returns void... $ECHO_C" >&6; }
+if test "${sudo_cv_func_unsetenv_void+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  sudo_cv_func_unsetenv_void=yes
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -15836,72 +16024,304 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
+$ac_includes_default
+        int unsetenv();
 
 int
 main ()
 {
-return $ac_func ();
+
+        return unsetenv("FOO") != 0;
+
   ;
   return 0;
 }
+
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
+rm -f conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_link") 2>&5
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sudo_cv_func_unsetenv_void=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+sudo_cv_func_unsetenv_void=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $sudo_cv_func_unsetenv_void" >&5
+echo "${ECHO_T}$sudo_cv_func_unsetenv_void" >&6; }
+    if test $sudo_cv_func_unsetenv_void = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define UNSETENV_VOID 1
+_ACEOF
+
+    fi
+
+fi
+done
+
+{ echo "$as_me:$LINENO: checking whether putenv has a const argument" >&5
+echo $ECHO_N "checking whether putenv has a const argument... $ECHO_C" >&6; }
+if test "${sudo_cv_func_putenv_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int putenv(const char *string) {return 0;}
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  sudo_cv_func_putenv_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       sudo_cv_func_putenv_const=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $sudo_cv_func_putenv_const" >&5
+echo "${ECHO_T}$sudo_cv_func_putenv_const" >&6; }
+  if test $sudo_cv_func_putenv_const = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PUTENV_CONST 1
+_ACEOF
+
+  fi
+
+if test -z "$SKIP_SETRESUID"; then
+
+for ac_func in setresuid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ SKIP_SETREUID=yes
+fi
+done
+
+fi
+if test -z "$SKIP_SETREUID"; then
+
+for ac_func in setreuid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 ac_res=`eval echo '${'$as_ac_var'}'`
 done
 
 
+netsvc_conf='/etc/netsvc.conf'
+nsswitch_conf='/etc/nsswitch.conf'
+if test ${with_netsvc-"no"} != "no"; then
+    cat >>confdefs.h <<EOF
+#define _PATH_NETSVC_CONF "${with_netsvc-/etc/netsvc.conf}"
+EOF
+
+    netsvc_conf=${with_netsvc-/etc/netsvc.conf}
+elif test ${with_nsswitch-"yes"} != "no"; then
+    cat >>confdefs.h <<EOF
+#define _PATH_NSSWITCH_CONF "${with_nsswitch-/etc/nsswitch.conf}"
+EOF
+
+    nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
+fi
+
 
 if test -z "${AUTH_EXCL}${AUTH_REG}" -a -n "$AUTH_EXCL_DEF"; then
     for auth in $AUTH_EXCL_DEF; do
@@ -19579,7 +20015,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -19887,7 +20328,12 @@ echo "$as_me: WARNING: bsd_auth.h:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: bsd_auth.h: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: bsd_auth.h: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: bsd_auth.h: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for bsd_auth.h" >&5
@@ -20337,7 +20783,12 @@ echo "$as_me: WARNING: krb.h:     section \"Present But Cannot Be Compiled\"" >&
 echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: krb.h: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: krb.h: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for krb.h" >&5
 echo "${ECHO_T}$ac_cv_search_ber_set_option" >&6; }
 ac_res=$ac_cv_search_ber_set_option
 if test "$ac_res" != no; then
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  found=yes
-else
-  found=no
-fi
-
-    if test X"$found" = X"yes" -a X"$LIBS" != X"$OLIBS"; then
-       LDAP_LIBS="$LDAP_LIBS -llber"
-    fi
-        { echo "$as_me:$LINENO: checking whether lber.h is needed" >&5
-echo $ECHO_N "checking whether lber.h is needed... $ECHO_C" >&6; }
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
-    #include <ldap.h>
-int
-main ()
-{
-(void)ldap_init(0, 0)
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-    { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-    cat >>confdefs.h <<\_ACEOF
-#define HAVE_LBER_H 1
-_ACEOF
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-
-
-
-
-
-
-
-
-
-
-
-for ac_func in ldap_initialize ldap_start_tls_s ldap_sasl_interactive_bind_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+  found=yes
+else
+  found=no
+fi
 
+    if test X"$found" = X"yes" -a X"$LIBS" != X"$OLIBS"; then
+       LDAP_LIBS="$LDAP_LIBS -llber"
+    fi
+        { echo "$as_me:$LINENO: checking whether lber.h is needed" >&5
+echo $ECHO_N "checking whether lber.h is needed... $ECHO_C" >&6; }
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+    #include <ldap.h>
 int
 main ()
 {
-return $ac_func ();
+(void)ldap_init(0, 0)
   ;
   return 0;
 }
@@ -22627,30 +22979,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+
+    { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+    cat >>confdefs.h <<\_ACEOF
+#define HAVE_LBER_H 1
+_ACEOF
+
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
 
-fi
-done
 
 
-for ac_header in sasl/sasl.h
+for ac_header in sasl/sasl.h sasl.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -22765,7 +23114,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -22785,6 +23139,101 @@ if test `eval echo '${'$as_ac_Header'}'` = yes; then
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
+for ac_func in ldap_sasl_interactive_bind_s
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+else
+  break
 fi
 
 done
 done
 
 
+
+
+
+
+
+
+
+
+
+
+for ac_func in ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
     if test X"$check_gss_krb5_ccache_name" = X"yes"; then
        { echo "$as_me:$LINENO: checking for gss_krb5_ccache_name in -lgssapi" >&5
 echo $ECHO_N "checking for gss_krb5_ccache_name in -lgssapi... $ECHO_C" >&6; }
@@ -23169,7 +23722,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -23310,7 +23868,12 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to http://www.sudo.ws/bugs/ ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
 { echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -23347,6 +23910,14 @@ echo "$as_me: WARNING: Unable to locate gssapi.h, you will have to edit the Make
     LDFLAGS="$_LDFLAGS"
 fi
 
+if test X"$LIBVAS_RPATH" != X""; then
+    if test -n "$blibpath"; then
+       blibpath_add="${blibpath_add}:$LIBVAS_RPATH"
+    else
+       LDFLAGS="$LDFLAGS -R$LIBVAS_RPATH"
+    fi
+fi
+
 if test -n "$blibpath"; then
     if test -n "$blibpath_add"; then
        SUDO_LDFLAGS="$SUDO_LDFLAGS -Wl,-blibpath:${blibpath}${blibpath_add}"
@@ -23891,7 +24462,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sudo $as_me 1.7, which was
+This file was extended by sudo $as_me 1.7.2, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -23940,7 +24511,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-sudo config.status 1.7
+sudo config.status 1.7.2
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -24153,6 +24724,7 @@ LIBS!$LIBS$ac_delim
 build_alias!$build_alias$ac_delim
 host_alias!$host_alias$ac_delim
 target_alias!$target_alias$ac_delim
+HAVE_BSM_AUDIT!$HAVE_BSM_AUDIT$ac_delim
 LIBTOOL!$LIBTOOL$ac_delim
 CFLAGS!$CFLAGS$ac_delim
 PROGS!$PROGS$ac_delim
@@ -24189,6 +24761,7 @@ BSDAUTH_USAGE!$BSDAUTH_USAGE$ac_delim
 SELINUX_USAGE!$SELINUX_USAGE$ac_delim
 LDAP!$LDAP$ac_delim
 LOGINCAP_USAGE!$LOGINCAP_USAGE$ac_delim
+NONUNIX_GROUPS_IMPL!$NONUNIX_GROUPS_IMPL$ac_delim
 timedir!$timedir$ac_delim
 timeout!$timeout$ac_delim
 password_timeout!$password_timeout$ac_delim
@@ -24211,8 +24784,6 @@ fqdn!$fqdn$ac_delim
 runas_default!$runas_default$ac_delim
 env_editor!$env_editor$ac_delim
 passwd_tries!$passwd_tries$ac_delim
-tty_tickets!$tty_tickets$ac_delim
-insults!$insults$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -24254,11 +24825,14 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+tty_tickets!$tty_tickets$ac_delim
+insults!$insults$ac_delim
 root_sudo!$root_sudo$ac_delim
 path_info!$path_info$ac_delim
 ldap_conf!$ldap_conf$ac_delim
 ldap_secret!$ldap_secret$ac_delim
 nsswitch_conf!$nsswitch_conf$ac_delim
+netsvc_conf!$netsvc_conf$ac_delim
 EGREPPROG!$EGREPPROG$ac_delim
 CC!$CC$ac_delim
 ac_ct_CC!$ac_ct_CC$ac_delim
@@ -24273,10 +24847,6 @@ host!$host$ac_delim
 host_cpu!$host_cpu$ac_delim
 host_vendor!$host_vendor$ac_delim
 host_os!$host_os$ac_delim
-target!$target$ac_delim
-target_cpu!$target_cpu$ac_delim
-target_vendor!$target_vendor$ac_delim
-target_os!$target_os$ac_delim
 SED!$SED$ac_delim
 GREP!$GREP$ac_delim
 EGREP!$EGREP$ac_delim
@@ -24292,6 +24862,7 @@ TRPROG!$TRPROG$ac_delim
 NROFFPROG!$NROFFPROG$ac_delim
 YACC!$YACC$ac_delim
 YFLAGS!$YFLAGS$ac_delim
+FLEX!$FLEX$ac_delim
 LIBOBJS!$LIBOBJS$ac_delim
 KRB5CONFIG!$KRB5CONFIG$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 
 
 
+
+
+
+
 
 
 
index 6b09b5f18fd535788bc7c6ed76428e6673ea26ab..e21ad6fe7b0e683c662d4ddba1800db3bc2d1a62 100644 (file)
@@ -1,18 +1,19 @@
 dnl
 dnl Process this file with GNU autoconf to produce a configure script.
-dnl $Sudo: configure.in,v 1.538 2008/12/09 21:13:01 millert Exp $
+dnl $Sudo: configure.in,v 1.549 2009/06/13 20:52:50 millert Exp $
 dnl
-dnl Copyright (c) 1994-1996,1998-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl Copyright (c) 1994-1996,1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
 dnl
-AC_INIT([sudo], [1.7])
+AC_INIT([sudo], [1.7.2], [http://www.sudo.ws/bugs/], [sudo])
 AC_CONFIG_HEADER(config.h pathnames.h)
 dnl
 dnl This won't work before AC_INIT
 dnl
-AC_MSG_NOTICE([Configuring Sudo version 1.7])
+AC_MSG_NOTICE([Configuring Sudo version $PACKAGE_VERSION])
 dnl
 dnl Variables that get substituted in the Makefile and man pages
 dnl
+AC_SUBST(HAVE_BSM_AUDIT)
 AC_SUBST(LIBTOOL)
 AC_SUBST(CFLAGS)
 AC_SUBST(PROGS)
@@ -50,6 +51,7 @@ AC_SUBST(BSDAUTH_USAGE)
 AC_SUBST(SELINUX_USAGE)
 AC_SUBST(LDAP)
 AC_SUBST(LOGINCAP_USAGE)
+AC_SUBST(NONUNIX_GROUPS_IMPL)
 dnl
 dnl Variables that get substituted in docs (not overridden by environment)
 dnl
@@ -82,6 +84,7 @@ AC_SUBST(path_info)
 AC_SUBST(ldap_conf)
 AC_SUBST(ldap_secret)
 AC_SUBST(nsswitch_conf)
+AC_SUBST(netsvc_conf)
 dnl
 dnl Initial values for above
 dnl
@@ -159,14 +162,14 @@ dnl
 dnl Deprecated --with options (these all warn or generate an error)
 dnl
 
-AC_ARG_WITH(otp-only, [  --with-otp-only         deprecated],
+AC_ARG_WITH(otp-only, [AS_HELP_STRING([--with-otp-only], [deprecated])],
 [case $with_otp_only in
     yes)       with_passwd="no"
                AC_MSG_NOTICE([--with-otp-only option deprecated, treating as --without-passwd])
                ;;
 esac])
 
-AC_ARG_WITH(alertmail, [  --with-alertmail        deprecated],
+AC_ARG_WITH(alertmail, [AS_HELP_STRING([--with-alertmail], [deprecated])],
 [case $with_alertmail in
     *)         with_mailto="$with_alertmail"
                AC_MSG_NOTICE([--with-alertmail option deprecated, treating as --mailto])
@@ -177,7 +180,7 @@ dnl
 dnl Options for --with
 dnl
 
-AC_ARG_WITH(CC, [  --with-CC               C compiler to use],
+AC_ARG_WITH(CC, [AS_HELP_STRING([--with-CC], [C compiler to use])],
 [case $with_CC in
     yes)       AC_MSG_ERROR(["must give --with-CC an argument."])
                ;;
@@ -187,21 +190,35 @@ AC_ARG_WITH(CC, [  --with-CC               C compiler to use],
                ;;
 esac])
 
-AC_ARG_WITH(rpath, [  --with-rpath            pass -R flag in addition to -L for lib paths],
+AC_ARG_WITH(rpath, [AS_HELP_STRING([--with-rpath], [pass -R flag in addition to -L for lib paths])],
 [case $with_rpath in
     yes|no)    ;;
     *)         AC_MSG_ERROR(["--with-rpath does not take an argument."])
                ;;
 esac])
 
-AC_ARG_WITH(blibpath, [  --with-blibpath[=PATH]    pass -blibpath flag to ld for additional lib paths],
+AC_ARG_WITH(blibpath, [AS_HELP_STRING([--with-blibpath[=PATH]], [pass -blibpath flag to ld for additional lib paths])],
 [case $with_blibpath in
     yes|no)    ;;
     *)         AC_MSG_NOTICE([will pass -blibpath:${with_blibpath} to the loader.])
                ;;
 esac])
 
-AC_ARG_WITH(incpath, [  --with-incpath          additional places to look for include files],
+dnl
+dnl Handle BSM auditing support.
+dnl
+AC_ARG_WITH(bsm-audit, [AS_HELP_STRING([--with-bsm-audit], [enable BSM audit support])],
+[case $with_bsm_audit in
+    yes)       AC_DEFINE(HAVE_BSM_AUDIT)
+               SUDO_LIBS="${SUDO_LIBS} -lbsm"
+               SUDO_OBJS="${SUDO_OBJS} bsm_audit.o"
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-bsm-audit does not take an argument."])
+               ;;
+esac])
+
+AC_ARG_WITH(incpath, [AS_HELP_STRING([--with-incpath], [additional places to look for include files])],
 [case $with_incpath in
     yes)       AC_MSG_ERROR(["must give --with-incpath an argument."])
                ;;
@@ -214,7 +231,7 @@ AC_ARG_WITH(incpath, [  --with-incpath          additional places to look for in
                ;;
 esac])
 
-AC_ARG_WITH(libpath, [  --with-libpath          additional places to look for libraries],
+AC_ARG_WITH(libpath, [AS_HELP_STRING([--with-libpath], [additional places to look for libraries])],
 [case $with_libpath in
     yes)       AC_MSG_ERROR(["must give --with-libpath an argument."])
                ;;
@@ -224,7 +241,7 @@ AC_ARG_WITH(libpath, [  --with-libpath          additional places to look for li
                ;;
 esac])
 
-AC_ARG_WITH(libraries, [  --with-libraries        additional libraries to link with],
+AC_ARG_WITH(libraries, [AS_HELP_STRING([--with-libraries], [additional libraries to link with])],
 [case $with_libraries in
     yes)       AC_MSG_ERROR(["must give --with-libraries an argument."])
                ;;
@@ -234,7 +251,7 @@ AC_ARG_WITH(libraries, [  --with-libraries        additional libraries to link w
                ;;
 esac])
 
-AC_ARG_WITH(devel, [  --with-devel            add development options],
+AC_ARG_WITH(devel, [AS_HELP_STRING([--with-devel], [add development options])],
 [case $with_devel in
     yes)       AC_MSG_NOTICE([Setting up for development: -Wall, flex, yacc])
                PROGS="${PROGS} testsudoers"
@@ -247,7 +264,7 @@ AC_ARG_WITH(devel, [  --with-devel            add development options],
                ;;
 esac])
 
-AC_ARG_WITH(efence, [  --with-efence           link with -lefence for malloc() debugging],
+AC_ARG_WITH(efence, [AS_HELP_STRING([--with-efence], [link with -lefence for malloc() debugging])],
 [case $with_efence in
     yes)       AC_MSG_NOTICE([Sudo will link with -lefence (Electric Fence)])
                LIBS="${LIBS} -lefence"
@@ -260,7 +277,7 @@ AC_ARG_WITH(efence, [  --with-efence           link with -lefence for malloc() d
                ;;
 esac])
 
-AC_ARG_WITH(csops, [  --with-csops            add CSOps standard options],
+AC_ARG_WITH(csops, [AS_HELP_STRING([--with-csops], [add CSOps standard options])],
 [case $with_csops in
     yes)       AC_MSG_NOTICE([Adding CSOps standard options])
                CHECKSIA=false
@@ -277,7 +294,7 @@ AC_ARG_WITH(csops, [  --with-csops            add CSOps standard options],
                ;;
 esac])
 
-AC_ARG_WITH(passwd, [  --without-passwd        don't use passwd/shadow file for authentication],
+AC_ARG_WITH(passwd, [AS_HELP_STRING([--without-passwd], [don't use passwd/shadow file for authentication])],
 [case $with_passwd in
     yes|no)    AC_MSG_CHECKING(whether to use shadow/passwd file authentication)
                AC_MSG_RESULT($with_passwd)
@@ -288,7 +305,7 @@ AC_ARG_WITH(passwd, [  --without-passwd        don't use passwd/shadow file for
                ;;
 esac])
 
-AC_ARG_WITH(skey, [  --with-skey[=DIR]         enable S/Key support ],
+AC_ARG_WITH(skey, [AS_HELP_STRING([--with-skey[=DIR]], [enable S/Key support ])],
 [case $with_skey in
     no)                with_skey=""
                ;;
@@ -299,7 +316,7 @@ AC_ARG_WITH(skey, [  --with-skey[=DIR]         enable S/Key support ],
                ;;
 esac])
 
-AC_ARG_WITH(opie, [  --with-opie[=DIR]         enable OPIE support ],
+AC_ARG_WITH(opie, [AS_HELP_STRING([--with-opie[=DIR]], [enable OPIE support ])],
 [case $with_opie in
     no)                with_opie=""
                ;;
@@ -310,7 +327,7 @@ AC_ARG_WITH(opie, [  --with-opie[=DIR]         enable OPIE support ],
                ;;
 esac])
 
-AC_ARG_WITH(long-otp-prompt, [  --with-long-otp-prompt  use a two line OTP (skey/opie) prompt],
+AC_ARG_WITH(long-otp-prompt, [AS_HELP_STRING([--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)
@@ -323,7 +340,7 @@ AC_ARG_WITH(long-otp-prompt, [  --with-long-otp-prompt  use a two line OTP (skey
                ;;
 esac])
 
-AC_ARG_WITH(SecurID, [  --with-SecurID[[=DIR]]    enable SecurID support],
+AC_ARG_WITH(SecurID, [AS_HELP_STRING([--with-SecurID[[=DIR]]], [enable SecurID support])],
 [case $with_SecurID in
     no)                with_SecurID="";;
     *)         AC_DEFINE(HAVE_SECURID)
@@ -333,7 +350,7 @@ AC_ARG_WITH(SecurID, [  --with-SecurID[[=DIR]]    enable SecurID support],
                ;;
 esac])
 
-AC_ARG_WITH(fwtk, [  --with-fwtk[[=DIR]]       enable FWTK AuthSRV support],
+AC_ARG_WITH(fwtk, [AS_HELP_STRING([--with-fwtk[[=DIR]]], [enable FWTK AuthSRV support])],
 [case $with_fwtk in
     no)                with_fwtk="";;
     *)         AC_DEFINE(HAVE_FWTK)
@@ -343,7 +360,7 @@ AC_ARG_WITH(fwtk, [  --with-fwtk[[=DIR]]       enable FWTK AuthSRV support],
                ;;
 esac])
 
-AC_ARG_WITH(kerb4, [  --with-kerb4[[=DIR]]      enable Kerberos IV support],
+AC_ARG_WITH(kerb4, [AS_HELP_STRING([--with-kerb4[[=DIR]]], [enable Kerberos IV support])],
 [case $with_kerb4 in
     no)                with_kerb4="";;
     *)         AC_MSG_CHECKING(whether to try kerberos IV authentication)
@@ -352,7 +369,7 @@ AC_ARG_WITH(kerb4, [  --with-kerb4[[=DIR]]      enable Kerberos IV support],
                ;;
 esac])
 
-AC_ARG_WITH(kerb5, [  --with-kerb5[[=DIR]]      enable Kerberos V support],
+AC_ARG_WITH(kerb5, [AS_HELP_STRING([--with-kerb5[[=DIR]]], [enable Kerberos V support])],
 [case $with_kerb5 in
     no)                with_kerb5="";;
     *)         AC_MSG_CHECKING(whether to try Kerberos V authentication)
@@ -361,7 +378,7 @@ AC_ARG_WITH(kerb5, [  --with-kerb5[[=DIR]]      enable Kerberos V support],
                ;;
 esac])
 
-AC_ARG_WITH(aixauth, [  --with-aixauth          enable AIX general authentication support],
+AC_ARG_WITH(aixauth, [AS_HELP_STRING([--with-aixauth], [enable AIX general authentication support])],
 [case $with_aixauth in
     yes)       AUTH_EXCL="$AUTH_EXCL AIX_AUTH";;
     no)                ;;
@@ -369,7 +386,7 @@ AC_ARG_WITH(aixauth, [  --with-aixauth          enable AIX general authenticatio
                ;;
 esac])
 
-AC_ARG_WITH(pam, [  --with-pam              enable PAM support],
+AC_ARG_WITH(pam, [AS_HELP_STRING([--with-pam], [enable PAM support])],
 [case $with_pam in
     yes)       AUTH_EXCL="$AUTH_EXCL PAM";;
     no)                ;;
@@ -377,7 +394,7 @@ AC_ARG_WITH(pam, [  --with-pam              enable PAM support],
                ;;
 esac])
 
-AC_ARG_WITH(AFS, [  --with-AFS              enable AFS support],
+AC_ARG_WITH(AFS, [AS_HELP_STRING([--with-AFS], [enable AFS support])],
 [case $with_AFS in
     yes)       AC_DEFINE(HAVE_AFS)
                AC_MSG_CHECKING(whether to try AFS (kerberos) authentication)
@@ -389,7 +406,7 @@ AC_ARG_WITH(AFS, [  --with-AFS              enable AFS support],
                ;;
 esac])
 
-AC_ARG_WITH(DCE, [  --with-DCE              enable DCE support],
+AC_ARG_WITH(DCE, [AS_HELP_STRING([--with-DCE], [enable DCE support])],
 [case $with_DCE in
     yes)       AC_DEFINE(HAVE_DCE)
                AC_MSG_CHECKING(whether to try DCE (kerberos) authentication)
@@ -401,14 +418,14 @@ AC_ARG_WITH(DCE, [  --with-DCE              enable DCE support],
                ;;
 esac])
 
-AC_ARG_WITH(logincap, [  --with-logincap         enable BSD login class support],
+AC_ARG_WITH(logincap, [AS_HELP_STRING([--with-logincap], [enable BSD login class support])],
 [case $with_logincap in
     yes|no)    ;;
     *)         AC_MSG_ERROR(["--with-logincap does not take an argument."])
                ;;
 esac])
 
-AC_ARG_WITH(bsdauth, [  --with-bsdauth          enable BSD authentication support],
+AC_ARG_WITH(bsdauth, [AS_HELP_STRING([--with-bsdauth], [enable BSD authentication support])],
 [case $with_bsdauth in
     yes)       AUTH_EXCL="$AUTH_EXCL BSD_AUTH";;
     no)                ;;
@@ -416,7 +433,7 @@ AC_ARG_WITH(bsdauth, [  --with-bsdauth          enable BSD authentication suppor
                ;;
 esac])
 
-AC_ARG_WITH(project, [  --with-project          enable Solaris project support],
+AC_ARG_WITH(project, [AS_HELP_STRING([--with-project], [enable Solaris project support])],
 [case $with_project in
     yes|no)    ;;
     no)        ;;
@@ -425,7 +442,7 @@ AC_ARG_WITH(project, [  --with-project          enable Solaris project support],
 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],
+AC_ARG_WITH(lecture, [AS_HELP_STRING([--without-lecture], [don't print lecture for first-time sudoer])],
 [case $with_lecture in
     yes|short|always)  lecture=once
                ;;
@@ -442,7 +459,7 @@ else
 fi
 
 AC_MSG_CHECKING(whether sudo should log via syslog or to a file by default)
-AC_ARG_WITH(logging, [  --with-logging          log via syslog, file, or both],
+AC_ARG_WITH(logging, [AS_HELP_STRING([--with-logging], [log via syslog, file, or both])],
 [case $with_logging in
     yes)       AC_MSG_ERROR(["must give --with-logging an argument."])
                ;;
@@ -462,7 +479,7 @@ AC_ARG_WITH(logging, [  --with-logging          log via syslog, file, or both],
 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")],
+AC_ARG_WITH(logfac, [AS_HELP_STRING([--with-logfac], [syslog facility to log with (default is "local2")])],
 [case $with_logfac in
     yes)       AC_MSG_ERROR(["must give --with-logfac an argument."])
                ;;
@@ -477,7 +494,7 @@ AC_DEFINE_UNQUOTED(LOGFAC, "$logfac", [The syslog facility sudo will use.])
 AC_MSG_RESULT($logfac)
 
 AC_MSG_CHECKING(at which syslog priority to log commands)
-AC_ARG_WITH(goodpri, [  --with-goodpri          syslog priority for commands (def is "notice")],
+AC_ARG_WITH(goodpri, [AS_HELP_STRING([--with-goodpri], [syslog priority for commands (def is "notice")])],
 [case $with_goodpri in
     yes)       AC_MSG_ERROR(["must give --with-goodpri an argument."])
                ;;
@@ -493,7 +510,7 @@ AC_DEFINE_UNQUOTED(PRI_SUCCESS, "$goodpri", [The syslog priority sudo will use f
 AC_MSG_RESULT($goodpri)
 
 AC_MSG_CHECKING(at which syslog priority to log failures)
-AC_ARG_WITH(badpri, [  --with-badpri           syslog priority for failures (def is "alert")],
+AC_ARG_WITH(badpri, [AS_HELP_STRING([--with-badpri], [syslog priority for failures (def is "alert")])],
 [case $with_badpri in
     yes)       AC_MSG_ERROR(["must give --with-badpri an argument."])
                ;;
@@ -508,7 +525,7 @@ esac])
 AC_DEFINE_UNQUOTED(PRI_FAILURE, "$badpri", [The syslog priority sudo will use for unsuccessful attempts/errors.])
 AC_MSG_RESULT($badpri)
 
-AC_ARG_WITH(logpath, [  --with-logpath          path to the sudo log file],
+AC_ARG_WITH(logpath, [AS_HELP_STRING([--with-logpath], [path to the sudo log file])],
 [case $with_logpath in
     yes)       AC_MSG_ERROR(["must give --with-logpath an argument."])
                ;;
@@ -517,7 +534,7 @@ AC_ARG_WITH(logpath, [  --with-logpath          path to the sudo log file],
 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)],
+AC_ARG_WITH(loglen, [AS_HELP_STRING([--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."])
                ;;
@@ -532,7 +549,7 @@ AC_DEFINE_UNQUOTED(MAXLOGFILELEN, $loglen, [The max number of chars per log file
 AC_MSG_RESULT($loglen)
 
 AC_MSG_CHECKING(whether sudo should ignore '.' or '' in \$PATH)
-AC_ARG_WITH(ignore-dot, [  --with-ignore-dot       ignore '.' in the PATH],
+AC_ARG_WITH(ignore-dot, [AS_HELP_STRING([--with-ignore-dot], [ignore '.' in the PATH])],
 [case $with_ignore_dot in
     yes)       ignore_dot=on
                ;;
@@ -549,7 +566,7 @@ else
 fi
 
 AC_MSG_CHECKING(whether to send mail when a user is not in sudoers)
-AC_ARG_WITH(mail-if-no-user, [  --without-mail-if-no-user do not send mail if user not in sudoers],
+AC_ARG_WITH(mail-if-no-user, [AS_HELP_STRING([--without-mail-if-no-user], [do not send mail if user not in sudoers])],
 [case $with_mail_if_no_user in
     yes)       mail_no_user=on
                ;;
@@ -566,7 +583,7 @@ else
 fi
 
 AC_MSG_CHECKING(whether to send mail when user listed but not for this host)
-AC_ARG_WITH(mail-if-no-host, [  --with-mail-if-no-host  send mail if user in sudoers but not for this host],
+AC_ARG_WITH(mail-if-no-host, [AS_HELP_STRING([--with-mail-if-no-host], [send mail if user in sudoers but not for this host])],
 [case $with_mail_if_no_host in
     yes)       mail_no_host=on
                ;;
@@ -583,7 +600,7 @@ else
 fi
 
 AC_MSG_CHECKING(whether to send mail when a user tries a disallowed command)
-AC_ARG_WITH(mail-if-noperms, [  --with-mail-if-noperms  send mail if user not allowed to run command],
+AC_ARG_WITH(mail-if-noperms, [AS_HELP_STRING([--with-mail-if-noperms], [send mail if user not allowed to run command])],
 [case $with_mail_if_noperms in
     yes)       mail_noperms=on
                ;;
@@ -600,7 +617,7 @@ else
 fi
 
 AC_MSG_CHECKING(who should get the mail that sudo sends)
-AC_ARG_WITH(mailto, [  --with-mailto           who should get sudo mail (default is "root")],
+AC_ARG_WITH(mailto, [AS_HELP_STRING([--with-mailto], [who should get sudo mail (default is "root")])],
 [case $with_mailto in
     yes)       AC_MSG_ERROR(["must give --with-mailto an argument."])
                ;;
@@ -612,7 +629,7 @@ esac])
 AC_DEFINE_UNQUOTED(MAILTO, "$mailto", [The user or email address that sudo mail is sent to.])
 AC_MSG_RESULT([$mailto])
 
-AC_ARG_WITH(mailsubject, [  --with-mailsubject      subject of sudo mail],
+AC_ARG_WITH(mailsubject, [AS_HELP_STRING([--with-mailsubject], [subject of sudo mail])],
 [case $with_mailsubject in
     yes)       AC_MSG_ERROR(["must give --with-mailsubject an argument."])
                ;;
@@ -626,7 +643,7 @@ esac])
 AC_DEFINE_UNQUOTED(MAILSUBJECT, "$mailsub", [The subject of the mail sent by sudo to the MAILTO user/address.])
 
 AC_MSG_CHECKING(for bad password prompt)
-AC_ARG_WITH(passprompt, [  --with-passprompt       default password prompt],
+AC_ARG_WITH(passprompt, [AS_HELP_STRING([--with-passprompt], [default password prompt])],
 [case $with_passprompt in
     yes)       AC_MSG_ERROR(["must give --with-passprompt an argument."])
                ;;
@@ -638,7 +655,7 @@ AC_MSG_RESULT($passprompt)
 AC_DEFINE_UNQUOTED(PASSPROMPT, "$passprompt", [The default password prompt.])
 
 AC_MSG_CHECKING(for bad password message)
-AC_ARG_WITH(badpass-message, [  --with-badpass-message  message the user sees when the password is wrong],
+AC_ARG_WITH(badpass-message, [AS_HELP_STRING([--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."])
                ;;
@@ -651,7 +668,7 @@ AC_DEFINE_UNQUOTED(INCORRECT_PASSWORD, "$badpass_message", [The message given wh
 AC_MSG_RESULT([$badpass_message])
 
 AC_MSG_CHECKING(whether to expect fully qualified hosts in sudoers)
-AC_ARG_WITH(fqdn, [  --with-fqdn             expect fully qualified hosts in sudoers],
+AC_ARG_WITH(fqdn, [AS_HELP_STRING([--with-fqdn], [expect fully qualified hosts in sudoers])],
 [case $with_fqdn in
     yes)       fqdn=on
                ;;
@@ -667,7 +684,7 @@ else
     AC_MSG_RESULT(no)
 fi
 
-AC_ARG_WITH(timedir, [  --with-timedir          path to the sudo timestamp dir],
+AC_ARG_WITH(timedir, [AS_HELP_STRING([--with-timedir], [path to the sudo timestamp dir])],
 [case $with_timedir in
     yes)       AC_MSG_ERROR(["must give --with-timedir an argument."])
                ;;
@@ -675,8 +692,8 @@ AC_ARG_WITH(timedir, [  --with-timedir          path to the sudo timestamp dir],
                ;;
 esac])
 
-AC_ARG_WITH(sendmail, [  --with-sendmail=path    set path to sendmail
-  --without-sendmail      do not send mail at all],
+AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail])
+AS_HELP_STRING([--without-sendmail], [do not send mail at all])],
 [case $with_sendmail in
     yes)       with_sendmail=""
                ;;
@@ -685,7 +702,7 @@ AC_ARG_WITH(sendmail, [  --with-sendmail=path    set path to sendmail
                ;;
 esac])
 
-AC_ARG_WITH(sudoers-mode, [  --with-sudoers-mode     mode of sudoers file (defaults to 0440)],
+AC_ARG_WITH(sudoers-mode, [AS_HELP_STRING([--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."])
                ;;
@@ -699,7 +716,7 @@ AC_ARG_WITH(sudoers-mode, [  --with-sudoers-mode     mode of sudoers file (defau
                ;;
 esac])
 
-AC_ARG_WITH(sudoers-uid, [  --with-sudoers-uid      uid that owns sudoers file (defaults to 0)],
+AC_ARG_WITH(sudoers-uid, [AS_HELP_STRING([--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."])
                ;;
@@ -711,7 +728,7 @@ AC_ARG_WITH(sudoers-uid, [  --with-sudoers-uid      uid that owns sudoers file (
                ;;
 esac])
 
-AC_ARG_WITH(sudoers-gid, [  --with-sudoers-gid      gid that owns sudoers file (defaults to 0)],
+AC_ARG_WITH(sudoers-gid, [AS_HELP_STRING([--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."])
                ;;
@@ -724,8 +741,8 @@ AC_ARG_WITH(sudoers-gid, [  --with-sudoers-gid      gid that owns sudoers file (
 esac])
 
 AC_MSG_CHECKING(for umask programs should be run with)
-AC_ARG_WITH(umask, [  --with-umask            umask with which the prog should run (default is 022)
-  --without-umask         Preserves the umask of the user invoking sudo.],
+AC_ARG_WITH(umask, [AS_HELP_STRING([--with-umask], [umask with which the prog should run (default is 022)])
+AS_HELP_STRING([--without-umask], [Preserves the umask of the user invoking sudo.])],
 [case $with_umask in
     yes)       AC_MSG_ERROR(["must give --with-umask an argument."])
                ;;
@@ -744,7 +761,7 @@ else
 fi
 
 AC_MSG_CHECKING(for default user to run commands as)
-AC_ARG_WITH(runas-default, [  --with-runas-default    User to run commands as (default is "root")],
+AC_ARG_WITH(runas-default, [AS_HELP_STRING([--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."])
                ;;
@@ -756,7 +773,7 @@ esac])
 AC_DEFINE_UNQUOTED(RUNAS_DEFAULT, "$runas_default", [The user sudo should run commands as by default.])
 AC_MSG_RESULT([$runas_default])
 
-AC_ARG_WITH(exempt, [  --with-exempt=group     no passwd needed for users in this group],
+AC_ARG_WITH(exempt, [AS_HELP_STRING([--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."])
                ;;
@@ -769,7 +786,7 @@ AC_ARG_WITH(exempt, [  --with-exempt=group     no passwd needed for users in thi
 esac])
 
 AC_MSG_CHECKING(for editor that visudo should use)
-AC_ARG_WITH(editor, [  --with-editor=path      Default editor for visudo (defaults to vi)],
+AC_ARG_WITH(editor, [AS_HELP_STRING([--with-editor=path], [Default editor for visudo (defaults to vi)])],
 [case $with_editor in
     yes)       AC_MSG_ERROR(["must give --with-editor an argument."])
                ;;
@@ -781,7 +798,7 @@ AC_ARG_WITH(editor, [  --with-editor=path      Default editor for visudo (defaul
 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],
+AC_ARG_WITH(env-editor, [AS_HELP_STRING([--with-env-editor], [Use the environment variable EDITOR for visudo])],
 [case $with_env_editor in
     yes)       env_editor=on
                ;;
@@ -798,7 +815,7 @@ else
 fi
 
 AC_MSG_CHECKING(number of tries a user gets to enter their password)
-AC_ARG_WITH(passwd-tries, [  --with-passwd-tries     number of tries to enter password (default is 3)],
+AC_ARG_WITH(passwd-tries, [AS_HELP_STRING([--with-passwd-tries], [number of tries to enter password (default is 3)])],
 [case $with_passwd_tries in
     yes)       ;;
     no)                AC_MSG_ERROR(["--without-editor not supported."])
@@ -812,7 +829,7 @@ AC_DEFINE_UNQUOTED(TRIES_FOR_PASSWORD, $passwd_tries, [The number of tries a use
 AC_MSG_RESULT($passwd_tries)
 
 AC_MSG_CHECKING(time in minutes after which sudo will ask for a password again)
-AC_ARG_WITH(timeout, [  --with-timeout          minutes before sudo asks for passwd again (def is 5 minutes)],
+AC_ARG_WITH(timeout, [AS_HELP_STRING([--with-timeout], [minutes before sudo asks for passwd again (def is 5 minutes)])],
 [case $with_timeout in
     yes)       ;;
     no)                timeout=0
@@ -826,7 +843,7 @@ AC_DEFINE_UNQUOTED(TIMEOUT, $timeout, [The number of minutes before sudo asks fo
 AC_MSG_RESULT($timeout)
 
 AC_MSG_CHECKING(time in minutes after the password prompt will time out)
-AC_ARG_WITH(password-timeout, [  --with-password-timeout passwd prompt timeout in minutes (default is 5 minutes)],
+AC_ARG_WITH(password-timeout, [AS_HELP_STRING([--with-password-timeout], [passwd prompt timeout in minutes (default is 5 minutes)])],
 [case $with_password_timeout in
     yes)       ;;
     no)                password_timeout=0
@@ -840,7 +857,7 @@ AC_DEFINE_UNQUOTED(PASSWORD_TIMEOUT, $password_timeout, [The passwd prompt timeo
 AC_MSG_RESULT($password_timeout)
 
 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],
+AC_ARG_WITH(tty-tickets, [AS_HELP_STRING([--with-tty-tickets], [use a different ticket file for each tty])],
 [case $with_tty_tickets in
     yes)       tty_tickets=on
                ;;
@@ -857,7 +874,7 @@ else
 fi
 
 AC_MSG_CHECKING(whether to include insults)
-AC_ARG_WITH(insults, [  --with-insults          insult the user for entering an incorrect password],
+AC_ARG_WITH(insults, [AS_HELP_STRING([--with-insults], [insult the user for entering an incorrect password])],
 [case $with_insults in
     yes)       insults=on
                with_classic_insults=yes
@@ -875,7 +892,7 @@ else
     AC_MSG_RESULT(no)
 fi
 
-AC_ARG_WITH(all-insults, [  --with-all-insults      include all the sudo insult sets],
+AC_ARG_WITH(all-insults, [AS_HELP_STRING([--with-all-insults], [include all the sudo insult sets])],
 [case $with_all_insults in
     yes)       with_classic_insults=yes
                with_csops_insults=yes
@@ -887,7 +904,7 @@ AC_ARG_WITH(all-insults, [  --with-all-insults      include all the sudo insult
                ;;
 esac])
 
-AC_ARG_WITH(classic-insults, [  --with-classic-insults  include the insults from the "classic" sudo],
+AC_ARG_WITH(classic-insults, [AS_HELP_STRING([--with-classic-insults], [include the insults from the "classic" sudo])],
 [case $with_classic_insults in
     yes)       AC_DEFINE(CLASSIC_INSULTS)
                ;;
@@ -896,7 +913,7 @@ AC_ARG_WITH(classic-insults, [  --with-classic-insults  include the insults from
                ;;
 esac])
 
-AC_ARG_WITH(csops-insults, [  --with-csops-insults    include CSOps insults],
+AC_ARG_WITH(csops-insults, [AS_HELP_STRING([--with-csops-insults], [include CSOps insults])],
 [case $with_csops_insults in
     yes)       AC_DEFINE(CSOPS_INSULTS)
                ;;
@@ -905,7 +922,7 @@ AC_ARG_WITH(csops-insults, [  --with-csops-insults    include CSOps insults],
                ;;
 esac])
 
-AC_ARG_WITH(hal-insults, [  --with-hal-insults      include 2001-like insults],
+AC_ARG_WITH(hal-insults, [AS_HELP_STRING([--with-hal-insults], [include 2001-like insults])],
 [case $with_hal_insults in
     yes)       AC_DEFINE(HAL_INSULTS)
                ;;
@@ -914,7 +931,7 @@ AC_ARG_WITH(hal-insults, [  --with-hal-insults      include 2001-like insults],
                ;;
 esac])
 
-AC_ARG_WITH(goons-insults, [  --with-goons-insults    include the insults from the "Goon Show"],
+AC_ARG_WITH(goons-insults, [AS_HELP_STRING([--with-goons-insults], [include the insults from the "Goon Show"])],
 [case $with_goons_insults in
     yes)       AC_DEFINE(GOONS_INSULTS)
                ;;
@@ -923,38 +940,32 @@ AC_ARG_WITH(goons-insults, [  --with-goons-insults    include the insults from t
                ;;
 esac])
 
-AC_ARG_WITH(nsswitch, [  --with-nsswitch[[=PATH]]  path to nsswitch.conf],
+AC_ARG_WITH(nsswitch, [AS_HELP_STRING([--with-nsswitch[[=PATH]]], [path to nsswitch.conf])],
 [case $with_nsswitch in
     no)                ;;
     yes)       with_nsswitch="/etc/nsswitch.conf"
                ;;
     *)         ;;
 esac])
-if test ${with_nsswitch-"yes"} != "no"; then
-    SUDO_DEFINE_UNQUOTED(_PATH_NSSWITCH_CONF, "${with_nsswitch-/etc/nsswitch.conf}")
-    nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
-else
-    nsswitch_conf='/etc/nsswitch.conf'
-fi
 
-AC_ARG_WITH(ldap, [  --with-ldap[[=DIR]]       enable LDAP support],
+AC_ARG_WITH(ldap, [AS_HELP_STRING([--with-ldap[[=DIR]]], [enable LDAP support])],
 [case $with_ldap in
-    no)                with_ldap="";;
+    no)                ;;
     *)         AC_DEFINE(HAVE_LDAP)
                AC_MSG_CHECKING(whether to use sudoers from LDAP)
                AC_MSG_RESULT(yes)
                ;;
 esac])
 
-AC_ARG_WITH(ldap-conf-file, [  --with-ldap-conf-file   path to LDAP configuration file])
+AC_ARG_WITH(ldap-conf-file, [AS_HELP_STRING([--with-ldap-conf-file], [path to LDAP configuration file])])
 SUDO_DEFINE_UNQUOTED(_PATH_LDAP_CONF, "${with_ldap_conf_file-/etc/ldap.conf}", [Path to the ldap.conf file])
 ldap_conf=${with_ldap_conf_file-'/etc/ldap.conf'}
 
-AC_ARG_WITH(ldap-secret-file, [  --with-ldap-secret-file path to LDAP secret password file])
+AC_ARG_WITH(ldap-secret-file, [AS_HELP_STRING([--with-ldap-secret-file], [path to LDAP secret password file])])
 SUDO_DEFINE_UNQUOTED(_PATH_LDAP_SECRET, "${with_ldap_secret_file-/etc/ldap.secret}", [Path to the ldap.secret file])
 ldap_secret=${with_ldap_secret_file-'/etc/ldap.secret'}
 
-AC_ARG_WITH(pc-insults, [  --with-pc-insults       replace politically incorrect insults with less offensive ones],
+AC_ARG_WITH(pc-insults, [AS_HELP_STRING([--with-pc-insults], [replace politically incorrect insults with less offensive ones])],
 [case $with_pc_insults in
     yes)       AC_DEFINE(PC_INSULTS)
                ;;
@@ -975,7 +986,7 @@ if test "$insults" = "on"; then
 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 built-in one],
+AC_ARG_WITH(secure-path, [AS_HELP_STRING([--with-secure-path], [override the user's path with a built-in 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])
@@ -988,7 +999,7 @@ AC_ARG_WITH(secure-path, [  --with-secure-path      override the user's path wit
 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],
+AC_ARG_WITH(interfaces, [AS_HELP_STRING([--without-interfaces], [don't try to read the ip addr of ether interfaces])],
 [case $with_interfaces in
     yes)       AC_MSG_RESULT(yes)
                ;;
@@ -1000,7 +1011,7 @@ AC_ARG_WITH(interfaces, [  --without-interfaces    don't try to read the ip addr
 esac], AC_MSG_RESULT(yes))
 
 AC_MSG_CHECKING(whether stow should be used)
-AC_ARG_WITH(stow, [  --with-stow             properly handle GNU stow packaging],
+AC_ARG_WITH(stow, [AS_HELP_STRING([--with-stow], [properly handle GNU stow packaging])],
 [case $with_stow in
     yes)       AC_MSG_RESULT(yes)
                AC_DEFINE(USE_STOW)
@@ -1012,7 +1023,7 @@ AC_ARG_WITH(stow, [  --with-stow             properly handle GNU stow packaging]
 esac], AC_MSG_RESULT(no))
 
 AC_MSG_CHECKING(whether to use an askpass helper)
-AC_ARG_WITH(askpass, [  --with-askpass=PATH     Fully qualified pathname of askpass helper],
+AC_ARG_WITH(askpass, [AS_HELP_STRING([--with-askpass=PATH], [Fully qualified pathname of askpass helper])],
 [case $with_askpass in
     yes)       AC_MSG_ERROR(["--with-askpass takes a path as an argument."])
                ;;
@@ -1021,14 +1032,36 @@ AC_ARG_WITH(askpass, [  --with-askpass=PATH     Fully qualified pathname of askp
                ;;
 esac], AC_MSG_RESULT(no))
 
+dnl
+dnl If enabled, set LIBVAS_SO, LIBVAS_RPATH and USING_NONUNIX_GROUPS
+dnl
+AC_ARG_WITH(libvas, [AS_HELP_STRING([--with-libvas=NAME], [Name of the libvas shared library (default=libvas.so)])],
+[case $with_libvas in
+    yes)       with_libvas=libvas.so
+               ;;
+    no)                ;;
+    *)         AC_DEFINE_UNQUOTED([LIBVAS_SO], ["$with_with_libvas"], [The name of libvas.so])
+               ;;
+esac
+if test X"$with_libvas" != X"no"; then
+    AC_DEFINE_UNQUOTED([LIBVAS_SO], ["$with_libvas"], [The name of libvas.so])
+    AC_DEFINE(USING_NONUNIX_GROUPS)
+    NONUNIX_GROUPS_IMPL="vasgroups.o"
+    AC_ARG_WITH([libvas-rpath],
+       [AS_HELP_STRING([--with-libvas-rpath=PATH],
+                      [Path to look for libvas in [default=/opt/quest/lib]])],
+       [LIBVAS_RPATH=$withval],
+       [LIBVAS_RPATH=/opt/quest/lib])
+fi
+])
+
 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],
+[AS_HELP_STRING([--disable-authentication], [Do not require authentication by default])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(yes)
                ;;
@@ -1043,7 +1076,7 @@ AC_ARG_ENABLE(authentication,
 
 AC_MSG_CHECKING(whether to disable running the mailer as root)
 AC_ARG_ENABLE(root-mailer,
-[  --disable-root-mailer   Don't run the mailer as root, run as the user],
+[AS_HELP_STRING([--disable-root-mailer], [Don't run the mailer as root, run as the user])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(no)
                ;;
@@ -1057,7 +1090,7 @@ AC_ARG_ENABLE(root-mailer,
 ], AC_MSG_RESULT(no))
 
 AC_ARG_ENABLE(setreuid,
-[  --disable-setreuid      Don't try to use the setreuid() function],
+[AS_HELP_STRING([--disable-setreuid], [Don't try to use the setreuid() function])],
 [ case "$enableval" in
     no)                SKIP_SETREUID=yes
                ;;
@@ -1066,7 +1099,7 @@ AC_ARG_ENABLE(setreuid,
 ])
 
 AC_ARG_ENABLE(setresuid,
-[  --disable-setresuid     Don't try to use the setresuid() function],
+[AS_HELP_STRING([--disable-setresuid], [Don't try to use the setresuid() function])],
 [ case "$enableval" in
     no)                SKIP_SETRESUID=yes
                ;;
@@ -1076,7 +1109,7 @@ AC_ARG_ENABLE(setresuid,
 
 AC_MSG_CHECKING(whether to disable shadow password support)
 AC_ARG_ENABLE(shadow,
-[  --disable-shadow        Never use shadow passwords],
+[AS_HELP_STRING([--disable-shadow], [Never use shadow passwords])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(no)
                ;;
@@ -1091,7 +1124,7 @@ AC_ARG_ENABLE(shadow,
 
 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],
+[AS_HELP_STRING([--disable-root-sudo], [Don't allow root to run sudo])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(yes)
                ;;
@@ -1106,7 +1139,7 @@ AC_ARG_ENABLE(root-sudo,
 
 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],
+[AS_HELP_STRING([--enable-log-host], [Log the hostname in the log file])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(yes)
                AC_DEFINE(HOST_IN_LOG)
@@ -1121,7 +1154,7 @@ AC_ARG_ENABLE(log-host,
 
 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],
+[AS_HELP_STRING([--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)
@@ -1136,8 +1169,7 @@ AC_ARG_ENABLE(noargs-shell,
 
 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],
+[AS_HELP_STRING([--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)
@@ -1152,7 +1184,7 @@ AC_ARG_ENABLE(shell-sets-home,
 
 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'],
+[AS_HELP_STRING([--disable-path-info], [Print 'command not allowed' not 'command not found'])],
 [ case "$enableval" in
     yes)       AC_MSG_RESULT(no)
                ;;
@@ -1166,7 +1198,22 @@ AC_ARG_ENABLE(path_info,
   esac
 ], AC_MSG_RESULT(no))
 
-AC_ARG_WITH(selinux, [  --with-selinux          enable SELinux support],
+AC_MSG_CHECKING(whether to enable environment debugging)
+AC_ARG_ENABLE(env_debug,
+[AS_HELP_STRING([--enable-env-debug], [Whether to enable environment debugging.])],
+[ case "$enableval" in
+    yes)       AC_MSG_RESULT(yes)
+               AC_DEFINE(ENV_DEBUG)
+               ;;
+    no)                AC_MSG_RESULT(no)
+               ;;
+    *)         AC_MSG_RESULT(no)
+               AC_MSG_WARN([Ignoring unknown argument to --enable-env-debug: $enableval])
+               ;;
+  esac
+], AC_MSG_RESULT(no))
+
+AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support])],
 [case $with_selinux in
     yes)       SELINUX_USAGE="[[-r role]] [[-t type]] "
                AC_DEFINE(HAVE_SELINUX)
@@ -1184,8 +1231,9 @@ esac])
 dnl
 dnl gss_krb5_ccache_name() may not work on Heimdal so we don't use it by default
 dnl
-AC_ARG_ENABLE(gss_krb5_ccache_name, [  --enable-gss-krb5-ccache-name
-                          Use GSS-API to set the Kerberos V cred cache name], [check_gss_krb5_ccache_name=$enableval], [check_gss_krb5_ccache_name=no])
+AC_ARG_ENABLE(gss_krb5_ccache_name,
+[AS_HELP_STRING([--enable-gss-krb5-ccache-name], [Use GSS-API to set the Kerberos V cred cache name])],
+[check_gss_krb5_ccache_name=$enableval], [check_gss_krb5_ccache_name=no])
 
 dnl
 dnl If we don't have egrep we can't do anything...
@@ -1212,8 +1260,8 @@ dnl
 dnl Libtool magic; enable shared libs and disable static libs
 dnl
 AC_CANONICAL_HOST
-AC_CANONICAL_TARGET([])
 AC_DISABLE_STATIC
+AC_LIBTOOL_DLOPEN
 AC_PROG_LIBTOOL
 
 dnl
@@ -1225,7 +1273,7 @@ else
     eval _shrext="$shrext_cmds"
 fi
 AC_MSG_CHECKING(path to sudo_noexec.so)
-AC_ARG_WITH(noexec, [  --with-noexec[=PATH]      fully qualified pathname of sudo_noexec.so],
+AC_ARG_WITH(noexec, [AS_HELP_STRING([--with-noexec[=PATH]], [fully qualified pathname of sudo_noexec.so])],
 [case $with_noexec in
     yes)       with_noexec="$libexecdir/sudo_noexec$_shrext"
                ;;
@@ -1334,6 +1382,18 @@ case "$host" in
                    AC_CHECK_FUNCS(authenticate, [AUTH_EXCL_DEF="AIX_AUTH"])
                fi
 
+               # AIX analog of nsswitch.conf, enabled by default
+               AC_ARG_WITH(netsvc, [AS_HELP_STRING([--with-netsvc[[=PATH]]], [path to netsvc.conf])],
+               [case $with_netsvc in
+                   no)         ;;
+                   yes)        with_netsvc="/etc/netsvc.conf"
+                               ;;
+                   *)          ;;
+               esac])
+               if test -z "$with_nsswitch" -a -z "$with_netsvc"; then
+                   with_netsvc="/etc/netsvc.conf"
+               fi
+
                # AIX-specific functions
                AC_CHECK_FUNCS(getuserattr)
                SUDO_OBJS="$SUDO_OBJS aix.o"
@@ -1354,6 +1414,19 @@ case "$host" in
                if test "x$ac_cv_prog_cc_c89" = "xno"; then
                    with_noexec=no
                fi
+
+               # Use the +DAportable flag if it is supported
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS +DAportable"
+               AC_CACHE_CHECK([whether $CC understands +DAportable],
+                   [sudo_cv_var_daportable],
+                   [AC_TRY_LINK([], [], [sudo_cv_var_daportable=yes],
+                                [sudo_cv_var_daportable=no])]
+               )
+               if test X"$sudo_cv_var_daportable" != X"yes"; then
+                   CFLAGS="$_CFLAGS"
+               fi
+
                case "$host" in
                        *-*-hpux[1-8].*)
                            AC_DEFINE(BROKEN_SYSLOG)
@@ -1396,7 +1469,7 @@ case "$host" in
                : ${CHECKSIA='true'}
                AC_MSG_CHECKING(whether to disable sia support on Digital UNIX)
                AC_ARG_ENABLE(sia,
-               [  --disable-sia           Disable SIA on Digital UNIX],
+               [AS_HELP_STRING([--disable-sia], [Disable SIA on Digital UNIX])],
                [ case "$enableval" in
                    yes)        AC_MSG_RESULT(no)
                                CHECKSIA=true
@@ -1689,6 +1762,7 @@ dnl
 dnl Program checks
 dnl
 AC_PROG_YACC
+AC_PATH_PROG([FLEX], [flex], [flex])
 SUDO_PROG_MV
 SUDO_PROG_BSHELL
 if test -z "$with_sendmail"; then
@@ -1762,7 +1836,9 @@ dnl
 AC_FUNC_GETGROUPS
 AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf tzset \
               strftime setrlimit initgroups getgroups fstat gettimeofday \
-              setlocale getaddrinfo setsid)
+              setlocale getaddrinfo setsid setenv)
+AC_CHECK_FUNCS(unsetenv, SUDO_FUNC_UNSETENV_VOID)
+SUDO_FUNC_PUTENV_CONST
 if test -z "$SKIP_SETRESUID"; then
     AC_CHECK_FUNCS(setresuid, [SKIP_SETREUID=yes])
 fi
@@ -1857,6 +1933,19 @@ AC_CHECK_FUNCS(getprogname, , [
     AC_MSG_RESULT($sudo_cv___progname)
 ])
 
+dnl
+dnl nsswitch.conf and its equivalents
+dnl
+netsvc_conf='/etc/netsvc.conf'
+nsswitch_conf='/etc/nsswitch.conf'
+if test ${with_netsvc-"no"} != "no"; then
+    SUDO_DEFINE_UNQUOTED(_PATH_NETSVC_CONF, "${with_netsvc-/etc/netsvc.conf}")
+    netsvc_conf=${with_netsvc-/etc/netsvc.conf}
+elif test ${with_nsswitch-"yes"} != "no"; then
+    SUDO_DEFINE_UNQUOTED(_PATH_NSSWITCH_CONF, "${with_nsswitch-/etc/nsswitch.conf}")
+    nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
+fi
+
 dnl
 dnl Mutually exclusive auth checks come first, followed by
 dnl non-exclusive ones.  Note: passwd must be last of all!
@@ -1899,7 +1988,7 @@ if test ${with_pam-"no"} != "no"; then
        AUTH_EXCL=PAM
        AC_MSG_CHECKING(whether to use PAM session support)
        AC_ARG_ENABLE(pam_session,
-       [  --disable-pam-session   Disable PAM session support],
+       [AS_HELP_STRING([--disable-pam-session], [Disable PAM session support])],
            [ case "$enableval" in
                yes)    AC_MSG_RESULT(yes)
                        ;;
@@ -2389,9 +2478,9 @@ if test ${with_ldap-'no'} != "no"; then
     AC_MSG_RESULT([yes])
     AC_DEFINE(HAVE_LBER_H)])
 
-    AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s ldap_sasl_interactive_bind_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s)
-    AC_CHECK_HEADERS([sasl/sasl.h])
+    AC_CHECK_HEADERS([sasl/sasl.h] [sasl.h], [AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s)], [break])
     AC_CHECK_HEADERS([ldap_ssl.h] [mps/ldap_ssl.h], [break], [], [#include <ldap.h>])
+    AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np)
 
     if test X"$check_gss_krb5_ccache_name" = X"yes"; then
        AC_CHECK_LIB(gssapi, gss_krb5_ccache_name,
@@ -2425,6 +2514,18 @@ if test ${with_ldap-'no'} != "no"; then
     LDFLAGS="$_LDFLAGS"
 fi
 
+dnl
+dnl Add LIBVAS_RPATH to LDFLAGS
+dnl GNU ld accepts -R/path/ as an alias for -rpath /path/
+dnl
+if test X"$LIBVAS_RPATH" != X""; then
+    if test -n "$blibpath"; then
+       blibpath_add="${blibpath_add}:$LIBVAS_RPATH"
+    else
+       LDFLAGS="$LDFLAGS -R$LIBVAS_RPATH"
+    fi
+fi
+
 dnl
 dnl Add $blibpath to SUDO_LDFLAGS if specified by the user or if we
 dnl added -L dirpaths to SUDO_LDFLAGS.
@@ -2539,6 +2640,7 @@ AH_TEMPLATE(HAL_INSULTS, [Define to 1 if you want 2001-like insults.])
 AH_TEMPLATE(HAVE_AFS, [Define to 1 if you use AFS.])
 AH_TEMPLATE(HAVE_AIXAUTH, [Define to 1 if you use AIX general authentication.])
 AH_TEMPLATE(HAVE_BSD_AUTH_H, [Define to 1 if you use BSD authentication.])
+AH_TEMPLATE(HAVE_BSM_AUDIT, [Define to 1 to enable BSM auditing.])
 AH_TEMPLATE(HAVE_DCE, [Define to 1 if you use OSF DCE.])
 AH_TEMPLATE(HAVE_DD_FD, [Define to 1 if your `DIR' contains dd_fd.])
 AH_TEMPLATE(HAVE_DIRFD, [Define to 1 if you have the `dirfd' function or macro.])
@@ -2603,6 +2705,7 @@ AH_TEMPLATE(USE_TTY_TICKETS, [Define to 1 if you want a different ticket file fo
 AH_TEMPLATE(WITHOUT_PASSWD, [Define to avoid using the passwd/shadow file for authentication.])
 AH_TEMPLATE(sig_atomic_t, [Define to `int' if <signal.h> does not define.])
 AH_TEMPLATE(__signed, [Define to `signed' or nothing if compiler does not support a signed type qualifier.])
+AH_TEMPLATE(USING_NONUNIX_GROUPS, [Define to 1 if using a non-Unix group lookup implementation.])
 
 dnl
 dnl Bits to copy verbatim into config.h.in
index 72c14c9f1f3f5de22b5489cc2a9941a0aee3e532..8498464dbe1e32250589ead5ae1eb9bb973fe3c9 100644 (file)
@@ -302,6 +302,18 @@ struct sudo_defs_types sudo_defs_table[] = {
        "visiblepw", T_FLAG,
        "Allow sudo to prompt for a password even if it would be visisble",
        NULL,
+    }, {
+       "pwfeedback", T_FLAG,
+       "Provide visual feedback at the password prompt when there is user input",
+       NULL,
+    }, {
+       "fast_glob", T_FLAG,
+       "Use faster globbing that is less accurate but does not access the filesystem",
+       NULL,
+    }, {
+       "umask_override", T_FLAG,
+       "The umask specified in sudoers will override the user's, even if it is more permissive",
+       NULL,
     }, {
        NULL, 0, NULL
     }
index afa78e0b5fc29b6f8ded5c4d491a22942a454465..bccfd160b8cebf6f6ee8a148ecfb1ecbee588431 100644 (file)
 #define I_SUDOERS_LOCALE        68
 #define def_visiblepw           (sudo_defs_table[69].sd_un.flag)
 #define I_VISIBLEPW             69
+#define def_pwfeedback          (sudo_defs_table[70].sd_un.flag)
+#define I_PWFEEDBACK            70
+#define def_fast_glob           (sudo_defs_table[71].sd_un.flag)
+#define I_FAST_GLOB             71
+#define def_umask_override      (sudo_defs_table[72].sd_un.flag)
+#define I_UMASK_OVERRIDE        72
 
 enum def_tupple {
        never,
index 0a0a3b86deb6a741121cc306f15e67c69191a539..625c1409729d61ebcc34958626899bef7e23ccaf 100644 (file)
@@ -223,3 +223,12 @@ sudoers_locale
 visiblepw
        T_FLAG
        "Allow sudo to prompt for a password even if it would be visisble"
+pwfeedback
+       T_FLAG
+       "Provide visual feedback at the password prompt when there is user input"
+fast_glob
+       T_FLAG
+       "Use faster globbing that is less accurate but does not access the filesystem"
+umask_override
+       T_FLAG
+       "The umask specified in sudoers will override the user's, even if it is more permissive"
diff --git a/env.c b/env.c
index af6d53554d5b83afa1af1ed30cc7926420207356..3049dff93308329d357e87b80e8601289ec3d85b 100644 (file)
--- a/env.c
+++ b/env.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005, 2007-2008
+ * Copyright (c) 2000-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+#include <errno.h>
 #include <pwd.h>
 
 #include "sudo.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: env.c,v 1.94 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: env.c,v 1.106 2009/06/23 18:24:42 millert Exp $";
 #endif /* lint */
 
 /*
@@ -101,11 +103,8 @@ struct environment {
  * Prototypes
  */
 void rebuild_env               __P((int, int));
-void sudo_setenv               __P((const char *, const char *, int));
-void sudo_unsetenv             __P((const char *));
-static void _sudo_setenv       __P((const char *, const char *, int));
-static void insert_env         __P((char *, int, int));
-static void sync_env           __P((void));
+static void sudo_setenv                __P((const char *, const char *, int));
+static void sudo_putenv                __P((char *, int, int));
 
 extern char **environ;         /* global environment */
 
@@ -214,36 +213,13 @@ static const char *initial_keepenv_table[] = {
     NULL
 };
 
-/*
- * Syncronize our private copy of the environment with what is
- * in environ.
- */
-static void
-sync_env()
-{
-    size_t evlen;
-    char **ep;
-
-    for (ep = environ; *ep != NULL; ep++)
-       continue;
-    evlen = ep - environ;
-    if (evlen + 1 > env.env_size) {
-       efree(env.envp);
-       env.env_size = evlen + 1 + 128;
-       env.envp = emalloc2(env.env_size, sizeof(char *));
-    }
-    memcpy(env.envp, environ, (evlen + 1) * sizeof(char *));
-    env.env_len = evlen;
-    environ = env.envp;
-}
-
 /*
  * Similar to setenv(3) but operates on sudo's private copy of the environment
- * and it always overwrites.  The dupcheck param determines whether we need
- * to verify that the variable is not already set.
+ * (not environ) and it always overwrites.  The dupcheck param determines
+ * whether we need to verify that the variable is not already set.
  */
 static void
-_sudo_setenv(var, val, dupcheck)
+sudo_setenv(var, val, dupcheck)
     const char *var;
     const char *val;
     int dupcheck;
@@ -261,106 +237,234 @@ _sudo_setenv(var, val, dupcheck)
 
        errorx(1, "internal error, sudo_setenv() overflow");
     }
-    insert_env(estring, dupcheck, FALSE);
+    sudo_putenv(estring, dupcheck, TRUE);
 }
 
-#ifdef HAVE_LDAP
 /*
- * External version of sudo_setenv() that keeps things in sync with
- * the environ pointer.
+ * Version of setenv(3) that uses our own environ pointer.
+ * Will sync with environ as needed.
  */
-void
-sudo_setenv(var, val, dupcheck)
+int
+setenv(var, val, overwrite)
     const char *var;
     const char *val;
-    int dupcheck;
+    int overwrite;
 {
-    char *estring;
+    char *estring, *ep;
+    const char *cp;
     size_t esize;
 
-    /* Make sure we are operating on the current environment. */
-    if (env.envp != environ)
-       sync_env();
+    if (!var || *var == '\0')
+       return(EINVAL);
 
-    esize = strlen(var) + 1 + strlen(val) + 1;
-    estring = emalloc(esize);
+    /*
+     * POSIX says a var name with '=' is an error but BSD
+     * just ignores the '=' and anything after it.
+     */
+    for (cp = var; *cp && *cp != '='; cp++)
+       ;
+    esize = (size_t)(cp - var) + 2;
+    if (val) {
+       esize += strlen(val);   /* glibc treats a NULL val as "" */
+    }
 
-    /* Build environment string and insert it. */
-    if (strlcpy(estring, var, esize) >= esize ||
-       strlcat(estring, "=", esize) >= esize ||
-       strlcat(estring, val, esize) >= esize) {
+    /* Allocate and fill in estring. */
+    estring = ep = emalloc(esize);
+    for (cp = var; *cp && *cp != '='; cp++)
+       *ep++ = *cp;
+    *ep++ = '=';
+    if (val) {
+       for (cp = val; *cp; cp++)
+           *ep++ = *cp;
+    }
+    *ep = '\0';
 
-       errorx(1, "internal error, sudo_setenv() overflow");
+    /* Sync env.envp with environ as needed. */
+    if (env.envp != environ) {
+       char **ep;
+       size_t len;
+
+       for (ep = environ; *ep != NULL; ep++)
+           continue;
+       len = ep - environ;
+       if (len + 2 > env.env_size) {
+           efree(env.envp);
+           env.env_size = len + 2 + 128;
+           env.envp = emalloc2(env.env_size, sizeof(char *));
+#ifdef ENV_DEBUG
+           memset(env.envp, 0, env.env_size * sizeof(char *));
+#endif
+       }
+       memcpy(env.envp, environ, len * sizeof(char *));
+       env.envp[len] = NULL;
+       env.env_len = len;
+       environ = env.envp;
+#ifdef ENV_DEBUG
+    } else {
+       if (env.envp[env.env_len] != NULL)
+           errorx(1, "setenv: corrupted envp, len mismatch");
+#endif
     }
-    insert_env(estring, dupcheck, TRUE);
+    sudo_putenv(estring, TRUE, overwrite);
+    return(0);
 }
-#endif /* HAVE_LDAP */
 
-#if defined(HAVE_LDAP) || defined(HAVE_AIXAUTH)
 /*
- * Similar to unsetenv(3) but operates on sudo's private copy of the
- * environment.
+ * Version of unsetenv(3) that uses our own environ pointer.
+ * Will sync with environ as needed.
  */
+#ifdef UNSETENV_VOID
 void
-sudo_unsetenv(var)
+#else
+int
+#endif
+unsetenv(var)
     const char *var;
 {
-    char **nep;
-    size_t varlen;
+    char **ep;
+    size_t len;
+
+    if (strchr(var, '=') != NULL) {
+       errno = EINVAL;
+#ifdef UNSETENV_VOID
+       return;
+#else
+       return(-1);
+#endif
+    }
 
     /* Make sure we are operating on the current environment. */
-    if (env.envp != environ)
-       sync_env();
-
-    varlen = strlen(var);
-    for (nep = env.envp; *nep; nep++) {
-       if (strncmp(var, *nep, varlen) == 0 && (*nep)[varlen] == '=') {
-           /* Found it; move everything over by one and update len. */
-           memmove(nep, nep + 1,
-               (env.env_len - (nep - env.envp)) * sizeof(char *));
+    /* XXX - this could be optimized to include the search */
+    if (env.envp != environ) {
+       for (ep = environ; *ep != NULL; ep++)
+           continue;
+       len = ep - environ;
+       if (len + 1 > env.env_size) {
+           efree(env.envp);
+           env.env_size = len + 1 + 128;
+           env.envp = emalloc2(env.env_size, sizeof(char *));
+#ifdef ENV_DEBUG
+           memset(env.envp, 0, env.env_size * sizeof(char *));
+#endif
+       }
+       memcpy(env.envp, environ, len * sizeof(char *));
+       env.envp[len] = NULL;
+       env.env_len = len;
+       environ = env.envp;
+#ifdef ENV_DEBUG
+    } else {
+       if (env.envp[env.env_len] != NULL)
+           errorx(1, "unsetenv: corrupted envp, len mismatch");
+#endif
+    }
+
+    len = strlen(var);
+    for (ep = env.envp; *ep; ep++) {
+       if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
+           /* Found it; shift remainder + NULL over by one and update len. */
+           memmove(ep, ep + 1,
+               (env.env_len - (ep - env.envp)) * sizeof(char *));
            env.env_len--;
-           return;
+           break;
        }
     }
+#ifndef UNSETENV_VOID
+    return(0);
+#endif
 }
-#endif /* HAVE_LDAP || HAVE_AIXAUTH */
 
 /*
- * Insert str into env.envp, assumes str has an '=' in it.
+ * Version of putenv(3) that uses our own environ pointer.
+ * Will sync with environ as needed.
+ */
+int
+#ifdef PUTENV_CONST
+putenv(const char *string)
+#else
+putenv(string)
+    char *string;
+#endif
+{
+    if (strchr(string, '=') == NULL) {
+       errno = EINVAL;
+       return(-1);
+    }
+    /* Sync env.envp with environ as needed. */
+    if (env.envp != environ) {
+       char **ep;
+       size_t len;
+
+       for (ep = environ; *ep != NULL; ep++)
+           continue;
+       len = ep - environ;
+       if (len + 2 > env.env_size) {
+           efree(env.envp);
+           env.env_size = len + 2 + 128;
+           env.envp = emalloc2(env.env_size, sizeof(char *));
+#ifdef ENV_DEBUG
+           memset(env.envp, 0, env.env_size * sizeof(char *));
+#endif
+       }
+       memcpy(env.envp, environ, len * sizeof(char *));
+       env.envp[len] = NULL;
+       env.env_len = len;
+       environ = env.envp;
+#ifdef ENV_DEBUG
+    } else {
+       if (env.envp[env.env_len] != NULL)
+           errorx(1, "putenv: corrupted envp, len mismatch");
+#endif
+    }
+    sudo_putenv((char *)string, TRUE, TRUE);
+    return(0);
+}
+
+/*
+ * Similar to putenv(3) but operates on sudo's private copy of the
+ * environment (not environ) and it always overwrites.  The dupcheck param
+ * determines whether we need to verify that the variable is not already set.
+ * Will only overwrite an existing variable if overwrite is set.
  */
 static void
-insert_env(str, dupcheck, dosync)
+sudo_putenv(str, dupcheck, overwrite)
     char *str;
     int dupcheck;
-    int dosync;
+    int overwrite;
 {
-    char **nep;
-    size_t varlen;
+    char **ep;
+    size_t len;
 
     /* Make sure there is room for the new entry plus a NULL. */
     if (env.env_len + 2 > env.env_size) {
        env.env_size += 128;
        env.envp = erealloc3(env.envp, env.env_size, sizeof(char *));
-       if (dosync)
-           environ = env.envp;
+#ifdef ENV_DEBUG
+       memset(env.envp + env.env_len, 0,
+           (env.env_size - env.env_len) * sizeof(char *));
+#endif
+       environ = env.envp;
     }
 
-    if (dupcheck) {
-           varlen = (strchr(str, '=') - str) + 1;
+#ifdef ENV_DEBUG
+    if (env.envp[env.env_len] != NULL)
+       errorx(1, "sudo_putenv: corrupted envp, len mismatch");
+#endif
 
-           for (nep = env.envp; *nep; nep++) {
-               if (strncmp(str, *nep, varlen) == 0) {
-                   if (dupcheck != -1)
-                       *nep = str;
+    if (dupcheck) {
+           len = (strchr(str, '=') - str) + 1;
+           for (ep = env.envp; *ep; ep++) {
+               if (strncmp(str, *ep, len) == 0) {
+                   if (overwrite)
+                       *ep = str;
                    return;
                }
            }
     } else
-       nep = env.envp + env.env_len;
+       ep = env.envp + env.env_len;
 
     env.env_len++;
-    *nep++ = str;
-    *nep = NULL;
+    *ep++ = str;
+    *ep = NULL;
 }
 
 /*
@@ -475,6 +579,9 @@ rebuild_env(sudo_mode, noexec)
     env.env_size = 128;
     old_envp = env.envp;
     env.envp = emalloc2(env.env_size, sizeof(char *));
+#ifdef ENV_DEBUG
+    memset(env.envp, 0, env.env_size * sizeof(char *));
+#endif
     if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
        /* Pull in vars we want to keep from the old environment. */
        for (ep = environ; *ep; ep++) {
@@ -529,7 +636,7 @@ rebuild_env(sudo_mode, noexec)
                            SET(didvar, DID_USERNAME);
                        break;
                }
-               insert_env(*ep, FALSE, FALSE);
+               sudo_putenv(*ep, FALSE, FALSE);
            }
        }
        didvar |= didvar << 8;          /* convert DID_* to KEPT_* */
@@ -540,24 +647,24 @@ rebuild_env(sudo_mode, noexec)
         * on sudoers options).
         */
        if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
-           _sudo_setenv("HOME", runas_pw->pw_dir, ISSET(didvar, DID_HOME));
-           _sudo_setenv("SHELL", runas_pw->pw_shell, ISSET(didvar, DID_SHELL));
-           _sudo_setenv("LOGNAME", runas_pw->pw_name,
+           sudo_setenv("HOME", runas_pw->pw_dir, ISSET(didvar, DID_HOME));
+           sudo_setenv("SHELL", runas_pw->pw_shell, ISSET(didvar, DID_SHELL));
+           sudo_setenv("LOGNAME", runas_pw->pw_name,
                ISSET(didvar, DID_LOGNAME));
-           _sudo_setenv("USER", runas_pw->pw_name, ISSET(didvar, DID_USER));
-           _sudo_setenv("USERNAME", runas_pw->pw_name,
+           sudo_setenv("USER", runas_pw->pw_name, ISSET(didvar, DID_USER));
+           sudo_setenv("USERNAME", runas_pw->pw_name,
                ISSET(didvar, DID_USERNAME));
        } else {
            if (!ISSET(didvar, DID_HOME))
-               _sudo_setenv("HOME", user_dir, FALSE);
+               sudo_setenv("HOME", user_dir, FALSE);
            if (!ISSET(didvar, DID_SHELL))
-               _sudo_setenv("SHELL", sudo_user.pw->pw_shell, FALSE);
+               sudo_setenv("SHELL", sudo_user.pw->pw_shell, FALSE);
            if (!ISSET(didvar, DID_LOGNAME))
-               _sudo_setenv("LOGNAME", user_name, FALSE);
+               sudo_setenv("LOGNAME", user_name, FALSE);
            if (!ISSET(didvar, DID_USER))
-               _sudo_setenv("USER", user_name, FALSE);
+               sudo_setenv("USER", user_name, FALSE);
            if (!ISSET(didvar, DID_USERNAME))
-               _sudo_setenv("USERNAME", user_name, FALSE);
+               sudo_setenv("USERNAME", user_name, FALSE);
        }
     } else {
        /*
@@ -588,13 +695,13 @@ rebuild_env(sudo_mode, noexec)
                    SET(didvar, DID_PATH);
                else if (strncmp(*ep, "TERM=", 5) == 0)
                    SET(didvar, DID_TERM);
-               insert_env(*ep, FALSE, FALSE);
+               sudo_putenv(*ep, FALSE, FALSE);
            }
        }
     }
     /* Replace the PATH envariable with a secure one? */
     if (def_secure_path && !user_is_exempt()) {
-       _sudo_setenv("PATH", def_secure_path, TRUE);
+       sudo_setenv("PATH", def_secure_path, TRUE);
        SET(didvar, DID_PATH);
     }
 
@@ -602,11 +709,11 @@ rebuild_env(sudo_mode, noexec)
     /* XXX - not needed for MODE_LOGIN_SHELL */
     if (def_set_logname && runas_pw->pw_name) {
        if (!ISSET(didvar, KEPT_LOGNAME))
-           _sudo_setenv("LOGNAME", runas_pw->pw_name, TRUE);
+           sudo_setenv("LOGNAME", runas_pw->pw_name, TRUE);
        if (!ISSET(didvar, KEPT_USER))
-           _sudo_setenv("USER", runas_pw->pw_name, TRUE);
+           sudo_setenv("USER", runas_pw->pw_name, TRUE);
        if (!ISSET(didvar, KEPT_USERNAME))
-           _sudo_setenv("USERNAME", runas_pw->pw_name, TRUE);
+           sudo_setenv("USERNAME", runas_pw->pw_name, TRUE);
     }
 
     /* Set $HOME for `sudo -H'.  Only valid at PERM_FULL_RUNAS. */
@@ -615,14 +722,14 @@ rebuild_env(sudo_mode, noexec)
        if (ISSET(sudo_mode, MODE_RESET_HOME) ||
            (ISSET(sudo_mode, MODE_RUN) && (def_always_set_home ||
            (ISSET(sudo_mode, MODE_SHELL) && def_set_home))))
-           _sudo_setenv("HOME", runas_pw->pw_dir, TRUE);
+           sudo_setenv("HOME", runas_pw->pw_dir, TRUE);
     }
 
     /* Provide default values for $TERM and $PATH if they are not set. */
     if (!ISSET(didvar, DID_TERM))
-       insert_env("TERM=unknown", FALSE, FALSE);
+       sudo_putenv("TERM=unknown", FALSE, FALSE);
     if (!ISSET(didvar, DID_PATH))
-       _sudo_setenv("PATH", _PATH_DEFPATH, FALSE);
+       sudo_setenv("PATH", _PATH_DEFPATH, FALSE);
 
     /*
      * Preload a noexec file?  For a list of LD_PRELOAD-alikes, see
@@ -631,18 +738,18 @@ rebuild_env(sudo_mode, noexec)
      */
     if (noexec && def_noexec_file != NULL) {
 #if defined(__darwin__) || defined(__APPLE__)
-       _sudo_setenv("DYLD_INSERT_LIBRARIES", def_noexec_file, TRUE);
-       _sudo_setenv("DYLD_FORCE_FLAT_NAMESPACE", "", TRUE);
+       sudo_setenv("DYLD_INSERT_LIBRARIES", def_noexec_file, TRUE);
+       sudo_setenv("DYLD_FORCE_FLAT_NAMESPACE", "", TRUE);
 #else
 # if defined(__osf__) || defined(__sgi)
        easprintf(&cp, "%s:DEFAULT", def_noexec_file);
-       _sudo_setenv("_RLD_LIST", cp, TRUE);
+       sudo_setenv("_RLD_LIST", cp, TRUE);
        efree(cp);
 # else
 #  ifdef _AIX
-       _sudo_setenv("LDR_PRELOAD", def_noexec_file, TRUE);
+       sudo_setenv("LDR_PRELOAD", def_noexec_file, TRUE);
 #  else
-       _sudo_setenv("LD_PRELOAD", def_noexec_file, TRUE);
+       sudo_setenv("LD_PRELOAD", def_noexec_file, TRUE);
 #  endif /* _AIX */
 # endif /* __osf__ || __sgi */
 #endif /* __darwin__ || __APPLE__ */
@@ -650,22 +757,22 @@ rebuild_env(sudo_mode, noexec)
 
     /* Set PS1 if SUDO_PS1 is set. */
     if (ps1 != NULL)
-       insert_env(ps1, TRUE, FALSE);
+       sudo_putenv(ps1, TRUE, TRUE);
 
     /* Add the SUDO_COMMAND envariable (cmnd + args). */
     if (user_args) {
        easprintf(&cp, "%s %s", user_cmnd, user_args);
-       _sudo_setenv("SUDO_COMMAND", cp, TRUE);
+       sudo_setenv("SUDO_COMMAND", cp, TRUE);
        efree(cp);
     } else
-       _sudo_setenv("SUDO_COMMAND", user_cmnd, TRUE);
+       sudo_setenv("SUDO_COMMAND", user_cmnd, TRUE);
 
     /* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
-    _sudo_setenv("SUDO_USER", user_name, TRUE);
+    sudo_setenv("SUDO_USER", user_name, TRUE);
     snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_uid);
-    _sudo_setenv("SUDO_UID", idbuf, TRUE);
+    sudo_setenv("SUDO_UID", idbuf, TRUE);
     snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_gid);
-    _sudo_setenv("SUDO_GID", idbuf, TRUE);
+    sudo_setenv("SUDO_GID", idbuf, TRUE);
 
     /* Install new environment. */
     environ = env.envp;
@@ -681,13 +788,9 @@ insert_env_vars(env_vars)
     if (env_vars == NULL)
        return;
 
-    /* Make sure we are operating on the current environment. */
-    if (env.envp != environ)
-       sync_env();
-
     /* Add user-specified environment variables. */
     for (cur = env_vars; cur != NULL; cur = cur->next)
-       insert_env(cur->value, TRUE, TRUE);
+       putenv(cur->value);
 }
 
 /*
@@ -747,35 +850,59 @@ validate_env_vars(env_vars)
 
 /*
  * Read in /etc/environment ala AIX and Linux.
- * Lines are in the form of NAME=VALUE
+ * Lines may be in either of three formats:
+ *  NAME=VALUE
+ *  NAME="VALUE"
+ *  NAME='VALUE'
+ * with an optional "export" prefix so the shell can source the file.
  * Invalid lines, blank lines, or lines consisting solely of a comment
  * character are skipped.
  */
 void
-read_env_file(path, replace)
+read_env_file(path, overwrite)
     const char *path;
-    int replace;
+    int overwrite;
 {
     FILE *fp;
-    char *cp;
+    char *cp, *var, *val;
+    size_t var_len, val_len;
 
     if ((fp = fopen(path, "r")) == NULL)
        return;
 
-    /* Make sure we are operating on the current environment. */
-    if (env.envp != environ)
-       sync_env();
-
-    while ((cp = sudo_parseln(fp)) != NULL) {
+    while ((var = sudo_parseln(fp)) != NULL) {
        /* Skip blank or comment lines */
-       if (*cp == '\0')
+       if (*var == '\0')
            continue;
 
-       /* Must be of the form name=value */
-       if (strchr(cp, '=') == NULL)
+       /* Skip optional "export " */
+       if (strncmp(var, "export", 6) == 0 && isspace((unsigned char) var[6])) {
+           var += 7;
+           while (isspace((unsigned char) *var)) {
+               var++;
+           }
+       }
+
+       /* Must be of the form name=["']value['"] */
+       for (val = var; *val != '\0' && *val != '='; val++)
+           ;
+       if (var == val || *val != '=')
            continue;
+       var_len = (size_t)(val - var);
+       val_len = strlen(++val);
+
+       /* Strip leading and trailing single/double quotes */
+       if ((val[0] == '\'' || val[0] == '\"') && val[0] == val[val_len - 1]) {
+           val[val_len - 1] = '\0';
+           val++;
+           val_len -= 2;
+       }
+
+       cp = emalloc(var_len + 1 + val_len + 1);
+       memcpy(cp, var, var_len + 1); /* includes '=' */
+       memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */
 
-       insert_env(estrdup(cp), replace ? TRUE : -1, TRUE);
+       sudo_putenv(cp, TRUE, overwrite);
     }
     fclose(fp);
 }
index 9f176bd4064220a7c4309648c9b7a00e11c5e675..40cc86023a453c5eff07302687a203f10a305dad 100644 (file)
--- a/fileops.c
+++ b/fileops.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005,2007,2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -54,7 +54,7 @@
 #endif
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: fileops.c,v 1.16 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: fileops.c,v 1.19 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 /*
@@ -144,7 +144,7 @@ lock_file(fd, lockit)
     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;
+    func = (lockit == SUDO_LOCK) ? F_SETLKW : F_SETLK;
 
     return(fcntl(fd, func, &lock) == 0);
 #else
@@ -172,7 +172,7 @@ sudo_parseln(fp)
 
        /* Trim leading and trailing whitespace/newline */
        len = strlen(buf);
-       while (len > 0 && isspace(buf[len - 1]))
+       while (len > 0 && isspace((unsigned char)buf[len - 1]))
            buf[--len] = '\0';
        for (cp = buf; isblank(*cp); cp++)
            continue;
diff --git a/glob.c b/glob.c
index 46d883b085d86fd4d893241af63c4cd903403e2b..5df33b596a97fa2027774ca03a52eae015285631 100644 (file)
--- a/glob.c
+++ b/glob.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2008-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
@@ -814,7 +814,7 @@ match(name, pat, patend)
                                return(0);
                        if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
                                ++pat;
-                       while (((c = *pat++) & M_MASK) != M_END)
+                       while (((c = *pat++) & M_MASK) != M_END) {
                                if ((c & M_MASK) == M_CLASS) {
                                        int idx = *pat & M_MASK;
                                        if (idx < NCCLASSES &&
@@ -828,6 +828,7 @@ match(name, pat, patend)
                                        pat += 2;
                                } else if (c == k)
                                        ok = 1;
+                       }
                        if (ok == negate_range)
                                return(0);
                        break;
diff --git a/gram.c b/gram.c
index ed991a7d1d9f579b3f0d9dd31bbc0ee6cc9774a1..bcbf25e8e771e47f472f589990fd3844e5196fa6 100644 (file)
--- a/gram.c
+++ b/gram.c
@@ -73,7 +73,7 @@ static char yyrcsid[]
 #include "parse.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: gram.c,v 1.34 2008/11/09 14:15:36 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: gram.c,v 1.35 2009/04/18 23:25:08 millert Exp $";
 #endif /* lint */
 
 /*
@@ -798,15 +798,18 @@ init_parser(path, quiet)
 
     init_aliases();
 
+    init_lexer();
+
     efree(sudoers);
     sudoers = path ? estrdup(path) : NULL;
 
     parse_error = FALSE;
     errorlineno = -1;
+    errorfile = NULL;
     sudolineno = 1;
     verbose = !quiet;
 }
-#line 758 "y.tab.c"
+#line 761 "y.tab.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1546,7 +1549,7 @@ case 92:
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
-#line 1498 "y.tab.c"
+#line 1501 "y.tab.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
diff --git a/gram.y b/gram.y
index d39068d47d66bc26f1c34898e89725874cc517f9..9ab395bfbd45594d9ce3f38823cba1a6ef46e006 100644 (file)
--- a/gram.y
+++ b/gram.y
@@ -1,6 +1,6 @@
 %{
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -54,7 +54,7 @@
 #include "parse.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: gram.y,v 1.34 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: gram.y,v 1.36 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 /*
@@ -766,11 +766,14 @@ init_parser(path, quiet)
 
     init_aliases();
 
+    init_lexer();
+
     efree(sudoers);
     sudoers = path ? estrdup(path) : NULL;
 
     parse_error = FALSE;
     errorlineno = -1;
+    errorfile = NULL;
     sudolineno = 1;
     verbose = !quiet;
 }
index 27ca4382e61be90a7ad65eb53c340409903942c9..6272704c94a94f32efe99f6f360745b7508929a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -85,9 +85,13 @@ struct rtentry;
 #include "interfaces.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: interfaces.c,v 1.84 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: interfaces.c,v 1.87 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
+/* Minix apparently lacks IFF_LOOPBACK */
+#ifndef IFF_LOOPBACK
+# define IFF_LOOPBACK  0
+#endif
 
 #ifdef HAVE_GETIFADDRS
 
@@ -139,9 +143,13 @@ load_interfaces()
        switch(ifa->ifa_addr->sa_family) {
            case AF_INET:
                sin = (struct sockaddr_in *)ifa->ifa_addr;
+               if (sin == NULL)
+                   continue;
                memcpy(&interfaces[i].addr, &sin->sin_addr,
                    sizeof(struct in_addr));
                sin = (struct sockaddr_in *)ifa->ifa_netmask;
+               if (sin == NULL)
+                   continue;
                memcpy(&interfaces[i].netmask, &sin->sin_addr,
                    sizeof(struct in_addr));
                interfaces[i].family = AF_INET;
@@ -150,9 +158,13 @@ load_interfaces()
 #ifdef HAVE_IN6_ADDR
            case AF_INET6:
                sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+               if (sin6 == NULL)
+                   continue;
                memcpy(&interfaces[i].addr, &sin6->sin6_addr,
                    sizeof(struct in6_addr));
                sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
+               if (sin6 == NULL)
+                   continue;
                memcpy(&interfaces[i].netmask, &sin6->sin6_addr,
                    sizeof(struct in6_addr));
                interfaces[i].family = AF_INET6;
diff --git a/lbuf.c b/lbuf.c
index ef898eb7be3d13723bbf47fd6793760f7fa14f46..9e6bf0d10b000058d4500526c71e2be194a00761 100644 (file)
--- a/lbuf.c
+++ b/lbuf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
 #include <ctype.h>
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#else
+# ifdef HAVE_TERMIO_H
+#  include <termio.h>
+# endif
+#endif
 
 #include "sudo.h"
 #include "lbuf.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: lbuf.c,v 1.7 2008/12/09 20:55:49 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: lbuf.c,v 1.9 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 #if !defined(TIOCGSIZE) && defined(TIOCGWINSZ)
diff --git a/ldap.c b/ldap.c
index c778f3a0b54a30015906ae926756c57040593214..33e65067c163e123f9a74ec13ee66e00f714cbe0 100644 (file)
--- a/ldap.c
+++ b/ldap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2003-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * This code is derived from software contributed by Aaron Spangler.
  *
@@ -82,7 +82,7 @@
 #include "lbuf.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: ldap.c,v 1.100 2008/04/23 12:30:07 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: ldap.c,v 1.108 2009/05/29 13:43:12 millert Exp $";
 #endif /* lint */
 
 #ifndef LDAP_OPT_SUCCESS
@@ -386,10 +386,32 @@ sudo_ldap_init(ldp, host, port)
            ldap_conf.tls_keyfile ? ldap_conf.tls_keyfile : "NULL"), 2);
        rc = ldapssl_clientauth_init(ldap_conf.tls_certfile, NULL,
            ldap_conf.tls_keyfile != NULL, ldap_conf.tls_keyfile, NULL);
+       /*
+        * Mozilla-derived SDKs have a bug starting with version 5.0
+        * where the path can no longer be a file name and must be a dir.
+        */
        if (rc != LDAP_SUCCESS) {
-           warningx("unable to initialize SSL cert and key db: %s",
-               ldapssl_err2string(rc));
-           goto done;
+           char *cp;
+           if (ldap_conf.tls_certfile) {
+               cp = strrchr(ldap_conf.tls_certfile, '/');
+               if (cp != NULL && strncmp(cp + 1, "cert", 4) == 0)
+                   *cp = '\0';
+           }
+           if (ldap_conf.tls_keyfile) {
+               cp = strrchr(ldap_conf.tls_keyfile, '/');
+               if (cp != NULL && strncmp(cp + 1, "key", 3) == 0)
+                   *cp = '\0';
+           }
+           DPRINTF(("ldapssl_clientauth_init(%s, %s)",
+               ldap_conf.tls_certfile ? ldap_conf.tls_certfile : "NULL",
+               ldap_conf.tls_keyfile ? ldap_conf.tls_keyfile : "NULL"), 2);
+           rc = ldapssl_clientauth_init(ldap_conf.tls_certfile, NULL,
+               ldap_conf.tls_keyfile != NULL, ldap_conf.tls_keyfile, NULL);
+           if (rc != LDAP_SUCCESS) {
+               warningx("unable to initialize SSL cert and key db: %s",
+                   ldapssl_err2string(rc));
+               goto done;
+           }
        }
 
        DPRINTF(("ldapssl_init(%s, %d, 1)", host, port), 2);
@@ -1128,7 +1150,7 @@ sudo_ldap_display_defaults(nss, pw, lbuf)
        return(-1);
 
     rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
-       "cn=defaults", NULL, 0, NULL, NULL, NULL, -1, &result);
+       "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
     if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
        bv = ldap_get_values_len(ld, entry, "sudoOption");
        if (bv != NULL) {
@@ -1358,7 +1380,7 @@ sudo_ldap_display_privs(nss, pw, lbuf)
        filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
        DPRINTF(("ldap search '%s'", filt), 1);
        rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
-           NULL, 0, NULL, NULL, NULL, -1, &result);
+           NULL, 0, NULL, NULL, NULL, 0, &result);
        efree(filt);
        if (rc != LDAP_SUCCESS)
            continue;   /* no entries for this pass */
@@ -1412,7 +1434,7 @@ sudo_ldap_display_cmnd(nss, pw)
        filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
        DPRINTF(("ldap search '%s'", filt), 1);
        rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
-           NULL, 0, NULL, NULL, NULL, -1, &result);
+           NULL, 0, NULL, NULL, NULL, 0, &result);
        efree(filt);
        if (rc != LDAP_SUCCESS)
            continue;   /* no entries for this pass */
@@ -1583,7 +1605,7 @@ sudo_ldap_bind_s(ld)
                DPRINTF(("gss_krb5_ccache_name() failed: %d", status), 1);
            }
 #else
-           sudo_setenv("KRB5CCNAME", ldap_conf.krb5_ccname, TRUE);
+           setenv("KRB5CCNAME", ldap_conf.krb5_ccname, TRUE);
 #endif
        }
        rc = ldap_sasl_interactive_bind_s(ld, ldap_conf.binddn, "GSSAPI",
@@ -1594,9 +1616,9 @@ sudo_ldap_bind_s(ld)
                    DPRINTF(("gss_krb5_ccache_name() failed: %d", status), 1);
 #else
            if (old_ccname != NULL)
-               sudo_setenv("KRB5CCNAME", old_ccname, TRUE);
+               setenv("KRB5CCNAME", old_ccname, TRUE);
            else
-               sudo_unsetenv("KRB5CCNAME");
+               unsetenv("KRB5CCNAME");
 #endif
        }
        if (rc != LDAP_SUCCESS) {
@@ -1651,7 +1673,7 @@ sudo_ldap_open(nss)
     /* Prevent reading of user ldaprc and system defaults. */
     if (getenv("LDAPNOINIT") == NULL) {
        ldapnoinit = TRUE;
-       sudo_setenv("LDAPNOINIT", "1", TRUE);
+       setenv("LDAPNOINIT", "1", TRUE);
     }
 
     /* Connect to LDAP server */
@@ -1668,23 +1690,34 @@ sudo_ldap_open(nss)
     }
 
     if (ldapnoinit)
-       sudo_unsetenv("LDAPNOINIT");
+       unsetenv("LDAPNOINIT");
 
     /* Set LDAP options */
     if (sudo_ldap_set_options(ld) < 0)
        return(-1);
 
     if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
-#ifdef HAVE_LDAP_START_TLS_S
+#if defined(HAVE_LDAP_START_TLS_S)
        rc = ldap_start_tls_s(ld, NULL, NULL);
        if (rc != LDAP_SUCCESS) {
            warningx("ldap_start_tls_s(): %s", ldap_err2string(rc));
            return(-1);
        }
        DPRINTF(("ldap_start_tls_s() ok"), 1);
+#elif defined(HAVE_LDAP_SSL_CLIENT_INIT) && defined(HAVE_LDAP_START_TLS_S_NP)
+       if (ldap_ssl_client_init(NULL, NULL, 0, &rc) != LDAP_SUCCESS) {
+           warningx("ldap_ssl_client_init(): %s", ldap_err2string(rc));
+           return(-1);
+       }
+       rc = ldap_start_tls_s_np(ld, NULL);
+       if (rc != LDAP_SUCCESS) {
+           warningx("ldap_start_tls_s_np(): %s", ldap_err2string(rc));
+           return(-1);
+       }
+       DPRINTF(("ldap_start_tls_s_np() ok"), 1);
 #else
-       warningx("start_tls specified but LDAP libs do not support ldap_start_tls_s()");
-#endif /* HAVE_LDAP_START_TLS_S */
+       warningx("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()");
+#endif /* !HAVE_LDAP_START_TLS_S && !HAVE_LDAP_START_TLS_S_NP */
     }
 
     /* Actually connect */
@@ -1707,7 +1740,7 @@ sudo_ldap_setdefs(nss)
        return(-1);
 
     rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
-       "cn=defaults", NULL, 0, NULL, NULL, NULL, -1, &result);
+       "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
     if (rc == 0 && (entry = ldap_first_entry(ld, result))) {
        DPRINTF(("found:%s", ldap_get_dn(ld, entry)), 1);
        sudo_ldap_parse_options(ld, entry);
@@ -1748,7 +1781,7 @@ sudo_ldap_lookup(nss, ret, pwflag)
        for (matched = 0, do_netgr = 0; !matched && do_netgr < 2; do_netgr++) {
            filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
            rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
-               NULL, 0, NULL, NULL, NULL, -1, &result);
+               NULL, 0, NULL, NULL, NULL, 0, &result);
            efree(filt);
            if (rc != LDAP_SUCCESS)
                continue;
@@ -1819,7 +1852,7 @@ sudo_ldap_lookup(nss, ret, pwflag)
        filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
        DPRINTF(("ldap search '%s'", filt), 1);
        rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
-           NULL, 0, NULL, NULL, NULL, -1, &result);
+           NULL, 0, NULL, NULL, NULL, 0, &result);
        if (rc != LDAP_SUCCESS)
            DPRINTF(("nothing found for '%s'", filt), 1);
        efree(filt);
index b536305dfd0cada0f3ab2360f62d0ee9d99a2f9e..53288e502da9970fef2020d93b812a6484f08ac4 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994-1996, 1998-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1994-1996, 1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -58,7 +58,7 @@
 #include "sudo.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: logging.c,v 1.203 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: logging.c,v 1.205 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 static void do_syslog          __P((int, char *));
@@ -371,7 +371,7 @@ log_error(flags, fmt, va_alist)
 #endif
 
     /* Become root if we are not already to avoid user interference */
-    set_perms(PERM_ROOT);
+    set_perms(PERM_ROOT|PERM_NOEXIT);
 
     /* Expand printf-style format + args. */
     evasprintf(&message, fmt, ap);
@@ -555,10 +555,10 @@ send_mail(line)
                 * (so user cannot kill it) or as the user (for the paranoid).
                 */
 #ifndef NO_ROOT_MAILER
-               set_perms(PERM_ROOT);
+               set_perms(PERM_ROOT|PERM_NOEXIT);
                execve(mpath, argv, root_envp);
 #else
-               set_perms(PERM_FULL_USER);
+               set_perms(PERM_FULL_USER|PERM_NOEXIT);
                execv(mpath, argv);
 #endif /* NO_ROOT_MAILER */
                mysyslog(LOG_ERR, "cannot execute %s: %m", mpath);
index b3f49412ecc82088fb2404437afee4f020b033be..d65a8abcb6116c1764353f9a300361d939fa9be7 100644 (file)
--- a/logging.h
+++ b/logging.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2008
+ * Copyright (c) 1999-2005, 2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Sudo: logging.h,v 1.13 2008/11/09 14:13:12 millert Exp $
+ * $Sudo: logging.h,v 1.15 2009/05/25 12:02:41 millert Exp $
  */
 
 #ifndef _LOGGING_H
@@ -49,6 +49,8 @@
 # define MAXSYSLOGLEN          960
 #endif
 
+void audit_success             __P((char **));
+void audit_failure             __P((char **, char const * const, ...));
 void log_allowed               __P((int));
 void log_denial                        __P((int, int));
 void log_error                 __P((int flags, const char *fmt, ...))
diff --git a/match.c b/match.c
index b3b7f9a897feebd39620ee222c62ce1ed28ce973..fd60fdbd28edb54e0c9641247662d8d3fabe6603 100644 (file)
--- a/match.c
+++ b/match.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 #ifndef HAVE_EXTENDED_GLOB
 # include "emul/glob.h"
 #endif /* HAVE_EXTENDED_GLOB */
+#ifdef USING_NONUNIX_GROUPS
+# include "nonunix.h"
+#endif /* USING_NONUNIX_GROUPS */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: match.c,v 1.38 2008/11/02 14:35:37 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: match.c,v 1.46 2009/05/27 00:49:07 millert Exp $";
 #endif /* lint */
 
 static struct member_list empty;
 
 static int command_matches_dir __P((char *, size_t));
+static int command_matches_glob __P((char *, char *));
+static int command_matches_fnmatch __P((char *, char *));
+static int command_matches_normal __P((char *, char *));
 
 /*
  * Returns TRUE if string 's' contains meta characters.
@@ -130,7 +136,7 @@ _userlist_matches(pw, list)
                    matched = !m->negated;
                break;
            case ALIAS:
-               if ((a = find_alias(m->name, USERALIAS)) != NULL) {
+               if ((a = alias_find(m->name, USERALIAS)) != NULL) {
                    rval = _userlist_matches(pw, &a->members);
                    if (rval != UNSPEC)
                        matched = m->negated ? !rval : rval;
@@ -171,9 +177,13 @@ _runaslist_matches(user_list, group_list)
     struct alias *a;
     int rval, matched = UNSPEC;
 
-    /* Deny if user specified a group but there is no group in sudoers */
-    if (runas_gr != NULL && tq_empty(group_list))
-       return(DENY);
+    if (runas_gr != NULL) {
+       if (tq_empty(group_list))
+           return(DENY); /* group was specified but none in sudoers */
+       if (runas_pw != NULL && strcmp(runas_pw->pw_name, user_name) &&
+           tq_empty(user_list))
+           return(DENY); /* user was specified but none in sudoers */
+    }
 
     if (tq_empty(user_list) && tq_empty(group_list))
        return(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
@@ -193,7 +203,7 @@ _runaslist_matches(user_list, group_list)
                        matched = !m->negated;
                    break;
                case ALIAS:
-                   if ((a = find_alias(m->name, RUNASALIAS)) != NULL) {
+                   if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
                        rval = _runaslist_matches(&a->members, &empty);
                        if (rval != UNSPEC)
                            matched = m->negated ? !rval : rval;
@@ -217,7 +227,7 @@ _runaslist_matches(user_list, group_list)
                    matched = !m->negated;
                    break;
                case ALIAS:
-                   if ((a = find_alias(m->name, RUNASALIAS)) != NULL) {
+                   if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
                        rval = _runaslist_matches(&a->members, &empty);
                        if (rval != UNSPEC)
                            matched = m->negated ? !rval : rval;
@@ -273,7 +283,7 @@ _hostlist_matches(list)
                    matched = !m->negated;
                break;
            case ALIAS:
-               if ((a = find_alias(m->name, HOSTALIAS)) != NULL) {
+               if ((a = alias_find(m->name, HOSTALIAS)) != NULL) {
                    rval = _hostlist_matches(&a->members);
                    if (rval != UNSPEC)
                        matched = m->negated ? !rval : rval;
@@ -346,7 +356,7 @@ cmnd_matches(m)
            break;
        case ALIAS:
            alias_seqno++;
-           if ((a = find_alias(m->name, CMNDALIAS)) != NULL) {
+           if ((a = alias_find(m->name, CMNDALIAS)) != NULL) {
                rval = _cmndlist_matches(&a->members);
                if (rval != UNSPEC)
                    matched = m->negated ? !rval : rval;
@@ -370,11 +380,6 @@ command_matches(sudoers_cmnd, sudoers_args)
     char *sudoers_cmnd;
     char *sudoers_args;
 {
-    struct stat sudoers_stat;
-    char **ap, *base, *cp;
-    glob_t gl;
-    size_t dlen;
-
     /* Check for pseudo-commands */
     if (strchr(user_cmnd, '/') == NULL) {
        /*
@@ -396,110 +401,163 @@ command_matches(sudoers_cmnd, sudoers_args)
        } else
            return(FALSE);
     }
-    dlen = strlen(sudoers_cmnd);
 
-    /*
-     * If sudoers_cmnd has meta characters in it, we may need to
-     * use glob(3) and fnmatch(3) to do the matching.
-     */
     if (has_meta(sudoers_cmnd)) {
        /*
-        * First check to see if we can avoid the call to glob(3).
-        * Short circuit if there are no meta chars in the command itself
-        * and user_base and basename(sudoers_cmnd) don't match.
-        */
-       if (sudoers_cmnd[dlen - 1] != '/') {
-           if ((base = strrchr(sudoers_cmnd, '/')) != NULL) {
-               base++;
-               if (!has_meta(base) && strcmp(user_base, base) != 0)
-                   return(FALSE);
-           }
-       }
-       /*
-        * Return true if we find a match in the glob(3) results 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 sudoers_cmnd has meta characters in it, we need to
+        * use glob(3) and/or fnmatch(3) to do the matching.
         */
-#define GLOB_FLAGS     (GLOB_NOSORT | GLOB_MARK | GLOB_BRACE | GLOB_TILDE)
-       if (glob(sudoers_cmnd, GLOB_FLAGS, NULL, &gl) != 0) {
-           globfree(&gl);
-           return(FALSE);
-       }
-       /* For each glob match, compare basename, st_dev and st_ino. */
-       for (ap = gl.gl_pathv; (cp = *ap) != NULL; ap++) {
-           /* If it ends in '/' it is a directory spec. */
-           dlen = strlen(cp);
-           if (cp[dlen - 1] == '/') {
-               if (command_matches_dir(cp, dlen))
-                   return(TRUE);
-               continue;
-           }
+       if (def_fast_glob)
+           return(command_matches_fnmatch(sudoers_cmnd, sudoers_args));
+       return(command_matches_glob(sudoers_cmnd, sudoers_args));
+    }
+    return(command_matches_normal(sudoers_cmnd, sudoers_args));
+}
 
-           /* Only proceed if user_base and basename(cp) match */
-           if ((base = strrchr(cp, '/')) != NULL)
-               base++;
-           else
-               base = cp;
-           if (strcmp(user_base, base) != 0 ||
-               stat(cp, &sudoers_stat) == -1)
-               continue;
-           if (user_stat == NULL ||
-               (user_stat->st_dev == sudoers_stat.st_dev &&
-               user_stat->st_ino == sudoers_stat.st_ino)) {
-               efree(safe_cmnd);
-               safe_cmnd = estrdup(cp);
-               break;
-           }
-       }
-       globfree(&gl);
-       if (cp == NULL)
-           return(FALSE);
+static int
+command_matches_fnmatch(sudoers_cmnd, sudoers_args)
+    char *sudoers_cmnd;
+    char *sudoers_args;
+{
+    /*
+     * 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(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0)
+       return(FALSE);
+    if (!sudoers_args ||
+       (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
+       (sudoers_args &&
+        fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
+       if (safe_cmnd)
+           free(safe_cmnd);
+       safe_cmnd = estrdup(user_cmnd);
+       return(TRUE);
+    } else
+       return(FALSE);
+}
 
-       if (!sudoers_args ||
-           (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
-           (sudoers_args &&
-            fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
-           efree(safe_cmnd);
-           safe_cmnd = estrdup(user_cmnd);
-           return(TRUE);
+static int
+command_matches_glob(sudoers_cmnd, sudoers_args)
+    char *sudoers_cmnd;
+    char *sudoers_args;
+{
+    struct stat sudoers_stat;
+    size_t dlen;
+    char **ap, *base, *cp;
+    glob_t gl;
+
+    /*
+     * First check to see if we can avoid the call to glob(3).
+     * Short circuit if there are no meta chars in the command itself
+     * and user_base and basename(sudoers_cmnd) don't match.
+     */
+    dlen = strlen(sudoers_cmnd);
+    if (sudoers_cmnd[dlen - 1] != '/') {
+       if ((base = strrchr(sudoers_cmnd, '/')) != NULL) {
+           base++;
+           if (!has_meta(base) && strcmp(user_base, base) != 0)
+               return(FALSE);
        }
+    }
+    /*
+     * Return true if we find a match in the glob(3) results 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.
+     */
+#define GLOB_FLAGS     (GLOB_NOSORT | GLOB_MARK | GLOB_BRACE | GLOB_TILDE)
+    if (glob(sudoers_cmnd, GLOB_FLAGS, NULL, &gl) != 0) {
+       globfree(&gl);
        return(FALSE);
-    } else {
+    }
+    /* For each glob match, compare basename, st_dev and st_ino. */
+    for (ap = gl.gl_pathv; (cp = *ap) != NULL; ap++) {
        /* If it ends in '/' it is a directory spec. */
-       if (sudoers_cmnd[dlen - 1] == '/')
-           return(command_matches_dir(sudoers_cmnd, dlen));
+       dlen = strlen(cp);
+       if (cp[dlen - 1] == '/') {
+           if (command_matches_dir(cp, dlen))
+               return(TRUE);
+           continue;
+       }
 
-       /* Only proceed if user_base and basename(sudoers_cmnd) match */
-       if ((base = strrchr(sudoers_cmnd, '/')) == NULL)
-           base = sudoers_cmnd;
-       else
+       /* Only proceed if user_base and basename(cp) match */
+       if ((base = strrchr(cp, '/')) != NULL)
            base++;
+       else
+           base = cp;
        if (strcmp(user_base, base) != 0 ||
-           stat(sudoers_cmnd, &sudoers_stat) == -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 (user_stat != NULL &&
-           (user_stat->st_dev != sudoers_stat.st_dev ||
-           user_stat->st_ino != sudoers_stat.st_ino))
-           return(FALSE);
-       if (!sudoers_args ||
-           (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
-           (sudoers_args &&
-            fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
+           stat(cp, &sudoers_stat) == -1)
+           continue;
+       if (user_stat == NULL ||
+           (user_stat->st_dev == sudoers_stat.st_dev &&
+           user_stat->st_ino == sudoers_stat.st_ino)) {
            efree(safe_cmnd);
-           safe_cmnd = estrdup(sudoers_cmnd);
-           return(TRUE);
+           safe_cmnd = estrdup(cp);
+           break;
        }
+    }
+    globfree(&gl);
+    if (cp == NULL)
        return(FALSE);
+
+    if (!sudoers_args ||
+       (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
+       (sudoers_args &&
+        fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
+       efree(safe_cmnd);
+       safe_cmnd = estrdup(user_cmnd);
+       return(TRUE);
     }
+    return(FALSE);
+}
+
+static int
+command_matches_normal(sudoers_cmnd, sudoers_args)
+    char *sudoers_cmnd;
+    char *sudoers_args;
+{
+    struct stat sudoers_stat;
+    char *base;
+    size_t dlen;
+
+    /* If it ends in '/' it is a directory spec. */
+    dlen = strlen(sudoers_cmnd);
+    if (sudoers_cmnd[dlen - 1] == '/')
+       return(command_matches_dir(sudoers_cmnd, dlen));
+
+    /* Only proceed if user_base and basename(sudoers_cmnd) match */
+    if ((base = strrchr(sudoers_cmnd, '/')) == NULL)
+       base = sudoers_cmnd;
+    else
+       base++;
+    if (strcmp(user_base, base) != 0 ||
+       stat(sudoers_cmnd, &sudoers_stat) == -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 (user_stat != NULL &&
+       (user_stat->st_dev != sudoers_stat.st_dev ||
+       user_stat->st_ino != sudoers_stat.st_ino))
+       return(FALSE);
+    if (!sudoers_args ||
+       (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) ||
+       (sudoers_args &&
+        fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) {
+       efree(safe_cmnd);
+       safe_cmnd = estrdup(sudoers_cmnd);
+       return(TRUE);
+    }
+    return(FALSE);
 }
 
 /*
@@ -754,7 +812,6 @@ group_matches(sudoers_group, gr)
 /*
  *  Returns TRUE if the given user belongs to the named group,
  *  else returns FALSE.
- *  XXX - reduce the number of group lookups
  */
 int
 usergr_matches(group, user, pw)
@@ -762,7 +819,7 @@ usergr_matches(group, user, pw)
     char *user;
     struct passwd *pw;
 {
-    struct group *grp;
+    struct group *grp = NULL;
     char **cur;
     int i;
 
@@ -770,14 +827,18 @@ usergr_matches(group, user, pw)
     if (*group++ != '%')
        return(FALSE);
 
+#ifdef USING_NONUNIX_GROUPS
+    if (*group == ':')
+       return(sudo_nonunix_groupcheck(++group, user, pw));   
+#endif /* USING_NONUNIX_GROUPS */
+
     /* look up user's primary gid in the passwd file */
     if (pw == NULL && (pw = sudo_getpwnam(user)) == NULL)
-       return(FALSE);
-
-    if ((grp = sudo_getgrnam(group)) == NULL)
-       return(FALSE);
+       goto try_supplementary;
 
     /* check against user's primary (passwd file) gid */
+    if ((grp = sudo_getgrnam(group)) == NULL)
+       goto try_supplementary;
     if (grp->gr_gid == pw->pw_gid)
        return(TRUE);
 
@@ -790,12 +851,21 @@ usergr_matches(group, user, pw)
            if (grp->gr_gid == user_groups[i])
                return(TRUE);
     }
-    if (grp->gr_mem != NULL) {
+
+try_supplementary:
+    if (grp != NULL && grp->gr_mem != NULL) {
        for (cur = grp->gr_mem; *cur; cur++)
            if (strcmp(*cur, user) == 0)
                return(TRUE);
     }
 
+#ifdef USING_NONUNIX_GROUPS
+    /* not a Unix group, could be an AD group */
+    if (sudo_nonunix_groupcheck_available() &&
+       sudo_nonunix_groupcheck(group, user, pw))
+       return(TRUE);
+#endif /* USING_NONUNIX_GROUPS */
+
     return(FALSE);
 }
 
diff --git a/nonunix.h b/nonunix.h
new file mode 100644 (file)
index 0000000..09de9d2
--- /dev/null
+++ b/nonunix.h
@@ -0,0 +1,46 @@
+/*
+ * (c) 2006 Quest Software, Inc.  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 Quest Software, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. 
+ */
+
+#ifndef _NONUNIX_H
+#define _NONUNIX_H
+
+void
+sudo_nonunix_groupcheck_init(void);
+
+void
+sudo_nonunix_groupcheck_cleanup(void);
+
+int
+sudo_nonunix_groupcheck( const char* group, const char* user, const struct passwd* pwd );
+
+int
+sudo_nonunix_groupcheck_available(void);
+
+#endif /* _NONUNIX_H */
diff --git a/parse.c b/parse.c
index ef4a4959945abf4864f2a759994402e508d2d0d6..eeb0511b9fc66feffb113d5e0ac0ccfe67970c8b 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005, 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -49,7 +49,7 @@
 #include <gram.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: parse.c,v 1.238 2008/12/09 13:49:55 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: parse.c,v 1.242 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 /* Characters that must be quoted in sudoers */
@@ -89,7 +89,7 @@ sudo_file_open(nss)
 {
     if (def_ignore_local_sudoers)
        return(-1);
-    nss->handle = open_sudoers(_PATH_SUDOERS, NULL);
+    nss->handle = open_sudoers(_PATH_SUDOERS, FALSE, NULL);
     return(nss->handle ? 0 : -1);
 }
 
@@ -328,8 +328,10 @@ sudo_file_display_priv_short(pw, us, lbuf)
                    print_member(lbuf, m->name, m->type, m->negated,
                        RUNASALIAS);
                }
-           } else {
+           } else if (tq_empty(&cs->runasgrouplist)) {
                lbuf_append(lbuf, def_runas_default, NULL);
+           } else {
+               lbuf_append(lbuf, pw->pw_name, NULL);
            }
            if (!tq_empty(&cs->runasgrouplist)) {
                lbuf_append(lbuf, " : ", NULL);
@@ -377,8 +379,10 @@ sudo_file_display_priv_long(pw, us, lbuf)
                    print_member(lbuf, m->name, m->type, m->negated,
                        RUNASALIAS);
                }
-           } else {
+           } else if (tq_empty(&cs->runasgrouplist)) {
                lbuf_append(lbuf, def_runas_default, NULL);
+           } else {
+               lbuf_append(lbuf, pw->pw_name, NULL);
            }
            lbuf_print(lbuf);
            if (!tq_empty(&cs->runasgrouplist)) {
@@ -639,7 +643,7 @@ _print_member(lbuf, name, type, negated, alias_type)
            }
            break;
        case ALIAS:
-           if ((a = find_alias(name, alias_type)) != NULL) {
+           if ((a = alias_find(name, alias_type)) != NULL) {
                tq_foreach_fwd(&a->members, m) {
                    if (m != tq_first(&a->members))
                        lbuf_append(lbuf, ", ", NULL);
diff --git a/parse.h b/parse.h
index 16388582565b946aa01669b83339d723ccee5e01..991856fd58150ebd91ef690ada29c02684d0b791 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2000, 2004, 2007-2008
+ * Copyright (c) 1996, 1998-2000, 2004, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Sudo: parse.h,v 1.44 2008/11/09 14:13:12 millert Exp $
+ * $Sudo: parse.h,v 1.49 2009/05/25 12:02:41 millert Exp $
  */
 
 #ifndef _SUDO_PARSE_H
@@ -168,7 +168,6 @@ extern unsigned int alias_seqno;
  */
 char *alias_add                __P((char *, int, struct member *));
 int addr_matches       __P((char *));
-int alias_remove       __P((char *, int));
 int cmnd_matches       __P((struct member *));
 int cmndlist_matches   __P((struct member_list *));
 int command_matches    __P((char *, char *));
@@ -181,9 +180,13 @@ int userlist_matches       __P((struct passwd *, struct member_list *));
 int usergr_matches     __P((char *, char *, struct passwd *));
 int userpw_matches     __P((char *, char *, struct passwd *));
 int group_matches      __P((char *, struct group *));
-struct alias *find_alias __P((char *, int));
+struct alias *alias_find __P((char *, int));
+struct alias *alias_remove __P((char *, int));
+void alias_free                __P((void *));
 void alias_apply       __P((int (*)(void *, void *), void *));
 void init_aliases      __P((void));
+void init_lexer                __P((void));
 void init_parser       __P((char *, int));
+int alias_compare      __P((const void *, const void *));
 
 #endif /* _SUDO_PARSE_H */
index 430f96a99ab7629b7b934e76885378d02844c882..be46f904b17f5611a2de6cb92ce83ac491fcba7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998, 1999, 2001, 2004
+ * Copyright (c) 1996, 1998, 1999, 2001, 2004, 2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>.
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  *
- * $Sudo: pathnames.h.in,v 1.63 2008/11/10 13:07:38 millert Exp $
+ * $Sudo: pathnames.h.in,v 1.65 2009/05/25 12:02:41 millert Exp $
  */
 
 /*
 #ifndef _PATH_NSSWITCH_CONF
 #undef _PATH_NSSWITCH_CONF
 #endif /* _PATH_NSSWITCH_CONF */
+
+#ifndef _PATH_NETSVC_CONF
+#undef _PATH_NETSVC_CONF
+#endif /* _PATH_NETSVC_CONF */
index 2fd0988008ac4799159c5b9f69fce74b4afbe226..bbc3174dddba5c795cb2d6ca50042abcf80bc3d3 100644 (file)
--- a/pwutil.c
+++ b/pwutil.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -53,7 +53,7 @@
 #include "redblack.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: pwutil.c,v 1.21 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: pwutil.c,v 1.23 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 #ifdef MYPW
@@ -207,18 +207,16 @@ sudo_getpwuid(uid)
        if (pw->pw_passwd != NULL)
            zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd));
        pw->pw_passwd = cp;
-
-       if (rbinsert(pwcache_byname, (void *) pw) != NULL)
-           errorx(1, "unable to cache user name, already exists");
        if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
-           errorx(1, "unable to cache uid, already exists");
+           errorx(1, "unable to cache uid %lu (%s), already exists",
+               uid, pw->pw_name);
        return(pw);
     } else {
        pw = emalloc(sizeof(*pw));
        zero_bytes(pw, sizeof(*pw));
        pw->pw_uid = uid;
        if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
-           errorx(1, "unable to cache uid, already exists");
+           errorx(1, "unable to cache uid %lu, already exists", uid);
        return(NULL);
     }
 }
@@ -250,11 +248,8 @@ sudo_getpwnam(name)
        if (pw->pw_passwd != NULL)
            zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd));
        pw->pw_passwd = cp;
-
        if (rbinsert(pwcache_byname, (void *) pw) != NULL)
-           errorx(1, "unable to cache user name, already exists");
-       if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
-           errorx(1, "unable to cache uid, already exists");
+           errorx(1, "unable to cache user %s, already exists", name);
        return(pw);
     } else {
        len = strlen(name) + 1;
@@ -266,7 +261,7 @@ sudo_getpwnam(name)
        pw->pw_name = cp;
        pw->pw_uid = (uid_t) -1;
        if (rbinsert(pwcache_byname, (void *) pw) != NULL)
-           errorx(1, "unable to cache user name, already exists");
+           errorx(1, "unable to cache user %s, already exists", name);
        return(NULL);
     }
 }
@@ -487,17 +482,16 @@ sudo_getgrgid(gid)
      */
     if ((gr = getgrgid(gid)) != NULL) {
        gr = sudo_grdup(gr);
-       if (rbinsert(grcache_byname, (void *) gr) != NULL)
-           errorx(1, "unable to cache group name, already exists");
        if (rbinsert(grcache_bygid, (void *) gr) != NULL)
-           errorx(1, "unable to cache gid, already exists");
+           errorx(1, "unable to cache gid %lu (%s), already exists",
+               gid, gr->gr_name);
        return(gr);
     } else {
        gr = emalloc(sizeof(*gr));
        zero_bytes(gr, sizeof(*gr));
        gr->gr_gid = gid;
        if (rbinsert(grcache_bygid, (void *) gr) != NULL)
-           errorx(1, "unable to cache gid, already exists");
+           errorx(1, "unable to cache gid %lu, already exists, gid");
        return(NULL);
     }
 }
@@ -525,9 +519,7 @@ sudo_getgrnam(name)
     if ((gr = getgrnam(name)) != NULL) {
        gr = sudo_grdup(gr);
        if (rbinsert(grcache_byname, (void *) gr) != NULL)
-           errorx(1, "unable to cache group name, already exists");
-       if (rbinsert(grcache_bygid, (void *) gr) != NULL)
-           errorx(1, "unable to cache gid, already exists");
+           errorx(1, "unable to cache group %s, already exists", name);
        return(gr);
     } else {
        len = strlen(name) + 1;
@@ -539,7 +531,7 @@ sudo_getgrnam(name)
        gr->gr_name = cp;
        gr->gr_gid = (gid_t) -1;
        if (rbinsert(grcache_byname, (void *) gr) != NULL)
-           errorx(1, "unable to cache group name, already exists");
+           errorx(1, "unable to cache group %s, already exists", name);
        return(NULL);
     }
 }
index 555e9385f30bbc33e7d7d55ba00e87e0e89b48cc..ac8ea2d2136f0f0c5b20be2a0e622ca787b92f77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2007,2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -58,7 +58,7 @@
 #include "redblack.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: redblack.c,v 1.10 2008/11/22 15:01:25 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: redblack.c,v 1.12 2009/06/29 13:36:20 millert Exp $";
 #endif /* lint */
 
 static void rbrepair           __P((struct rbtree *, struct rbnode *));
@@ -77,10 +77,11 @@ static void _rbdestroy              __P((struct rbtree *, struct rbnode *,
  * In addition to the ordinary requirements imposed on binary search
  * trees, we make the following additional requirements of any valid
  * red-black tree:
- *  1) The root is black.
- *  2) All leaves are black.
- *  3) Both children of each red node are black.
- *  4) The paths from each leaf up to the root each contain the same
+ *  1) Every node is either red or black.
+ *  2) The root is black.
+ *  3) All leaves are black.
+ *  4) Both children of each red node are black.
+ *  5) The paths from each leaf up to the root each contain the same
  *     number of black nodes.
  */
 
@@ -372,8 +373,8 @@ rbdestroy(tree, destroy)
  * Delete node 'z' from the tree and return its data pointer.
  */
 void *rbdelete(tree, z)
-    struct rbtreetree;
-    struct rbnodez;
+    struct rbtree *tree;
+    struct rbnode *z;
 {
     struct rbnode *x, *y;
     void *data = z->data;
@@ -421,7 +422,7 @@ rbrepair(tree, node)
 {
     struct rbnode *sibling;
 
-    while (node->color == black) {
+    while (node->color == black && node != rbroot(tree)) {
        if (node == node->parent->left) {
            sibling = node->parent->right;
            if (sibling->color == red) {
@@ -444,7 +445,7 @@ rbrepair(tree, node)
                node->parent->color = black;
                sibling->right->color = black;
                rotate_left(tree, node->parent);
-               break;
+               node = rbroot(tree); /* exit loop */
            }
        } else { /* if (node == node->parent->right) */
            sibling = node->parent->left;
@@ -468,8 +469,9 @@ rbrepair(tree, node)
                node->parent->color = black;
                sibling->left->color = black;
                rotate_right(tree, node->parent);
-               break;
+               node = rbroot(tree); /* exit loop */
            }
        }
     }
+    node->color = black;
 }
index bc88a844de35233e3bc434687bd9c4ce8f047c8b..4417330f976ad8b833350048a417ca6428413fb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994-1996,1998-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1994-1996,1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -52,7 +52,7 @@
 #include "sudo.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: set_perms.c,v 1.44 2008/03/06 17:19:56 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: set_perms.c,v 1.49 2009/06/25 12:44:33 millert Exp $";
 #endif /* lint */
 
 #ifdef __TANDEM
@@ -77,14 +77,18 @@ static int current_perm = -1;
  * We only flip the effective gid since it only changes for PERM_SUDOERS.
  * This version of set_perms() works fine with the "stay_setuid" option.
  */
-void
+int
 set_perms(perm)
     int perm;
 {
     const char *errstr;
+    int noexit;
+
+    noexit = ISSET(perm, PERM_NOEXIT);
+    CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return;
+       return(1);
 
     switch (perm) {
        case PERM_ROOT:
@@ -169,10 +173,13 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return;
+    return(1);
 bad:
-    errorx(1, "%s: %s", errstr,
+    warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
+    if (noexit)
+       return(0);
+    exit(1);
 }
 
 #else
@@ -184,14 +191,18 @@ bad:
  * we are headed for an exec().
  * This version of set_perms() works fine with the "stay_setuid" option.
  */
-void
+int
 set_perms(perm)
     int perm;
 {
     const char *errstr;
+    int noexit;
+
+    noexit = ISSET(perm, PERM_NOEXIT);
+    CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return;
+       return(1);
 
     switch (perm) {
        case PERM_ROOT:
@@ -279,10 +290,13 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return;
+    return(1);
 bad:
-    errorx(1, "%s: %s", errstr,
+    warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
+    if (noexit)
+       return(0);
+    exit(1);
 }
 
 # else /* !HAVE_SETRESUID && !HAVE_SETREUID */
@@ -292,14 +306,18 @@ bad:
  * Set real and effective uids and gids based on perm.
  * NOTE: does not support the "stay_setuid" option.
  */
-void
+int
 set_perms(perm)
     int perm;
 {
     const char *errstr;
+    int noexit;
+
+    noexit = ISSET(perm, PERM_NOEXIT);
+    CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return;
+       return(1);
 
     /*
      * Since we only have setuid() and seteuid() and semantics
@@ -391,10 +409,13 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return;
+    return(1);
 bad:
-    errorx(1, "%s: %s", errstr,
+    warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
+    if (noexit)
+       return(0);
+    exit(1);
 }
 
 # else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
@@ -404,14 +425,18 @@ bad:
  * NOTE: does not support the "stay_setuid" or timestampowner options.
  *       Also, SUDOERS_UID and SUDOERS_GID are not used.
  */
-void
+int
 set_perms(perm)
     int perm;
 {
     const char *errstr;
+    int noexit;
+
+    noexit = ISSET(perm, PERM_NOEXIT);
+    CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return;
+       return(1);
 
     switch (perm) {
        case PERM_ROOT:
@@ -448,10 +473,13 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return;
+    return(1);
 bad:
-    errorx(1, "%s: %s", errstr,
+    warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
+    if (noexit)
+       return(0);
+    exit(1);
 }
 #  endif /* HAVE_SETEUID */
 # endif /* HAVE_SETREUID */
@@ -462,7 +490,9 @@ static void
 runas_setgroups()
 {
     static int ngroups = -1;
+#ifdef HAVE_GETGROUPS
     static GETGROUPS_T *groups;
+#endif
     struct passwd *pw;
 
     if (def_preserve_groups)
@@ -475,14 +505,16 @@ runas_setgroups()
        pw = runas_pw ? runas_pw : sudo_user.pw;
        if (initgroups(pw->pw_name, pw->pw_gid) < 0)
            log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
-       if ((ngroups = getgroups(0, NULL)) < 0)
-           log_error(USE_ERRNO|MSG_ONLY, "can't get runas ngroups");
-       groups = emalloc2(ngroups, sizeof(GETGROUPS_T));
-       if (getgroups(ngroups, groups) < 0)
-           log_error(USE_ERRNO|MSG_ONLY, "can't get runas group vector");
+#ifdef HAVE_GETGROUPS
+       if ((ngroups = getgroups(0, NULL)) > 0) {
+           groups = emalloc2(ngroups, sizeof(GETGROUPS_T));
+           if (getgroups(ngroups, groups) < 0)
+               log_error(USE_ERRNO|MSG_ONLY, "can't get runas group vector");
+       }
     } else {
        if (setgroups(ngroups, groups) < 0)
            log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
+#endif /* HAVE_GETGROUPS */
     }
 }
 
@@ -530,13 +562,9 @@ runas_setup()
 #ifdef HAVE_LOGIN_CAP_H
        if (def_use_loginclass) {
            /*
-             * We only use setusercontext() set the nice value and rlimits.
+             * We only use setusercontext() to set the nice value and rlimits.
             */
            flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
-           if (!def_preserve_groups)
-               SET(flags, LOGIN_SETGROUP);
-           else if (setgid(gid))
-               warning("cannot set gid to runas gid");
            if (setusercontext(lc, runas_pw, runas_pw->pw_uid, flags)) {
                if (runas_pw->pw_uid != ROOT_UID)
                    error(1, "unable to set user context");
@@ -545,11 +573,15 @@ runas_setup()
            }
        }
 #endif /* HAVE_LOGIN_CAP_H */
-       if (setgid(gid))
-           warning("cannot set gid to runas gid");
        /*
         * Initialize group vector
         */
        runas_setgroups();
+#ifdef HAVE_SETEUID
+       if (setegid(gid))
+           warning("cannot set egid to runas gid");
+#endif
+       if (setgid(gid))
+           warning("cannot set gid to runas gid");
     }
 }
diff --git a/sudo.c b/sudo.c
index 7191ee14a68ecfb5f57d02bf3d72557cd4a06856..66a1121dcf13ce89d4112b95b3977f570a5a16c2 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1993-1996, 1998-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1993-1996, 1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 # include <selinux/selinux.h>
 #endif
 
+#include <sudo_usage.h>
 #include "sudo.h"
-#include "sudo_usage.h"
 #include "lbuf.h"
 #include "interfaces.h"
-#include "version.h"
+
+#ifdef USING_NONUNIX_GROUPS
+# include "nonunix.h"
+#endif
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: sudo.c,v 1.500 2008/11/18 15:57:09 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: sudo.c,v 1.517 2009/05/27 00:49:07 millert Exp $";
 #endif /* lint */
 
 /*
@@ -231,7 +234,7 @@ main(argc, argv, envp)
        user_cmnd = "shell";
     else if (ISSET(sudo_mode, MODE_EDIT))
        user_cmnd = "sudoedit";
-    else
+    else {
        switch (sudo_mode) {
            case MODE_VERSION:
                show_version();
@@ -240,6 +243,7 @@ main(argc, argv, envp)
                usage(0);
                break;
            case MODE_VALIDATE:
+           case MODE_VALIDATE|MODE_INVALIDATE:
                user_cmnd = "validate";
                pwflag = I_VERIFYPW;
                break;
@@ -253,13 +257,16 @@ main(argc, argv, envp)
                exit(0);
                break;
            case MODE_LIST:
+           case MODE_LIST|MODE_INVALIDATE:
                user_cmnd = "list";
                pwflag = I_LISTPW;
                break;
            case MODE_CHECK:
+           case MODE_CHECK|MODE_INVALIDATE:
                pwflag = I_LISTPW;
                break;
        }
+    }
 
     /* Must have a command to run... */
     if (user_cmnd == NULL && NewArgc == 0)
@@ -267,6 +274,10 @@ main(argc, argv, envp)
 
     init_vars(sudo_mode, envp);                /* XXX - move this later? */
 
+#ifdef USING_NONUNIX_GROUPS
+    sudo_nonunix_groupcheck_init();    /* initialise nonunix groups impl */
+#endif /* USING_NONUNIX_GROUPS */
+
     /* Parse nsswitch.conf for sudoers order. */
     snl = sudo_read_nss();
 
@@ -341,10 +352,22 @@ main(argc, argv, envp)
     tq_foreach_fwd(snl, nss) {
        validated = nss->lookup(nss, validated, pwflag);
 
-       /* Handle [NOTFOUND=return] */
-       if (!ISSET(validated, VALIDATE_OK) && nss->ret_notfound)
-           break;
+       if (ISSET(validated, VALIDATE_OK)) {
+           /* Handle "= auth" in netsvc.conf */
+           if (nss->ret_if_found)
+               break;
+       } else {
+           /* Handle [NOTFOUND=return] */
+           if (nss->ret_if_notfound)
+               break;
+       }
     }
+
+#ifdef USING_NONUNIX_GROUPS
+    /* Finished with the groupcheck code */
+    sudo_nonunix_groupcheck_cleanup();
+#endif
+
     if (safe_cmnd == NULL)
        safe_cmnd = estrdup(user_cmnd);
 
@@ -382,9 +405,10 @@ main(argc, argv, envp)
 
     /* Bail if a tty is required and we don't have one.  */
     if (def_requiretty) {
-       if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1)
+       if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) {
+           audit_failure(NewArgv, "no tty");
            log_error(NO_MAIL, "sorry, you must have a tty to run sudo");
-       else
+       else
            (void) close(fd);
     }
 
@@ -404,7 +428,7 @@ main(argc, argv, envp)
 
     /* Require a password if sudoers says so.  */
     if (def_authenticate)
-       check_user(validated, !ISSET(sudo_mode, MODE_NONINTERACTIVE));
+       check_user(validated, sudo_mode);
 
     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
     /* XXX - causes confusion when root is not listed in sudoers */
@@ -419,10 +443,13 @@ main(argc, argv, envp)
 
     if (ISSET(validated, VALIDATE_OK)) {
        /* Finally tell the user if the command did not exist. */
-       if (cmnd_status == NOT_FOUND_DOT)
+       if (cmnd_status == NOT_FOUND_DOT) {
+           audit_failure(NewArgv, "command in current directory");
            errorx(1, "ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd);
-       else if (cmnd_status == NOT_FOUND)
+       } else if (cmnd_status == NOT_FOUND) {
+           audit_failure(NewArgv, "%s: command not found", user_cmnd);
            errorx(1, "%s: command not found", user_cmnd);
+       }
 
        /* If user specified env vars make sure sudoers allows it. */
        if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
@@ -434,9 +461,9 @@ main(argc, argv, envp)
        }
 
        log_allowed(validated);
-       if (sudo_mode == MODE_CHECK)
+       if (ISSET(sudo_mode, MODE_CHECK))
            rc = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
-       else if (sudo_mode == MODE_LIST)
+       else if (ISSET(sudo_mode, MODE_LIST))
            display_privs(snl, list_pw ? list_pw : sudo_user.pw);
 
        /* Cleanup sudoers sources */
@@ -444,19 +471,23 @@ main(argc, argv, envp)
            nss->close(nss);
 
        /* Deferred exit due to sudo_ldap_close() */
-       if (sudo_mode == MODE_VALIDATE || sudo_mode == MODE_CHECK ||
-           sudo_mode == MODE_LIST)
+       if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST)))
            exit(rc);
 
        /*
-        * Override user's umask if configured to do so.
-        * If user's umask is more restrictive, OR in those bits too.
+        * Set umask based on sudoers.
+        * If user's umask is more restrictive, OR in those bits too
+        * unless umask_override is set.
         */
        if (def_umask != 0777) {
-           mode_t mask = umask(def_umask);
-           mask |= def_umask;
-           if (mask != def_umask)
-               umask(mask);
+           if (def_umask_override) {
+               umask(def_umask);
+           } else {
+               mode_t mask = umask(def_umask);
+               mask |= def_umask;
+               if (mask != def_umask)
+                   umask(mask);
+           }
        }
 
        /* Restore coredumpsize resource limit. */
@@ -464,6 +495,9 @@ main(argc, argv, envp)
        (void) setrlimit(RLIMIT_CORE, &corelimit);
 #endif /* RLIMIT_CORE && !SUDO_DEVEL */
 
+       /* Must audit before uid change. */
+       audit_success(NewArgv);
+
        /* Become specified user or root if executing a command. */
        if (ISSET(sudo_mode, MODE_RUN))
            set_perms(PERM_FULL_RUNAS);
@@ -509,9 +543,10 @@ main(argc, argv, envp)
        closefrom(def_closefrom + 1);
 
 #ifndef PROFILING
-       if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
+       if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) {
+           syslog(LOG_AUTH|LOG_ERR, "fork");
            exit(0);
-       else {
+       else {
 #ifdef HAVE_SELINUX
            if (is_selinux_enabled() > 0 && user_role != NULL)
                selinux_exec(user_role, user_type, NewArgv,
@@ -530,9 +565,11 @@ main(argc, argv, envp)
            NewArgv[0] = "sh";
            NewArgv[1] = safe_cmnd;
            execv(_PATH_BSHELL, NewArgv);
-       } warning("unable to execute %s", safe_cmnd);
+       }
+       warning("unable to execute %s", safe_cmnd);
        exit(127);
     } else if (ISSET(validated, FLAG_NO_USER | FLAG_NO_HOST)) {
+       audit_failure(NewArgv, "No user or host");
        log_denial(validated, 1);
        exit(1);
     } else {
@@ -554,6 +591,7 @@ main(argc, argv, envp)
            /* Just tell the user they are not allowed to run foo. */
            log_denial(validated, 1);
        }
+       audit_failure(NewArgv, "validation failure");
        exit(1);
     }
     exit(0);   /* not reached */
@@ -666,7 +704,7 @@ init_vars(sudo_mode, envp)
         * users to place "sudo -k" in a .logout file which can cause sudo to
         * be run during reboot after the YP/NIS/NIS+/LDAP/etc daemon has died.
         */
-       if (sudo_mode & (MODE_INVALIDATE|MODE_KILL))
+       if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE)
            errorx(1, "unknown uid: %s", pw_name);
        log_error(0, "unknown uid: %s", pw_name);
     }
@@ -802,6 +840,9 @@ set_cmnd(sudo_mode)
     if (!update_defaults(SETDEF_CMND))
        log_error(NO_STDERR|NO_EXIT, "problem with defaults entries");
 
+    if (!runas_user && !runas_group)
+       set_runaspw(def_runas_default); /* may have been updated above */
+
     return(rval);
 }
 
@@ -817,7 +858,7 @@ parse_args(argc, argv)
 {
     int mode = 0;              /* what mode is sudo to be run in? */
     int flags = 0;             /* mode flags */
-    int ch;
+    int valid_flags, ch;
 
     /* First, check to see if we were invoked as "sudoedit". */
     if (strcmp(getprogname(), "sudoedit") == 0)
@@ -831,6 +872,10 @@ parse_args(argc, argv)
 #define is_envar (optind < argc && argv[optind][0] != '/' && \
            strchr(argv[optind], '=') != NULL)
 
+    /* Flags allowed when running a command */
+    valid_flags = MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|
+                 MODE_LOGIN_SHELL|MODE_INVALIDATE|MODE_NONINTERACTIVE|
+                 MODE_PRESERVE_GROUPS|MODE_SHELL;
     for (;;) {
        /*
         * We disable arg permutation for GNU getopt().
@@ -869,6 +914,7 @@ parse_args(argc, argv)
                    if (mode && mode != MODE_EDIT)
                        usage_excl(1);
                    mode = MODE_EDIT;
+                   valid_flags = MODE_INVALIDATE|MODE_NONINTERACTIVE;
                    break;
                case 'g':
                    runas_group = optarg;
@@ -877,28 +923,31 @@ parse_args(argc, argv)
                    SET(flags, MODE_RESET_HOME);
                    break;
                case 'h':
-                   if (mode && mode != MODE_HELP)
-                       usage_excl(1);
+                   if (mode && mode != MODE_HELP) {
+                       if (strcmp(getprogname(), "sudoedit") != 0)
+                           usage_excl(1);
+                   }
                    mode = MODE_HELP;
+                   valid_flags = 0;
                    break;
                case 'i':
                    SET(flags, MODE_LOGIN_SHELL);
                    def_env_reset = TRUE;
                    break;
                case 'k':
-                   if (mode && mode != MODE_INVALIDATE)
-                       usage_excl(1);
-                   mode = MODE_INVALIDATE;
+                   SET(flags, MODE_INVALIDATE);
                    break;
                case 'K':
                    if (mode && mode != MODE_KILL)
                        usage_excl(1);
                    mode = MODE_KILL;
+                   valid_flags = 0;
                    break;
                case 'L':
                    if (mode && mode != MODE_LISTDEFS)
                        usage_excl(1);
                    mode = MODE_LISTDEFS;
+                   valid_flags = MODE_INVALIDATE|MODE_NONINTERACTIVE;
                    break;
                case 'l':
                    if (mode) {
@@ -908,6 +957,7 @@ parse_args(argc, argv)
                            usage_excl(1);
                    }
                    mode = MODE_LIST;
+                   valid_flags = MODE_INVALIDATE|MODE_NONINTERACTIVE;
                    break;
                case 'n':
                    SET(flags, MODE_NONINTERACTIVE);
@@ -944,11 +994,13 @@ parse_args(argc, argv)
                    if (mode && mode != MODE_VALIDATE)
                        usage_excl(1);
                    mode = MODE_VALIDATE;
+                   valid_flags = MODE_INVALIDATE|MODE_NONINTERACTIVE;
                    break;
                case 'V':
                    if (mode && mode != MODE_VERSION)
                        usage_excl(1);
                    mode = MODE_VERSION;
+                   valid_flags = 0;
                    break;
                default:
                    usage(1);
@@ -973,8 +1025,16 @@ parse_args(argc, argv)
     NewArgc = argc - optind;
     NewArgv = argv + optind;
 
-    if (!mode)
-       mode = MODE_RUN;
+    if (!mode) {
+       /* Defer -k mode setting until we know whether it is a flag or not */
+       if (ISSET(flags, MODE_INVALIDATE) && NewArgc == 0) {
+           mode = MODE_INVALIDATE;     /* -k by itself */
+           CLR(flags, MODE_INVALIDATE);
+           valid_flags = 0;
+       } else {
+           mode = MODE_RUN;            /* running a command */
+       }
+    }
 
     if (NewArgc > 0 && mode == MODE_LIST)
        mode = MODE_CHECK;
@@ -990,6 +1050,8 @@ parse_args(argc, argv)
        }
        SET(flags, MODE_SHELL);
     }
+    if ((flags & valid_flags) != flags)
+       usage(1);
     if (mode == MODE_EDIT &&
        (ISSET(flags, MODE_PRESERVE_ENV) || sudo_user.env_vars != NULL)) {
        if (ISSET(mode, MODE_PRESERVE_ENV))
@@ -1024,8 +1086,9 @@ parse_args(argc, argv)
  * Returns a handle to the sudoers file or NULL on error.
  */
 FILE *
-open_sudoers(sudoers, keepopen)
+open_sudoers(sudoers, doedit, keepopen)
     const char *sudoers;
+    int doedit;
     int *keepopen;
 {
     struct stat statbuf;
@@ -1077,16 +1140,18 @@ open_sudoers(sudoers, keepopen)
            (unsigned long) statbuf.st_gid, (unsigned long) SUDOERS_GID);
     else if ((fp = fopen(sudoers, "r")) == NULL)
        log_error(USE_ERRNO, "can't open %s", sudoers);
-    else if (statbuf.st_size != 0) {
+    else {
        /*
         * Make sure we can actually read sudoers so we can present the
-        * user with a reasonable error message.
+        * user with a reasonable error message (unlike the lexer).
         */
-       if (fgetc(fp) == EOF)
-           log_error(USE_ERRNO, "can't read %s", sudoers);
-       rewind(fp);
+       if (statbuf.st_size != 0) {
+           if (fgetc(fp) == EOF)
+               log_error(USE_ERRNO, "can't read %s", sudoers);
+           rewind(fp);
+       }
+       (void) fcntl(fileno(fp), F_SETFD, 1);
     }
-    (void) fcntl(fileno(fp), F_SETFD, 1);
 
     set_perms(PERM_ROOT);              /* change back to root */
     return(fp);
@@ -1313,8 +1378,10 @@ set_runaspw(user)
        if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
            runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
     } else {
-       if ((runas_pw = sudo_getpwnam(user)) == NULL)
+       if ((runas_pw = sudo_getpwnam(user)) == NULL) {
+           audit_failure(NewArgv, "unknown user: %s", user);
            log_error(NO_MAIL|MSG_ONLY, "unknown user: %s", user);
+       }
     }
 }
 
@@ -1384,7 +1451,7 @@ cleanup(gotsignal)
 static void
 show_version()
 {
-    (void) printf("Sudo version %s\n", version);
+    (void) printf("Sudo version %s\n", PACKAGE_VERSION);
     if (getuid() == 0) {
        putchar('\n');
        (void) printf("Sudoers path: %s\n", _PATH_SUDOERS);
@@ -1409,7 +1476,7 @@ static void
 usage_excl(exit_val)
     int exit_val;
 {
-    warningx("Only one of the -e, -h, -i, -k, -K, -l, -s, -v or -V options may be specified");
+    warningx("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified");
     usage(exit_val);
 }
 
@@ -1422,21 +1489,22 @@ usage(exit_val)
     int exit_val;
 {
     struct lbuf lbuf;
-    char *uvec[5];
+    char *uvec[6];
     int i, ulen;
 
     /*
      * Use usage vectors appropriate to the progname.
      */
     if (strcmp(getprogname(), "sudoedit") == 0) {
-       uvec[0] = SUDO_USAGE4 + 3;
+       uvec[0] = SUDO_USAGE5 + 3;
        uvec[1] = NULL;
     } else {
        uvec[0] = SUDO_USAGE1;
        uvec[1] = SUDO_USAGE2;
        uvec[2] = SUDO_USAGE3;
        uvec[3] = SUDO_USAGE4;
-       uvec[4] = NULL;
+       uvec[4] = SUDO_USAGE5;
+       uvec[5] = NULL;
     }
 
     /*
index 07290ee23723a038959340bb490b34f648b93a58..c7375477c7040de347d248d308e3a6477e11a612 100644 (file)
--- a/sudo.cat
+++ b/sudo.cat
@@ -8,10 +8,12 @@ N\bNA\bAM\bME\bE
        sudo, sudoedit - execute a command as another user
 
 S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
-       s\bsu\bud\bdo\b[-\b-n\bn] -\b-h\bh | -\b-K\bK | -\b-k\bk | -\b-L\bL | -\b-V\bV | -\b-v\bv
+       s\bsu\bud\bdo\b-\b-h\bh | -\b-K\bK | -\b-k\bk | -\b-L\bL | -\b-V\bV
 
-       s\bsu\bud\bdo\bo -\b-l\bl[\b[l\bl]\b] [-\b-A\bAn\bnS\bS] [-\b-g\bg _\bg_\br_\bo_\bu_\bp_\bn_\ba_\bm_\be|_\b#_\bg_\bi_\bd] [-\b-U\bU _\bu_\bs_\be_\br_\bn_\ba_\bm_\be] [-\b-u\bu _\bu_\bs_\be_\br_\bn_\ba_\bm_\be|_\b#_\bu_\bi_\bd]
-       [_\bc_\bo_\bm_\bm_\ba_\bn_\bd]
+       s\bsu\bud\bdo\bo -\b-v\bv [-\b-A\bAk\bkn\bnS\bS] [-\b-a\ba _\ba_\bu_\bt_\bh_\b__\bt_\by_\bp_\be] [-\b-p\bp _\bp_\br_\bo_\bm_\bp_\bt]
+
+       s\bsu\bud\bdo\bo -\b-l\bl[\b[l\bl]\b] [-\b-A\bAk\bkn\bnS\bS] [-\b-a\ba _\ba_\bu_\bt_\bh_\b__\bt_\by_\bp_\be] [-\b-g\bg _\bg_\br_\bo_\bu_\bp_\bn_\ba_\bm_\be|_\b#_\bg_\bi_\bd] [-\b-p\bp _\bp_\br_\bo_\bm_\bp_\bt]
+       [-\b-U\bU _\bu_\bs_\be_\br_\bn_\ba_\bm_\be] [-\b-u\bu _\bu_\bs_\be_\br_\bn_\ba_\bm_\be|_\b#_\bu_\bi_\bd] [_\bc_\bo_\bm_\bm_\ba_\bn_\bd]
 
        s\bsu\bud\bdo\bo [-\b-A\bAb\bbE\bEH\bHn\bnP\bPS\bS] [-\b-a\ba _\ba_\bu_\bt_\bh_\b__\bt_\by_\bp_\be] [-\b-C\bC _\bf_\bd] [-\b-c\bc _\bc_\bl_\ba_\bs_\bs|_\b-] [-\b-g\bg _\bg_\br_\bo_\bu_\bp_\bn_\ba_\bm_\be|_\b#_\bg_\bi_\bd]
        [-\b-p\bp _\bp_\br_\bo_\bm_\bp_\bt] [-\b-u\bu _\bu_\bs_\be_\br_\bn_\ba_\bm_\be|_\b#_\bu_\bi_\bd] [V\bVA\bAR\bR=_\bv_\ba_\bl_\bu_\be] [-\b-i\bi | -\b-s\bs] [_\bc_\bo_\bm_\bm_\ba_\bn_\bd]
@@ -56,12 +58,10 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        the sudoers lookup is still done for root, not the user specified by
        SUDO_USER.
 
-       s\bsu\bud\bdo\bo can log both successful and unsuccessful attempts (as well as
-       errors) to _\bs_\by_\bs_\bl_\bo_\bg(3), a log file, or both.  By default s\bsu\bud\bdo\bo will log
 
 
 
-1.7.0                   November 15, 2008                       1
+1.7.2                     June 15, 2009                         1
 
 
 
@@ -70,6 +70,8 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
+       s\bsu\bud\bdo\bo can log both successful and unsuccessful attempts (as well as
+       errors) to _\bs_\by_\bs_\bl_\bo_\bg(3), a log file, or both.  By default s\bsu\bud\bdo\bo will log
        via _\bs_\by_\bs_\bl_\bo_\bg(3) but this is changeable at configure time or via the
        _\bs_\bu_\bd_\bo_\be_\br_\bs file.
 
@@ -78,12 +80,12 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
        -A          Normally, if s\bsu\bud\bdo\bo requires a password, it will read it from
                    the current terminal.  If the -\b-A\bA (_\ba_\bs_\bk_\bp_\ba_\bs_\bs) option is
-                   specified, a helper program is executed to read the user's
-                   password and output the password to the standard output.
-                   If the SUDO_ASKPASS environment variable is set, it
-                   specifies the path to the helper program.  Otherwise, the
-                   value specified by the _\ba_\bs_\bk_\bp_\ba_\bs_\bs option in _\bs_\bu_\bd_\bo_\be_\br_\bs(4) is
-                   used.
+                   specified, a (possibly graphical) helper program is
+                   executed to read the user's password and output the
+                   password to the standard output.  If the SUDO_ASKPASS
+                   environment variable is set, it specifies the path to the
+                   helper program.  Otherwise, the value specified by the
+                   _\ba_\bs_\bk_\bp_\ba_\bs_\bs option in _\bs_\bu_\bd_\bo_\be_\br_\bs(4) is used.
 
        -a _\bt_\by_\bp_\be     The -\b-a\ba (_\ba_\bu_\bt_\bh_\be_\bn_\bt_\bi_\bc_\ba_\bt_\bi_\bo_\bn _\bt_\by_\bp_\be) option causes s\bsu\bud\bdo\bo to use the
                    specified authentication type when validating the user, as
@@ -123,11 +125,9 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
                    either the matching command has the SETENV tag or the
                    _\bs_\be_\bt_\be_\bn_\bv option is set in _\bs_\bu_\bd_\bo_\be_\br_\bs(4).
 
-       -e          The -\b-e\be (_\be_\bd_\bi_\bt) option indicates that, instead of running a
-
 
 
-1.7.0                   November 15, 2008                       2
+1.7.2                     June 15, 2009                         2
 
 
 
@@ -136,6 +136,7 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
+       -e          The -\b-e\be (_\be_\bd_\bi_\bt) option indicates that, instead of running a
                    command, the user wishes to edit one or more files.  In
                    lieu of a command, the string "sudoedit" is used when
                    consulting the _\bs_\bu_\bd_\bo_\be_\br_\bs file.  If the user is authorized by
@@ -189,11 +190,10 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
                    execution.  Otherwise, an interactive shell is executed.
                    s\bsu\bud\bdo\bo attempts to change to that user's home directory
                    before running the shell.  It also initializes the
-                   environment, leaving _\bD_\bI_\bS_\bP_\bL_\bA_\bY and _\bT_\bE_\bR_\bM unchanged, setting
 
 
 
-1.7.0                   November 15, 2008                       3
+1.7.2                     June 15, 2009                         3
 
 
 
@@ -202,19 +202,28 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
+                   environment, leaving _\bD_\bI_\bS_\bP_\bL_\bA_\bY and _\bT_\bE_\bR_\bM unchanged, setting
                    _\bH_\bO_\bM_\bE, _\bS_\bH_\bE_\bL_\bL, _\bU_\bS_\bE_\bR, _\bL_\bO_\bG_\bN_\bA_\bM_\bE, and _\bP_\bA_\bT_\bH, as well as the
                    contents of _\b/_\be_\bt_\bc_\b/_\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt on Linux and AIX systems.  All
                    other environment variables are removed.
 
        -K          The -\b-K\bK (sure _\bk_\bi_\bl_\bl) option is like -\b-k\bk except that it removes
-                   the user's timestamp entirely.  Like -\b-k\bk, this option does
-                   not require a password.
-
-       -k          The -\b-k\bk (_\bk_\bi_\bl_\bl) option to s\bsu\bud\bdo\bo invalidates the user's
-                   timestamp by setting the time on it to the Epoch.  The next
-                   time s\bsu\bud\bdo\bo is run a password will be required.  This option
-                   does not require a password and was added to allow a user
-                   to revoke s\bsu\bud\bdo\bo permissions from a .logout file.
+                   the user's timestamp entirely and may not be used in
+                   conjunction with a command or other option.  This option
+                   does not require a password.
+
+       -k          When used by itself, the -\b-k\bk (_\bk_\bi_\bl_\bl) option to s\bsu\bud\bdo\bo
+                   invalidates the user's timestamp by setting the time on it
+                   to the Epoch.  The next time s\bsu\bud\bdo\bo is run a password will be
+                   required.  This option does not require a password and was
+                   added to allow a user to revoke s\bsu\bud\bdo\bo permissions from a
+                   .logout file.
+
+                   When used in conjunction with a command or an option that
+                   may require a password, the -\b-k\bk option will cause s\bsu\bud\bdo\bo to
+                   ignore the user's timestamp file.  As a result, s\bsu\bud\bdo\bo will
+                   prompt for a password (if one is required by _\bs_\bu_\bd_\bo_\be_\br_\bs) and
+                   will not update the user's timestamp file.
 
        -L          The -\b-L\bL (_\bl_\bi_\bs_\bt defaults) option will list out the parameters
                    that may be set in a _\bD_\be_\bf_\ba_\bu_\bl_\bt_\bs line along with a short
@@ -248,26 +257,25 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
                    password prompt and use a custom one.  The following
                    percent (`%') escapes are supported:
 
-                   %H  expanded to the local hostname including the domain
-                       name (on if the machine's hostname is fully qualified
-                       or the _\bf_\bq_\bd_\bn _\bs_\bu_\bd_\bo_\be_\br_\bs option is set)
-
-                   %h  expanded to the local hostname without the domain name
 
-                   %p  expanded to the user whose password is being asked for
-                       (respects the _\br_\bo_\bo_\bt_\bp_\bw, _\bt_\ba_\br_\bg_\be_\bt_\bp_\bw and _\br_\bu_\bn_\ba_\bs_\bp_\bw flags in
 
+1.7.2                     June 15, 2009                         4
 
 
-1.7.0                   November 15, 2008                       4
 
 
 
+SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
-SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
+                   %H  expanded to the local hostname including the domain
+                       name (on if the machine's hostname is fully qualified
+                       or the _\bf_\bq_\bd_\bn _\bs_\bu_\bd_\bo_\be_\br_\bs option is set)
 
+                   %h  expanded to the local hostname without the domain name
 
+                   %p  expanded to the user whose password is being asked for
+                       (respects the _\br_\bo_\bo_\bt_\bp_\bw, _\bt_\ba_\br_\bg_\be_\bt_\bp_\bw and _\br_\bu_\bn_\ba_\bs_\bp_\bw flags in
                        _\bs_\bu_\bd_\bo_\be_\br_\bs)
 
                    %U  expanded to the login name of the user the command will
@@ -314,26 +322,26 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
        -v          If given the -\b-v\bv (_\bv_\ba_\bl_\bi_\bd_\ba_\bt_\be) option, s\bsu\bud\bdo\bo will update the
                    user's timestamp, prompting for the user's password if
                    necessary.  This extends the s\bsu\bud\bdo\bo timeout for another 5
-                   minutes (or whatever the timeout is set to in _\bs_\bu_\bd_\bo_\be_\br_\bs) but
-                   does not run a command.
 
-       --          The -\b--\b- option indicates that s\bsu\bud\bdo\bo should stop processing
-                   command line arguments.  It is most useful in conjunction
-                   with the -\b-s\bs option.
 
-       Environment variables to be set for the command may also be passed on
 
+1.7.2                     June 15, 2009                         5
 
 
-1.7.0                   November 15, 2008                       5
 
 
 
+SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
-SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
+                   minutes (or whatever the timeout is set to in _\bs_\bu_\bd_\bo_\be_\br_\bs) but
+                   does not run a command.
 
+       --          The -\b--\b- option indicates that s\bsu\bud\bdo\bo should stop processing
+                   command line arguments.  It is most useful in conjunction
+                   with the -\b-s\bs option.
 
+       Environment variables to be set for the command may also be passed on
        the command line in the form of V\bVA\bAR\bR=_\bv_\ba_\bl_\bu_\be, e.g.
        L\bLD\bD_\b_L\bLI\bIB\bBR\bRA\bAR\bRY\bY_\b_P\bPA\bAT\bTH\bH=_\b/_\bu_\bs_\br_\b/_\bl_\bo_\bc_\ba_\bl_\b/_\bp_\bk_\bg_\b/_\bl_\bi_\bb.  Variables passed on the command
        line are subject to the same restrictions as normal environment
@@ -380,18 +388,10 @@ S\bSE\bEC\bCU\bUR\bRI\bIT\bTY\bY N\bNO\bOT\bTE\bES\bS
        output of sudo -V when run as root.
 
        Note that the dynamic linker on most operating systems will remove
-       variables that can control dynamic linking from the environment of
-       setuid executables, including s\bsu\bud\bdo\bo.  Depending on the operating system
-       this may include _RLD*, DYLD_*, LD_*, LDR_*, LIBPATH, SHLIB_PATH, and
-       others.  These type of variables are removed from the environment
-       before s\bsu\bud\bdo\bo even begins execution and, as such, it is not possible for
-       s\bsu\bud\bdo\bo to preserve them.
-
-       To prevent command spoofing, s\bsu\bud\bdo\bo checks "." and "" (both denoting
 
 
 
-1.7.0                   November 15, 2008                       6
+1.7.2                     June 15, 2009                         6
 
 
 
@@ -400,6 +400,14 @@ S\bSE\bEC\bCU\bUR\bRI\bIT\bTY\bY N\bNO\bOT\bTE\bES\bS
 SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
+       variables that can control dynamic linking from the environment of
+       setuid executables, including s\bsu\bud\bdo\bo.  Depending on the operating system
+       this may include _RLD*, DYLD_*, LD_*, LDR_*, LIBPATH, SHLIB_PATH, and
+       others.  These type of variables are removed from the environment
+       before s\bsu\bud\bdo\bo even begins execution and, as such, it is not possible for
+       s\bsu\bud\bdo\bo to preserve them.
+
+       To prevent command spoofing, s\bsu\bud\bdo\bo 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 PATH
        environment variable is _\bn_\bo_\bt modified and is passed unchanged to the
@@ -447,25 +455,24 @@ E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
                        --enable-shell-sets-home option), set to homedir of the
                        target user
 
-       PATH            Set to a sane value if the _\bs_\be_\bc_\bu_\br_\be_\b__\bp_\ba_\bt_\bh sudoers option
-                       is set.
 
-       SHELL           Used to determine shell to run with -s option
-
-       SUDO_ASKPASS    Specifies the path to a helper program used to read the
-                       password if no terminal is available or if the -A
 
+1.7.2                     June 15, 2009                         7
 
 
-1.7.0                   November 15, 2008                       7
 
 
 
+SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
-SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
+       PATH            Set to a sane value if the _\bs_\be_\bc_\bu_\br_\be_\b__\bp_\ba_\bt_\bh sudoers option
+                       is set.
 
+       SHELL           Used to determine shell to run with -s option
 
+       SUDO_ASKPASS    Specifies the path to a helper program used to read the
+                       password if no terminal is available or if the -A
                        option is specified.
 
        SUDO_COMMAND    Set to the command run by sudo
@@ -504,33 +511,42 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
 
         $ sudo ls /usr/local/protected
 
-       To list the home directory of user yazza on a machine where the file
-       system holding ~yazza is not exported as root:
+       To list the home directory of user yaz on a machine where the file
+       system holding ~yaz is not exported as root:
 
-        $ sudo -u yazza ls ~yazza
+        $ sudo -u yaz ls ~yaz
 
        To edit the _\bi_\bn_\bd_\be_\bx_\b._\bh_\bt_\bm_\bl file as user www:
 
         $ sudo -u www vi ~www/htdocs/index.html
 
-       To shutdown a machine:
 
-        $ sudo shutdown -r +15 "quick reboot"
 
-       To make a usage listing of the directories in the /home partition.
-       Note that this runs the commands in a sub-shell to make the cd and file
-       redirection work.
+
+1.7.2                     June 15, 2009                         8
 
 
 
-1.7.0                   November 15, 2008                       8
 
 
+SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
+       To view system logs only accessible to root and users in the adm group:
 
-SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
+        $ sudo -g adm view /var/log/syslog
 
+       To run an editor as jim with a different primary group:
+
+        $ sudo -u jim -g audio vi ~jim/sound.txt
+
+       To shutdown a machine:
+
+        $ sudo shutdown -r +15 "quick reboot"
+
+       To make a usage listing of the directories in the /home partition.
+       Note that this runs the commands in a sub-shell to make the cd and file
+       redirection work.
 
         $ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
 
@@ -570,6 +586,18 @@ C\bCA\bAV\bVE\bEA\bAT\bTS\bS
        make setuid shell scripts unsafe on some operating systems (if your OS
        has a /dev/fd/ directory, setuid shell scripts are generally safe).
 
+
+
+
+1.7.2                     June 15, 2009                         9
+
+
+
+
+
+SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
+
+
 B\bBU\bUG\bGS\bS
        If you feel you have found a bug in s\bsu\bud\bdo\bo, please submit a bug report at
        http://www.sudo.ws/sudo/bugs/
@@ -589,6 +617,44 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.7.0                   November 15, 2008                       9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.7.2                     June 15, 2009                        10
 
 
diff --git a/sudo.h b/sudo.h
index ac5fdbde6d0a56ceb3c427c741c88f376eb210ba..afb4e4e0bda6d8a5a65f5b46ea030898b8ad7053 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1993-1996, 1998-2005, 2007-2008
+ * Copyright (c) 1993-1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  *
- * $Sudo: sudo.h,v 1.269 2008/11/25 17:01:34 millert Exp $
+ * $Sudo: sudo.h,v 1.273 2009/05/25 12:02:41 millert Exp $
  */
 
 #ifndef _SUDO_SUDO_H
@@ -129,6 +129,8 @@ struct sudo_user {
 #define PERM_RUNAS               0x04
 #define PERM_FULL_RUNAS          0x05
 #define PERM_TIMESTAMP           0x06
+#define PERM_NOEXIT              0x10 /* flag */
+#define PERM_MASK                0xf0
 
 /*
  * Shortcuts for sudo_user contents.
@@ -237,6 +239,12 @@ void *memrchr              __P((const void *, int, size_t));
 #ifndef HAVE_MKSTEMP
 int mkstemp            __P((char *));
 #endif
+#ifndef HAVE_SETENV
+int setenv             __P((const char *, const char *, int));
+#endif
+#ifndef HAVE_UNSETENV
+int unsetenv           __P((const char *));
+#endif
 char *sudo_goodpath    __P((const char *, struct stat *));
 char *tgetpass         __P((const char *, int, int));
 int find_path          __P((char *, char **, struct stat *, char *));
@@ -263,7 +271,7 @@ int sudo_file_display_cmnd __P((struct sudo_nss *, struct passwd *));
 int sudo_file_display_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
 int sudo_file_display_bound_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
 int sudo_file_display_privs __P((struct sudo_nss *, struct passwd *, struct lbuf *));
-void set_perms         __P((int));
+int set_perms          __P((int));
 void remove_timestamp  __P((int));
 int check_secureware   __P((char *));
 void sia_attempt_auth  __P((void));
@@ -292,13 +300,11 @@ char *sudo_getepw __P((const struct passwd *));
 int pam_prep_user      __P((struct passwd *));
 void zero_bytes                __P((volatile void *, size_t));
 int gettime            __P((struct timespec *));
-FILE *open_sudoers     __P((const char *, int *));
+FILE *open_sudoers     __P((const char *, int, int *));
 void display_privs     __P((struct sudo_nss_list *, struct passwd *));
 int display_cmnd       __P((struct sudo_nss_list *, struct passwd *));
 int get_ttycols                __P((void));
 char *sudo_parseln     __P((FILE *));
-void sudo_setenv       __P((const char *, const char *, int));
-void sudo_unsetenv     __P((const char *));
 void sudo_setgrent     __P((void));
 void sudo_endgrent     __P((void));
 void sudo_setpwent     __P((void));
index 26d8a309538e416889416c0889d03cbf7389c040..13c0d6d84b1e3def07d560b3396671c72a0f327b 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2008
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2009
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: sudo.man.in,v 1.53 2008/11/15 18:34:26 millert Exp $
+.\" $Sudo: sudo.man.in,v 1.56 2009/06/29 13:36:42 millert Exp $
 .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "SUDO @mansectsu@"
-.TH SUDO @mansectsu@ "November 15, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+.TH SUDO @mansectsu@ "June 15, 2009" "1.7.2" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
 sudo, sudoedit \- execute a command as another user
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
-\&\fBsudo\fR [\fB\-n\fR] \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-L\fR | \fB\-V\fR | \fB\-v\fR
+\&\fBsudo\fR \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-L\fR | \fB\-V\fR
 .PP
-\&\fBsudo\fR \fB\-l[l]\fR [\fB\-AnS\fR] [\fB\-g\fR\ \fIgroupname\fR|\fI#gid\fR] [\fB\-U\fR\ \fIusername\fR]
-[\fB\-u\fR\ \fIusername\fR|\fI#uid\fR] [\fIcommand\fR]
+\&\fBsudo\fR \fB\-v\fR [\fB\-AknS\fR]
+@BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+.PP
+\&\fBsudo\fR \fB\-l[l]\fR [\fB\-AknS\fR]
+@BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+[\fB\-g\fR\ \fIgroupname\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
+[\fB\-U\fR\ \fIusername\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR] [\fIcommand\fR]
 .PP
 \&\fBsudo\fR [\fB\-AbEHnPS\fR]
 @BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
@@ -235,11 +241,11 @@ or via the \fIsudoers\fR file.
 .IX Item "-A"
 Normally, if \fBsudo\fR requires a password, it will read it from the
 current terminal.  If the \fB\-A\fR (\fIaskpass\fR) option is specified,
-a helper program is executed to read the user's password and output
-the password to the standard output.  If the \f(CW\*(C`SUDO_ASKPASS\*(C'\fR
-environment variable is set, it specifies the path to the helper
-program.  Otherwise, the value specified by the \fIaskpass\fR option
-in \fIsudoers\fR\|(@mansectform@) is used.
+a (possibly graphical) helper program is executed to read the
+user's password and output the password to the standard output.  If
+the \f(CW\*(C`SUDO_ASKPASS\*(C'\fR environment variable is set, it specifies the
+path to the helper program.  Otherwise, the value specified by the
+\&\fIaskpass\fR option in \fIsudoers\fR\|(@mansectform@) is used.
 @BAMAN@.IP "\-a \fItype\fR" 12
 @BAMAN@.IX Item "-a type"
 @BAMAN@The \fB\-a\fR (\fIauthentication type\fR) option causes \fBsudo\fR to use the
@@ -344,15 +350,22 @@ All other environment variables are removed.
 .IP "\-K" 12
 .IX Item "-K"
 The \fB\-K\fR (sure \fIkill\fR) option is like \fB\-k\fR except that it removes
-the user's timestamp entirely.  Like \fB\-k\fR, this option does not
-require a password.
+the user's timestamp entirely and may not be used in conjunction
+with a command or other option.  This option does not require a
+password.
 .IP "\-k" 12
 .IX Item "-k"
-The \fB\-k\fR (\fIkill\fR) option to \fBsudo\fR invalidates the user's timestamp
-by setting the time on it to the Epoch.  The next time \fBsudo\fR is
-run a password will be required.  This option does not require a password
-and was added to allow a user to revoke \fBsudo\fR permissions from a .logout
-file.
+When used by itself, the \fB\-k\fR (\fIkill\fR) option to \fBsudo\fR invalidates
+the user's timestamp by setting the time on it to the Epoch.  The
+next time \fBsudo\fR is run a password will be required.  This option
+does not require a password and was added to allow a user to revoke
+\&\fBsudo\fR permissions from a .logout file.
+.Sp
+When used in conjunction with a command or an option that may require
+a password, the \fB\-k\fR option will cause \fBsudo\fR to ignore the user's
+timestamp file.  As a result, \fBsudo\fR will prompt for a password
+(if one is required by \fIsudoers\fR) and will not update the user's
+timestamp file.
 .IP "\-L" 12
 .IX Item "-L"
 The \fB\-L\fR (\fIlist\fR defaults) option will list out the parameters
@@ -654,11 +667,11 @@ To get a file listing of an unreadable directory:
 \& $ sudo ls /usr/local/protected
 .Ve
 .PP
-To list the home directory of user yazza on a machine where the
-file system holding ~yazza is not exported as root:
+To list the home directory of user yaz on a machine where the
+file system holding ~yaz is not exported as root:
 .PP
 .Vb 1
-\& $ sudo \-u yazza ls ~yazza
+\& $ sudo \-u yaz ls ~yaz
 .Ve
 .PP
 To edit the \fIindex.html\fR file as user www:
@@ -667,6 +680,18 @@ To edit the \fIindex.html\fR file as user www:
 \& $ sudo \-u www vi ~www/htdocs/index.html
 .Ve
 .PP
+To view system logs only accessible to root and users in the adm group:
+.PP
+.Vb 1
+\& $ sudo \-g adm view /var/log/syslog
+.Ve
+.PP
+To run an editor as jim with a different primary group:
+.PP
+.Vb 1
+\& $ sudo \-u jim \-g audio vi ~jim/sound.txt
+.Ve
+.PP
 To shutdown a machine:
 .PP
 .Vb 1
index e96f044c0b699bb39273eb03131578afad31be2c..c8b370d2e7b0a2ba8213a97f19072e0c2972b467 100644 (file)
--- a/sudo.pod
+++ b/sudo.pod
@@ -1,4 +1,4 @@
-Copyright (c) 1994-1996, 1998-2005, 2007-2008
+Copyright (c) 1994-1996, 1998-2005, 2007-2009
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@ Sponsored in part by the Defense Advanced Research Projects
 Agency (DARPA) and Air Force Research Laboratory, Air Force
 Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-$Sudo: sudo.pod,v 1.120 2008/11/15 18:34:01 millert Exp $
+$Sudo: sudo.pod,v 1.124 2009/06/15 21:19:47 millert Exp $
 =pod
 
 =head1 NAME
@@ -27,10 +27,16 @@ sudo, sudoedit - execute a command as another user
 
 =head1 SYNOPSIS
 
-B<sudo> [B<-n>] B<-h> | B<-K> | B<-k> | B<-L> | B<-V> | B<-v>
+B<sudo> B<-h> | B<-K> | B<-k> | B<-L> | B<-V>
 
-B<sudo> B<-l[l]> [B<-AnS>] S<[B<-g> I<groupname>|I<#gid>]> S<[B<-U> I<username>]>
-S<[B<-u> I<username>|I<#uid>]> [I<command>]
+B<sudo> B<-v> [B<-AknS>]
+S<[B<-a> I<auth_type>]>
+S<[B<-p> I<prompt>]>
+
+B<sudo> B<-l[l]> [B<-AknS>]
+S<[B<-a> I<auth_type>]>
+S<[B<-g> I<groupname>|I<#gid>]> S<[B<-p> I<prompt>]>
+S<[B<-U> I<username>]> S<[B<-u> I<username>|I<#uid>]> [I<command>]
 
 B<sudo> [B<-AbEHnPS>]
 S<[B<-a> I<auth_type>]>
@@ -105,11 +111,11 @@ B<sudo> accepts the following command line options:
 
 Normally, if B<sudo> requires a password, it will read it from the
 current terminal.  If the B<-A> (I<askpass>) option is specified,
-a helper program is executed to read the user's password and output
-the password to the standard output.  If the C<SUDO_ASKPASS>
-environment variable is set, it specifies the path to the helper
-program.  Otherwise, the value specified by the I<askpass> option
-in L<sudoers(5)> is used.
+a (possibly graphical) helper program is executed to read the
+user's password and output the password to the standard output.  If
+the C<SUDO_ASKPASS> environment variable is set, it specifies the
+path to the helper program.  Otherwise, the value specified by the
+I<askpass> option in L<sudoers(5)> is used.
 
 =item -a I<type>
 
@@ -231,16 +237,23 @@ All other environment variables are removed.
 =item -K
 
 The B<-K> (sure I<kill>) option is like B<-k> except that it removes
-the user's timestamp entirely.  Like B<-k>, this option does not
-require a password.
+the user's timestamp entirely and may not be used in conjunction
+with a command or other option.  This option does not require a
+password.
 
 =item -k
 
-The B<-k> (I<kill>) option to B<sudo> invalidates the user's timestamp
-by setting the time on it to the Epoch.  The next time B<sudo> is
-run a password will be required.  This option does not require a password
-and was added to allow a user to revoke B<sudo> permissions from a .logout
-file.
+When used by itself, the B<-k> (I<kill>) option to B<sudo> invalidates
+the user's timestamp by setting the time on it to the Epoch.  The
+next time B<sudo> is run a password will be required.  This option
+does not require a password and was added to allow a user to revoke
+B<sudo> permissions from a .logout file.
+
+When used in conjunction with a command or an option that may require
+a password, the B<-k> option will cause B<sudo> to ignore the user's
+timestamp file.  As a result, B<sudo> will prompt for a password
+(if one is required by I<sudoers>) and will not update the user's
+timestamp file.
 
 =item -L
 
@@ -570,15 +583,23 @@ To get a file listing of an unreadable directory:
 
  $ sudo ls /usr/local/protected
 
-To list the home directory of user yazza on a machine where the
-file system holding ~yazza is not exported as root:
+To list the home directory of user yaz on a machine where the
+file system holding ~yaz is not exported as root:
 
- $ sudo -u yazza ls ~yazza
+ $ sudo -u yaz ls ~yaz
 
 To edit the F<index.html> file as user www:
 
  $ sudo -u www vi ~www/htdocs/index.html
 
+To view system logs only accessible to root and users in the adm group:
+
+ $ sudo -g adm view /var/log/syslog
+
+To run an editor as jim with a different primary group:
+
+ $ sudo -u jim -g audio vi ~jim/sound.txt
+
 To shutdown a machine:
 
  $ sudo shutdown -r +15 "quick reboot"
index 7d7061758791166c99e1abc8942e5d117b1f6435..138c0e2ad6054b94449ef3312e843a20cb1cac37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #endif /* HAVE_UNISTD_H */
 #include <pwd.h>
 #include <grp.h>
+#include <ctype.h>
 
 #include "sudo.h"
 #include "lbuf.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: sudo_nss.c,v 1.6 2008/02/08 13:18:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: sudo_nss.c,v 1.8 2009/05/25 12:02:41 millert Exp $";
 #endif /* lint */
 
 extern struct sudo_nss sudo_nss_file;
@@ -89,7 +90,7 @@ sudo_read_nss()
                got_match = TRUE;
            } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
                /* NOTFOUND affects the most recent entry */
-               tq_last(&snl)->ret_notfound = TRUE;
+               tq_last(&snl)->ret_if_notfound = TRUE;
                got_match = FALSE;
            } else
                got_match = FALSE;
@@ -109,6 +110,85 @@ nomatch:
 
 #else /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
 
+# if defined(HAVE_LDAP) && defined(_PATH_NETSVC_CONF)
+
+/*
+ * Read in /etc/netsvc.conf (like nsswitch.conf on AIX)
+ * Returns a tail queue of matches.
+ */
+struct sudo_nss_list *
+sudo_read_nss()
+{
+    FILE *fp;
+    char *cp, *ep;
+    int saw_files = FALSE;
+    int saw_ldap = FALSE;
+    int got_match = FALSE;
+    static struct sudo_nss_list snl;
+
+    if ((fp = fopen(_PATH_NETSVC_CONF, "r")) == NULL)
+       goto nomatch;
+
+    while ((cp = sudo_parseln(fp)) != NULL) {
+       /* Skip blank or comment lines */
+       if (*cp == '\0')
+           continue;
+
+       /* Look for a line starting with "sudoers = " */
+       if (strncasecmp(cp, "sudoers", 7) != 0)
+           continue;
+       cp += 7;
+       while (isspace((unsigned char)*cp))
+           cp++;
+       if (*cp++ != '=')
+           continue;
+
+       /* Parse line */
+       for ((cp = strtok(cp, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
+           /* Trim leading whitespace. */
+           while (isspace((unsigned char)*cp))
+               cp++;
+
+           if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
+               (isspace((unsigned char)cp[5]) || cp[5] == '\0')) {
+               tq_append(&snl, &sudo_nss_file);
+               got_match = TRUE;
+               ep = &cp[5];
+           } else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
+               (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
+               tq_append(&snl, &sudo_nss_ldap);
+               got_match = TRUE;
+               ep = &cp[4];
+           } else {
+               got_match = FALSE;
+           }
+
+           /* check for = auth qualifier */
+           if (got_match && *ep) {
+               cp = ep;
+               while (isspace((unsigned char)*cp) || *cp == '=')
+                   cp++;
+               if (strncasecmp(cp, "auth", 4) == 0 &&
+                   (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
+                   tq_last(&snl)->ret_if_found = TRUE;
+               }
+           }
+       }
+       /* Only parse the first "sudoers" line */
+       break;
+    }
+    fclose(fp);
+
+nomatch:
+    /* Default to files only if no matches */
+    if (tq_empty(&snl))
+       tq_append(&snl, &sudo_nss_file);
+
+    return(&snl);
+}
+
+# else /* !_PATH_NETSVC_CONF && !_PATH_NSSWITCH_CONF */
+
 /*
  * Non-nsswitch.conf version with hard-coded order.
  */
@@ -117,14 +197,16 @@ sudo_read_nss()
 {
     static struct sudo_nss_list snl;
 
-# ifdef HAVE_LDAP
+#  ifdef HAVE_LDAP
     tq_append(&snl, &sudo_nss_ldap);
-# endif
+#  endif
     tq_append(&snl, &sudo_nss_file);
 
     return(&snl);
 }
 
+# endif /* !HAVE_LDAP || !_PATH_NETSVC_CONF */
+
 #endif /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
 
 /* Reset user_groups based on passwd entry. */
index 361510f84e73a568d2ace80f9ccbce939efd5cdd..1822465a3730cfdb68481f9ffca1fd8248480855 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Sudo: sudo_nss.h,v 1.5 2008/11/09 14:13:12 millert Exp $
+ * $Sudo: sudo_nss.h,v 1.7 2009/05/25 12:02:42 millert Exp $
  */
 
 struct lbuf;
@@ -32,7 +32,8 @@ struct sudo_nss {
     int (*display_bound_defaults) __P((struct sudo_nss *nss, struct passwd *, struct lbuf *));
     int (*display_privs) __P((struct sudo_nss *nss, struct passwd *, struct lbuf *));
     void *handle;
-    int ret_notfound;
+    short ret_if_found;
+    short ret_if_notfound;
 };
 
 TQ_DECLARE(sudo_nss)
index 5a1bfc60fc7ad8e083860143d03a19e3c540710a..e310b0c8b31990b0df92724b06872294ef931fe8 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Sudo: sudo_usage.h.in,v 1.10 2009/05/25 12:02:42 millert Exp $
+ */
+
 #ifndef _SUDO_USAGE_H
 #define _SUDO_USAGE_H
 
@@ -5,9 +25,10 @@
  * Usage strings for sudo.  These are here because we
  * need to be able to substitute values from configure.
  */
-#define SUDO_USAGE1 " [-n] -h | -K | -k | -L | -V | -v"
-#define SUDO_USAGE2 " -l[l] [-AnS] [-g groupname|#gid] [-U username] [-u username|#uid] [-g groupname|#gid] [command]"
-#define SUDO_USAGE3 " [-AbEHnPS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [<command>]"
-#define SUDO_USAGE4 " -e [-AnS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..."
+#define SUDO_USAGE1 " -h | -K | -k | -L | -V"
+#define SUDO_USAGE2 " -v [-AknS] @BSDAUTH_USAGE@[-p prompt]"
+#define SUDO_USAGE3 " -l[l] [-AknS] @BSDAUTH_USAGE@[-g groupname|#gid] [-p prompt] [-U username] [-u username|#uid] [-g groupname|#gid] [command]"
+#define SUDO_USAGE4 " [-AbEHknPS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [<command>]"
+#define SUDO_USAGE5 " -e [-AknS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..."
 
 #endif /* _SUDO_USAGE_H */
index 8c7876d3fd0d6fe3a9cdac791e2ec28bc4f634c2..1afd9269d3520037b7cf6b835041528a2f983c44 100644 (file)
@@ -61,7 +61,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
 
 
-1.7.0                   December  3, 2008                       1
+1.7.2                     June 30, 2009                         1
 
 
 
@@ -98,6 +98,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                  '!'* '#'uid |
                  '!'* '%'group |
                  '!'* '+'netgroup |
+                 '!'* '%:'nonunix_group |
                  '!'* User_Alias
 
        A User_List is made up of one or more usernames, uids (prefixed with
@@ -106,6 +107,35 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        operators.  An odd number of '!' operators negate the value of the
        item; an even number just cancel each other out.
 
+       A username, group, netgroup and nonunix_groups may be enclosed in
+       double quotes to avoid the need for escaping special characters.
+       Alternately, special characters may be specified in escaped hex mode,
+       e.g. \x20 for space.
+
+       The nonunix_group syntax depends on the underlying implementation.  For
+       instance, the QAS AD backend supports the following formats:
+
+       +\bo   Group in the same domain: "Group Name"
+
+       +\bo   Group in any domain: "Group Name@FULLY.QUALIFIED.DOMAIN"
+
+       +\bo   Group SID: "S-1-2-34-5678901234-5678901234-5678901234-567"
+
+       Note that quotes around group names are optional.  Unquoted strings
+       must use a backslash (\) to escape spaces and the '@' symbol.
+
+
+
+
+1.7.2                     June 30, 2009                         2
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
         Runas_List ::= Runas_Member |
                        Runas_Member ',' Runas_List
 
@@ -125,18 +155,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
         Host_List ::= Host |
                       Host ',' Host_List
 
-
-
-1.7.0                   December  3, 2008                       2
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
-
         Host ::= '!'* hostname |
                  '!'* ip_addr |
                  '!'* network(/netmask)? |
@@ -172,6 +190,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        other aliases.  A commandname is a fully qualified filename which may
        include shell-style wildcards (see the Wildcards section below).  A
        simple filename allows the user to run the command with any arguments
+
+
+
+1.7.2                     June 30, 2009                         3
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
        he/she wishes.  However, you may also specify command line arguments
        (including wildcards).  Alternately, you can specify "" to indicate
        that the command may only be run w\bwi\bit\bth\bho\bou\but\bt command line arguments.  A
@@ -187,21 +217,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        to permit a user to run s\bsu\bud\bdo\bo with the -\b-e\be option (or as s\bsu\bud\bdo\boe\bed\bdi\bit\bt).  It
        may take command line arguments just as a normal command does.
 
-
-
-
-
-
-
-1.7.0                   December  3, 2008                       3
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        D\bDe\bef\bfa\bau\bul\blt\bts\bs
 
        Certain configuration options may be changed from their default values
@@ -241,33 +256,33 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        not exist in a list.
 
        Defaults entries are parsed in the following order: generic, host and
-       user Defaults first, then runas Defaults and finally command defaults.
 
-       See "SUDOERS OPTIONS" for a list of supported Defaults parameters.
 
-       U\bUs\bse\ber\br S\bSp\bpe\bec\bci\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 
-        User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \
-                      (':' Host_List '=' Cmnd_Spec_List)*
+1.7.2                     June 30, 2009                         4
 
-        Cmnd_Spec_List ::= Cmnd_Spec |
-                           Cmnd_Spec ',' Cmnd_Spec_List
 
-        Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
 
-        Runas_Spec ::= '(' Runas_List? (: Runas_List)? ')'
 
 
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
-1.7.0                   December  3, 2008                       4
 
+       user Defaults first, then runas Defaults and finally command defaults.
 
+       See "SUDOERS OPTIONS" for a list of supported Defaults parameters.
 
+       U\bUs\bse\ber\br S\bSp\bpe\bec\bci\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 
+        User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \
+                      (':' Host_List '=' Cmnd_Spec_List)*
 
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+        Cmnd_Spec_List ::= Cmnd_Spec |
+                           Cmnd_Spec ',' Cmnd_Spec_List
 
+        Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
 
+        Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
 
         Tag_Spec ::= ('NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' |
                       'SETENV:' | 'NOSETENV:' )
@@ -276,7 +291,8 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        what user) on specified hosts.  By default, commands are run as r\bro\boo\bot\bt,
        but this can be changed on a per-command basis.
 
-       Let's break that down into its constituent parts:
+       The basic structure of a user specification is `who = where (as_whom)
+       what'.  Let's break that down into its constituent parts:
 
        R\bRu\bun\bna\bas\bs_\b_S\bSp\bpe\bec\bc
 
@@ -307,6 +323,17 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        It is also possible to override a Runas_Spec later on in an entry.  If
        we modify the entry like so:
 
+
+
+1.7.2                     June 30, 2009                         5
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
         dgb    boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
 
        Then user d\bdg\bgb\bb is now allowed to run _\b/_\bb_\bi_\bn_\b/_\bl_\bs as o\bop\bpe\ber\bra\bat\bto\bor\br, but  _\b/_\bb_\bi_\bn_\b/_\bk_\bi_\bl_\bl
@@ -322,18 +349,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        device file with the dialer group.  Note that in this example only the
        group will be set, the command still runs as user t\btc\bcm\bm.
 
-
-
-
-1.7.0                   December  3, 2008                       5
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
         tcm    boulder = (:dialer) /usr/bin/tip, /usr/bin/cu, \
                /usr/local/bin/minicom
 
@@ -374,31 +389,30 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
        _\bN_\bO_\bE_\bX_\bE_\bC _\ba_\bn_\bd _\bE_\bX_\bE_\bC
 
-       If s\bsu\bud\bdo\bo has been compiled with _\bn_\bo_\be_\bx_\be_\bc support and the underlying
-       operating system supports it, the NOEXEC tag can be used to prevent a
-       dynamically-linked executable from running further commands itself.
 
-       In the following example, user a\baa\bar\bro\bon\bn may run _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bm_\bo_\br_\be and
-       _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bv_\bi but shell escapes will be disabled.
 
-        aaron  shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+1.7.2                     June 30, 2009                         6
 
-       See the "PREVENTING SHELL ESCAPES" section below for more details on
-       how NOEXEC works and whether or not it will work on your system.
 
-       _\bS_\bE_\bT_\bE_\bN_\bV _\ba_\bn_\bd _\bN_\bO_\bS_\bE_\bT_\bE_\bN_\bV
 
 
 
-
-1.7.0                   December  3, 2008                       6
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
+       If s\bsu\bud\bdo\bo has been compiled with _\bn_\bo_\be_\bx_\be_\bc support and the underlying
+       operating system supports it, the NOEXEC tag can be used to prevent a
+       dynamically-linked executable from running further commands itself.
 
+       In the following example, user a\baa\bar\bro\bon\bn may run _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bm_\bo_\br_\be and
+       _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bv_\bi but shell escapes will be disabled.
 
+        aaron  shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
 
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+       See the "PREVENTING SHELL ESCAPES" section below for more details on
+       how NOEXEC works and whether or not it will work on your system.
 
+       _\bS_\bE_\bT_\bE_\bN_\bV _\ba_\bn_\bd _\bN_\bO_\bS_\bE_\bT_\bE_\bN_\bV
 
        These tags override the value of the _\bs_\be_\bt_\be_\bn_\bv option on a per-command
        basis.  Note that if SETENV has been set for a command, any environment
@@ -412,8 +426,8 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
        s\bsu\bud\bdo\bo allows shell-style _\bw_\bi_\bl_\bd_\bc_\ba_\br_\bd_\bs (aka meta or glob characters) to be
        used in hostnames, pathnames and command line arguments in the _\bs_\bu_\bd_\bo_\be_\br_\bs
-       file.  Wildcard matching is done via the P\bPO\bOS\bSI\bIX\bX _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3) routine.
-       Note that these are _\bn_\bo_\bt regular expressions.
+       file.  Wildcard matching is done via the P\bPO\bOS\bSI\bIX\bX _\bg_\bl_\bo_\bb(3) and _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3)
+       routines.  Note that these are _\bn_\bo_\bt regular expressions.
 
        *       Matches any set of zero or more characters.
 
@@ -426,9 +440,9 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        \x      For any character "x", evaluates to "x".  This is used to
                escape special characters such as: "*", "?", "[", and "}".
 
-       POSIX character classes may also be used if your system's _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3)
-       function supports them.  However, because the ':' character has special
-       meaning in _\bs_\bu_\bd_\bo_\be_\br_\bs, it must be escaped.  For example:
+       POSIX character classes may also be used if your system's _\bg_\bl_\bo_\bb(3) and
+       _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3) functions support them.  However, because the ':' character
+       has special meaning in _\bs_\bu_\bd_\bo_\be_\br_\bs, it must be escaped.  For example:
 
            /bin/ls [[\:alpha\:]]*
 
@@ -440,6 +454,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
            /usr/bin/*
 
+
+
+
+1.7.2                     June 30, 2009                         7
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
        match _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bw_\bh_\bo but not _\b/_\bu_\bs_\br_\b/_\bb_\bi_\bn_\b/_\bX_\b1_\b1_\b/_\bx_\bt_\be_\br_\bm.
 
        E\bEx\bxc\bce\bep\bpt\bti\bio\bon\bns\bs t\bto\bo w\bwi\bil\bld\bdc\bca\bar\brd\bd r\bru\bul\ble\bes\bs
@@ -453,34 +479,62 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        I\bIn\bnc\bcl\blu\bud\bdi\bin\bng\bg o\bot\bth\bhe\ber\br f\bfi\bil\ble\bes\bs f\bfr\bro\bom\bm w\bwi\bit\bth\bhi\bin\bn s\bsu\bud\bdo\boe\ber\brs\bs
 
        It is possible to include other _\bs_\bu_\bd_\bo_\be_\br_\bs files from within the _\bs_\bu_\bd_\bo_\be_\br_\bs
-       file currently being parsed using the #include directive, similar to
+       file currently being parsed using the #include and #includedir
+       directives.
 
+       This can be used, for example, to keep a site-wide _\bs_\bu_\bd_\bo_\be_\br_\bs file in
+       addition to a local, per-machine file.  For the sake of this example
+       the site-wide _\bs_\bu_\bd_\bo_\be_\br_\bs will be _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs and the per-machine one will
+       be _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl.  To include _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl from within
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs we would use the following line in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs:
 
+           #include /etc/sudoers.local
 
-1.7.0                   December  3, 2008                       7
+       When s\bsu\bud\bdo\bo reaches this line it will suspend processing of the current
+       file (_\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs) and switch to _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl.  Upon reaching
+       the end of _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl, the rest of _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs will be
+       processed.  Files that are included may themselves include other files.
+       A hard limit of 128 nested include files is enforced to prevent include
+       file loops.
 
+       The filename may include the %h escape, signifying the short form of
+       the hostname.  I.e., if the machine's hostname is "xerxes", then
 
+       #include /etc/sudoers.%h
 
+       will cause s\bsu\bud\bdo\bo to include the file _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bx_\be_\br_\bx_\be_\bs.
 
+       The #includedir directive can be used to create a _\bs_\bu_\bd_\bo_\b._\bd directory that
+       the system package manager can drop _\bs_\bu_\bd_\bo_\be_\br_\bs rules into as part of
+       package installation.  For example, given:
 
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+       #includedir /etc/sudoers.d
 
+       s\bsu\bud\bdo\bo will read each file in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bd, skipping file names that
+       end in ~ or contain a . character to avoid causing problems with
+       package manager or editor temporary/backup files.  Files are parsed in
+       sorted lexical order.  That is, _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bd_\b/_\b0_\b1_\b__\bf_\bi_\br_\bs_\bt will be parsed
+       before _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bd_\b/_\b1_\b0_\b__\bs_\be_\bc_\bo_\bn_\bd.  Be aware that because the sorting is
+       lexical, not numeric, _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bd_\b/_\b1_\b__\bw_\bh_\bo_\bo_\bp_\bs would be loaded a\baf\bft\bte\ber\br
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bd_\b/_\b1_\b0_\b__\bs_\be_\bc_\bo_\bn_\bd.  Using a consistent number of leading zeroes
+       in the file names can be used to avoid such problems.
 
-       the one used by the C preprocessor.  This is useful, for example, for
-       keeping a site-wide _\bs_\bu_\bd_\bo_\be_\br_\bs file in addition to a per-machine local
-       one.  For the sake of this example the site-wide _\bs_\bu_\bd_\bo_\be_\br_\bs will be
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs and the per-machine one will be _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl.  To
-       include _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl from _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs we would use the following
-       line in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs:
+       Note that unlike files included via #include, v\bvi\bis\bsu\bud\bdo\bo will not edit the
 
-        #include /etc/sudoers.local
 
-       When s\bsu\bud\bdo\bo reaches this line it will suspend processing of the current
-       file (_\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs) and switch to _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl.  Upon reaching
-       the end of _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl, the rest of _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs will be
-       processed.  Files that are included may themselves include other files.
-       A hard limit of 128 nested include files is enforced to prevent include
-       file loops.
+
+1.7.2                     June 30, 2009                         8
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
+       files in a #includedir directory unless one of them contains a syntax
+       error.  It is still possible to run v\bvi\bis\bsu\bud\bdo\bo with the -f flag to edit the
+       files directly.
 
        O\bOt\bth\bhe\ber\br s\bsp\bpe\bec\bci\bia\bal\bl c\bch\bha\bar\bra\bac\bct\bte\ber\brs\bs a\ban\bnd\bd r\bre\bes\bse\ber\brv\bve\bed\bd w\bwo\bor\brd\bds\bs
 
@@ -521,17 +575,6 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
        F\bFl\bla\bag\bgs\bs:
 
-
-
-1.7.0                   December  3, 2008                       8
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        always_set_home If set, s\bsu\bud\bdo\bo will set the HOME environment variable to
                        the home directory of the target user (which is root
                        unless the -\b-u\bu option is used).  This effectively means
@@ -544,6 +587,17 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        the PASSWD and NOPASSWD tags.  This flag is _\bo_\bn by
                        default.
 
+
+
+1.7.2                     June 30, 2009                         9
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
        closefrom_override
                        If set, the user may use s\bsu\bud\bdo\bo's -\b-C\bC option which
                        overrides the default starting point at which s\bsu\bud\bdo\bo
@@ -586,18 +640,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        qualified you shouldn't need to set _\bf_\bq_\bd_\bn.  This flag is
                        _\bo_\bf_\bf by default.
 
-
-
-
-1.7.0                   December  3, 2008                       9
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        ignore_dot      If set, s\bsu\bud\bdo\bo will ignore '.' or '' (current dir) in the
                        PATH environment variable; the PATH itself is not
                        modified.  This flag is _\bo_\bf_\bf by default.
@@ -610,6 +652,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        operators who would attempt to add roles to
                        _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  When this option is present,
                        _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs does not even need to exist. Since this
+
+
+
+1.7.2                     June 30, 2009                        10
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                        option tells s\bsu\bud\bdo\bo how to behave when no specific LDAP
                        entries have been matched, this sudoOption is only
                        meaningful for the cn=defaults section.  This flag is
@@ -653,17 +707,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        invoking user is not in the _\bs_\bu_\bd_\bo_\be_\br_\bs file.  This flag is
                        _\bo_\bn by default.
 
-
-
-1.7.0                   December  3, 2008                      10
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        noexec          If set, all commands run via s\bsu\bud\bdo\bo will behave as if the
                        NOEXEC tag has been set, unless overridden by a EXEC
                        tag.  See the description of _\bN_\bO_\bE_\bX_\bE_\bC _\ba_\bn_\bd _\bE_\bX_\bE_\bC below as
@@ -675,6 +718,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        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
+
+
+
+1.7.2                     June 30, 2009                        11
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                        disadvantage is that if the executable is simply not in
                        the user's PATH, s\bsu\bud\bdo\bo will tell the user that they are
                        not allowed to run it, which can be confusing.  This
@@ -687,13 +742,23 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        _\bp_\ba_\bs_\bs_\bp_\br_\bo_\bm_\bp_\bt_\b__\bo_\bv_\be_\br_\br_\bi_\bd_\be is set, _\bp_\ba_\bs_\bs_\bp_\br_\bo_\bm_\bp_\bt will always be
                        used.  This flag is _\bo_\bf_\bf by default.
 
-       preserve_groups By default s\bsu\bud\bdo\bo will initialize the group vector to the
-                       list of groups the target user is in.  When
+       preserve_groups By default, s\bsu\bud\bdo\bo will initialize the group vector to
+                       the list of groups the target user is in.  When
                        _\bp_\br_\be_\bs_\be_\br_\bv_\be_\b__\bg_\br_\bo_\bu_\bp_\bs is set, the user's existing group
                        vector is left unaltered.  The real and effective group
                        IDs, however, are still set to match the target user.
                        This flag is _\bo_\bf_\bf by default.
 
+       pwfeedback      By default, s\bsu\bud\bdo\bo reads the password like most other
+                       Unix programs, by turning off echo until the user hits
+                       the return (or enter) key.  Some users become confused
+                       by this as it appears to them that s\bsu\bud\bdo\bo has hung at
+                       this point.  When _\bp_\bw_\bf_\be_\be_\bd_\bb_\ba_\bc_\bk is set, s\bsu\bud\bdo\bo will provide
+                       visual feedback when the user presses a key.  Note that
+                       this does have a security impact as an onlooker may be
+                       able to determine the length of the password being
+                       entered.  This flag is _\bo_\bf_\bf by default.
+
        requiretty      If set, s\bsu\bud\bdo\bo will only run when the user is logged in
                        to a real tty.  When this flag is set, s\bsu\bud\bdo\bo can only be
                        run from a login session and not via other means such
@@ -718,10 +783,11 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        instead of the password of the invoking user.  This
                        flag is _\bo_\bf_\bf by default.
 
+       set_home        If set and s\bsu\bud\bdo\bo is invoked with the -\b-s\bs option the HOME
 
 
 
-1.7.0                   December  3, 2008                      11
+1.7.2                     June 30, 2009                        12
 
 
 
@@ -730,7 +796,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-       set_home        If set and s\bsu\bud\bdo\bo is invoked with the -\b-s\bs option the HOME
                        environment variable will be set to the home directory
                        of the target user (which is root unless the -\b-u\bu option
                        is used).  This effectively makes the -\b-s\bs option imply
@@ -762,6 +827,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        shell listed in the invoking user's /etc/passwd entry
                        if not).  This flag is _\bo_\bf_\bf by default.
 
+       fast_glob       Normally, s\bsu\bud\bdo\bo uses the _\bg_\bl_\bo_\bb(3) function to do shell-
+                       style globbing when matching pathnames.  However, since
+                       it accesses the file system, _\bg_\bl_\bo_\bb(3) can take a long
+                       time to complete for some patterns, especially when the
+                       pattern references a network file system that is
+                       mounted on demand (automounted).  The _\bf_\ba_\bs_\bt_\b__\bg_\bl_\bo_\bb option
+                       causes s\bsu\bud\bdo\bo to use the _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3) function, which does
+                       not access the file system to do its matching.  The
+                       disadvantage of _\bf_\ba_\bs_\bt_\b__\bg_\bl_\bo_\bb is that it is unable to match
+                       relative pathnames such as _\b._\b/_\bl_\bs or _\b._\b._\b/_\bb_\bi_\bn_\b/_\bl_\bs.  This
+                       flag is _\bo_\bf_\bf by default.
+
        stay_setuid     Normally, when s\bsu\bud\bdo\bo executes a command the real and
                        effective UIDs are set to the target user (root by
                        default).  This option changes that behavior such that
@@ -773,21 +850,10 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        with either the _\bs_\be_\bt_\br_\be_\bu_\bi_\bd_\b(_\b) or _\bs_\be_\bt_\br_\be_\bs_\bu_\bi_\bd_\b(_\b) function.
                        This flag is _\bo_\bf_\bf by default.
 
-       targetpw        If set, s\bsu\bud\bdo\bo will prompt for the password of the user
-                       specified by the -\b-u\bu option (defaults to root) instead
-                       of the password of the invoking user.  Note that this
-                       precludes the use of a uid not listed in the passwd
-                       database as an argument to the -\b-u\bu option.  This flag is
-                       _\bo_\bf_\bf by default.
 
-       tty_tickets     If set, users must authenticate on a per-tty basis.
-                       Normally, s\bsu\bud\bdo\bo uses a directory in the ticket dir with
-                       the same name as the user running it.  With this flag
-                       enabled, s\bsu\bud\bdo\bo will use a file named for the tty the
 
 
-
-1.7.0                   December  3, 2008                      12
+1.7.2                     June 30, 2009                        13
 
 
 
@@ -796,9 +862,28 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
+       targetpw        If set, s\bsu\bud\bdo\bo will prompt for the password of the user
+                       specified by the -\b-u\bu option (defaults to root) instead
+                       of the password of the invoking user.  Note that this
+                       precludes the use of a uid not listed in the passwd
+                       database as an argument to the -\b-u\bu option.  This flag is
+                       _\bo_\bf_\bf by default.
+
+       tty_tickets     If set, users must authenticate on a per-tty basis.
+                       Normally, s\bsu\bud\bdo\bo uses a directory in the ticket dir with
+                       the same name as the user running it.  With this flag
+                       enabled, s\bsu\bud\bdo\bo will use a file named for the tty the
                        user is logged in on in that directory.  This flag is
                        _\bo_\bf_\bf by default.
 
+       umask_override  If set, s\bsu\bud\bdo\bo will set the umask as specified by _\bs_\bu_\bd_\bo_\be_\br_\bs
+                       without modification.  This makes it possible to
+                       specify a more permissive umask in _\bs_\bu_\bd_\bo_\be_\br_\bs than the
+                       user's own umask and matches historical behavior.  If
+                       _\bu_\bm_\ba_\bs_\bk_\b__\bo_\bv_\be_\br_\br_\bi_\bd_\be is not set, s\bsu\bud\bdo\bo will set the umask to
+                       be the union of the user's umask and what is specified
+                       in _\bs_\bu_\bd_\bo_\be_\br_\bs.  This flag is _\bo_\bf_\bf by default.
+
        use_loginclass  If set, s\bsu\bud\bdo\bo will apply the defaults specified for the
                        target user's login class if one exists.  Only
                        available if s\bsu\bud\bdo\bo is configured with the
@@ -831,6 +916,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        value is used to decide when to wrap lines for nicer
                        log files.  This has no effect on the syslog log file,
                        only the file log.  The default is 80 (use 0 or negate
+
+
+
+1.7.2                     June 30, 2009                        14
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                        the option to disable word wrap).
 
        passwd_timeout  Number of minutes before the s\bsu\bud\bdo\bo password prompt times
@@ -850,18 +947,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        option or set it to 0777 to preserve the user's umask.
                        The actual umask that is used will be the union of the
                        user's umask and 0022.  This guarantees that s\bsu\bud\bdo\bo never
-
-
-
-1.7.0                   December  3, 2008                      13
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
                        lowers the umask when running a command.  Note on
                        systems that use PAM, the default PAM configuration may
                        specify its own umask which will override the value set
@@ -897,6 +982,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        escapes are supported:
 
                        %H  expanded to the local hostname including the domain
+
+
+
+1.7.2                     June 30, 2009                        15
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                            name (on if the machine's hostname is fully
                            qualified or the _\bf_\bq_\bd_\bn option is set)
 
@@ -917,17 +1014,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
                        The default value is Password:.
 
-
-
-1.7.0                   December  3, 2008                      14
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        runas_default   The default user to run commands as if the -\b-u\bu option is
                        not specified on the command line.  This defaults to
                        root.  Note that if _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt is set it m\bmu\bus\bst\bt occur
@@ -962,37 +1048,38 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                    variable.
 
        env_file    The _\be_\bn_\bv_\b__\bf_\bi_\bl_\be options specifies the fully qualified path to
-                   a file containing variables to be set in the environment of
-                   the program being run.  Entries in this file should be of
-                   the form VARIABLE=value.  Variables in this file are
-                   subject to other s\bsu\bud\bdo\bo environment settings such as _\be_\bn_\bv_\b__\bk_\be_\be_\bp
-                   and _\be_\bn_\bv_\b__\bc_\bh_\be_\bc_\bk.
 
-       exempt_group
-                   Users in this group are exempt from password and PATH
-                   requirements.  This is not set by default.
 
-       lecture     This option controls when a short lecture will be printed
-                   along with the password prompt.  It has the following
-                   possible values:
 
-                   always  Always lecture the user.
+1.7.2                     June 30, 2009                        16
 
-                   never   Never lecture the user.
 
-                   once    Only lecture the user the first time they run s\bsu\bud\bdo\bo.
 
 
 
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
-1.7.0                   December  3, 2008                      15
 
+                   a file containing variables to be set in the environment of
+                   the program being run.  Entries in this file should either
+                   be of the form VARIABLE=value or export VARIABLE=value.
+                   The value may optionally be surrounded by single or double
+                   quotes.  Variables in this file are subject to other s\bsu\bud\bdo\bo
+                   environment settings such as _\be_\bn_\bv_\b__\bk_\be_\be_\bp and _\be_\bn_\bv_\b__\bc_\bh_\be_\bc_\bk.
 
+       exempt_group
+                   Users in this group are exempt from password and PATH
+                   requirements.  This is not set by default.
 
+       lecture     This option controls when a short lecture will be printed
+                   along with the password prompt.  It has the following
+                   possible values:
 
+                   always  Always lecture the user.
 
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+                   never   Never lecture the user.
 
+                   once    Only lecture the user the first time they run s\bsu\bud\bdo\bo.
 
                    If no value is specified, a value of _\bo_\bn_\bc_\be is implied.
                    Negating the option results in a value of _\bn_\be_\bv_\be_\br being used.
@@ -1027,6 +1114,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
        logfile     Path to the s\bsu\bud\bdo\bo log file (not the syslog log file).
                    Setting a path turns on logging to a file; negating this
+
+
+
+1.7.2                     June 30, 2009                        17
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                    option turns it off.  By default, s\bsu\bud\bdo\bo logs via syslog.
 
        mailerflags Flags to use when invoking mailer. Defaults to -\b-t\bt.
@@ -1048,18 +1147,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                    environment variable you may want to use this.  Another use
                    is if you want to have the "root path" be separate from the
                    "user path."  Users in the group specified by the
-
-
-
-1.7.0                   December  3, 2008                      16
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
                    _\be_\bx_\be_\bm_\bp_\bt_\b__\bg_\br_\bo_\bu_\bp option are not affected by _\bs_\be_\bc_\bu_\br_\be_\b__\bp_\ba_\bt_\bh.  This
                    is not set by default.
 
@@ -1093,6 +1180,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        env_check       Environment variables to be removed from the user's
                        environment if the variable's value contains % or /
                        characters.  This can be used to guard against printf-
+
+
+
+1.7.2                     June 30, 2009                        18
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                        style format vulnerabilities in poorly-written
                        programs.  The argument may be a double-quoted, space-
                        separated list or a single value without double-quotes.
@@ -1106,28 +1205,16 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        is run by root with the _\b-_\bV option.
 
        env_delete      Environment variables to be removed from the user's
-                       environment.  The argument may be a double-quoted,
-                       space-separated list or a single value without double-
-                       quotes.  The list can be replaced, added to, deleted
-                       from, or disabled by using the =, +=, -=, and !
-                       operators respectively.  The default list of
-                       environment variables to remove is displayed when s\bsu\bud\bdo\bo
-                       is run by root with the _\b-_\bV option.  Note that many
-                       operating systems will remove potentially dangerous
-
-
-
-1.7.0                   December  3, 2008                      17
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
-                       variables from the environment of any setuid process
-                       (such as s\bsu\bud\bdo\bo).
+                       environment when the _\be_\bn_\bv_\b__\br_\be_\bs_\be_\bt option is not in effect.
+                       The argument may be a double-quoted, space-separated
+                       list or a single value without double-quotes.  The list
+                       can be replaced, added to, deleted from, or disabled by
+                       using the =, +=, -=, and ! operators respectively.  The
+                       default list of environment variables to remove is
+                       displayed when s\bsu\bud\bdo\bo is run by root with the _\b-_\bV option.
+                       Note that many operating systems will remove
+                       potentially dangerous variables from the environment of
+                       any setuid process (such as s\bsu\bud\bdo\bo).
 
        env_keep        Environment variables to be preserved in the user's
                        environment when the _\be_\bn_\bv_\b__\br_\be_\bs_\be_\bt option is in effect.
@@ -1158,6 +1245,19 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
        Below are example _\bs_\bu_\bd_\bo_\be_\br_\bs entries.  Admittedly, some of these are a bit
        contrived.  First, we define our _\ba_\bl_\bi_\ba_\bs_\be_\bs:
 
+
+
+
+
+1.7.2                     June 30, 2009                        19
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
         # User alias specification
         User_Alias     FULLTIMERS = millert, mikef, dowdy
         User_Alias     PARTTIMERS = bostley, jwfox, crawl
@@ -1166,6 +1266,7 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
         # Runas alias specification
         Runas_Alias    OP = root, operator
         Runas_Alias    DB = oracle, sybase
+        Runas_Alias    ADMINGRP = adm, oper
 
         # Host alias specification
         Host_Alias     SPARC = bigtime, eclipse, moet, anchor :\
@@ -1180,18 +1281,6 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
         # Cmnd alias specification
         Cmnd_Alias     DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
                                /usr/sbin/restore, /usr/sbin/rrestore
-
-
-
-1.7.0                   December  3, 2008                      18
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
         Cmnd_Alias     KILL = /usr/bin/kill
         Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm
         Cmnd_Alias     SHUTDOWN = /usr/sbin/shutdown
@@ -1223,6 +1312,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
         Defaults!PAGERS        noexec
 
        The _\bU_\bs_\be_\br _\bs_\bp_\be_\bc_\bi_\bf_\bi_\bc_\ba_\bt_\bi_\bo_\bn is the part that actually determines who may run
+
+
+
+1.7.2                     June 30, 2009                        20
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
        what.
 
         root           ALL = (ALL) ALL
@@ -1246,18 +1347,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
        The user j\bja\bac\bck\bk may run any command on the machines in the _\bC_\bS_\bN_\bE_\bT_\bS alias
        (the networks 128.138.243.0, 128.138.204.0, and 128.138.242.0).  Of
-
-
-
-1.7.0                   December  3, 2008                      19
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        those networks, only 128.138.204.0 has an explicit netmask (in CIDR
        notation) indicating it is a class C network.  For the other networks
        in _\bC_\bS_\bN_\bE_\bT_\bS, the local machine's netmask will be used during matching.
@@ -1281,10 +1370,26 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
         pete           HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
 
+        %opers         ALL = (: ADMINGRP) /usr/sbin/
+
+       Users in the o\bop\bpe\ber\brs\bs group may run commands in _\b/_\bu_\bs_\br_\b/_\bs_\bb_\bi_\bn_\b/ as themselves
+       with any group in the _\bA_\bD_\bM_\bI_\bN_\bG_\bR_\bP Runas_Alias (the a\bad\bdm\bm and o\bop\bpe\ber\br groups).
+
        The user p\bpe\bet\bte\be is allowed to change anyone's password except for root on
        the _\bH_\bP_\bP_\bA machines.  Note that this assumes _\bp_\ba_\bs_\bs_\bw_\bd(1) does not take
        multiple usernames on the command line.
 
+
+
+1.7.2                     June 30, 2009                        21
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
         bob            SPARC = (OP) ALL : SGI = (OP) ALL
 
        The user b\bbo\bob\bb may run anything on the _\bS_\bP_\bA_\bR_\bC and _\bS_\bG_\bI machines as any user
@@ -1313,17 +1418,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
         jen            ALL, !SERVERS = ALL
 
-
-
-1.7.0                   December  3, 2008                      20
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        The user j\bje\ben\bn may run any command on any machine except for those in the
        _\bS_\bE_\bR_\bV_\bE_\bR_\bS Host_Alias (master, mail, www and ns).
 
@@ -1349,6 +1443,19 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        and wim), may run any command as user www (which owns the web pages) or
        simply _\bs_\bu(1) to www.
 
+
+
+
+
+1.7.2                     June 30, 2009                        22
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
         ALL            CDROM = NOPASSWD: /sbin/umount /CDROM,\
                        /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
 
@@ -1379,17 +1486,6 @@ P\bPR\bRE\bEV\bVE\bEN\bNT\bTI\bIN\bNG\bG S\bSH\bHE\bEL\bLL\bL E\bES\bSC\bCA\bAP\bPE\bES\bS
        that permit shell escapes include shells (obviously), editors,
        paginators, mail and terminal programs.
 
-
-
-1.7.0                   December  3, 2008                      21
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        There are two basic approaches to this problem:
 
        restrict  Avoid giving users access to commands that allow the user to
@@ -1414,6 +1510,18 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
                      sudo -V | grep "dummy exec"
 
+
+
+
+1.7.2                     June 30, 2009                        23
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
                  If the resulting output contains a line that begins with:
 
                      File containing dummy exec functions:
@@ -1444,24 +1552,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
        Note that restricting shell escapes is not a panacea.  Programs running
        as root are still capable of many potentially hazardous operations
-
-
-
-1.7.0                   December  3, 2008                      22
-
-
-
-
-
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
-
-
        (such as changing or overwriting files) that could lead to unintended
        privilege escalation.  In the specific case of an editor, a safer
        approach is to give the user permission to run s\bsu\bud\bdo\boe\bed\bdi\bit\bt.
 
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
-       _\br_\bs_\bh(1), _\bs_\bu(1), _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3), _\bs_\bu_\bd_\bo(1m), _\bv_\bi_\bs_\bu_\bd_\bo(8)
+       _\br_\bs_\bh(1), _\bs_\bu(1), _\bf_\bn_\bm_\ba_\bt_\bc_\bh(3), _\bg_\bl_\bo_\bb(3), _\bs_\bu_\bd_\bo(1m), _\bv_\bi_\bs_\bu_\bd_\bo(8)
 
 C\bCA\bAV\bVE\bEA\bAT\bTS\bS
        The _\bs_\bu_\bd_\bo_\be_\br_\bs file should a\bal\blw\bwa\bay\bys\bs be edited by the v\bvi\bis\bsu\bud\bdo\bo command which
@@ -1480,6 +1576,18 @@ B\bBU\bUG\bGS\bS
 
 S\bSU\bUP\bPP\bPO\bOR\bRT\bT
        Limited free support is available via the sudo-users mailing list, see
+
+
+
+1.7.2                     June 30, 2009                        24
+
+
+
+
+
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
+
        http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
        the archives.
 
@@ -1513,6 +1621,30 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.7.0                   December  3, 2008                      23
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.7.2                     June 30, 2009                        25
 
 
index 8b581ffd4537d4c36adc5e943e2a469fdb9e2a96..234931dea9994e28f152476ca994b0e1d6e4167a 100644 (file)
@@ -26,17 +26,17 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            prevent s\bsu\bud\bdo\bo from running.
 
        +\bo   It is possible to specify per-entry options that override the
-           global default options.  _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs only supports default
-           options and limited options associated with
-           user/host/commands/aliases.  The syntax is complicated and can be
-           difficult for users to understand.  Placing the options directly in
-           the entry is more natural.
+           global default options.  _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs only supports default options
+           and limited options associated with user/host/commands/aliases.
+           The syntax is complicated and can be difficult for users to
+           understand.  Placing the options directly in the entry is more
+           natural.
 
        +\bo   The v\bvi\bis\bsu\bud\bdo\bo program is no longer needed.  v\bvi\bis\bsu\bud\bdo\bo provides locking
-           and syntax checking of the _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs file.  Since LDAP
-           updates are atomic, locking is no longer necessary.  Because syntax
-           is checked when the data is inserted into LDAP, there is no need
-           for a specialized tool to check syntax.
+           and syntax checking of the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs file.  Since LDAP updates
+           are atomic, locking is no longer necessary.  Because syntax is
+           checked when the data is inserted into LDAP, there is no need for a
+           specialized tool to check syntax.
 
        Another major difference between LDAP and file-based _\bs_\bu_\bd_\bo_\be_\br_\bs is that in
        LDAP, s\bsu\bud\bdo\bo-specific Aliases are not supported.
@@ -61,7 +61,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
 
 
-1.7.0                    October 24, 2008                       1
+1.7.2                     June 11, 2009                         1
 
 
 
@@ -71,8 +71,8 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
        found, the multi-valued sudoOption attribute is parsed in the same
-       manner as a global Defaults line in _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  In the
-       following example, the SSH_AUTH_SOCK variable will be preserved in the
+       manner as a global Defaults line in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  In the following
+       example, the SSH_AUTH_SOCK variable will be preserved in the
        environment for all users.
 
            dn: cn=defaults,ou=SUDOers,dc=example,dc=com
@@ -127,7 +127,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
 
-1.7.0                    October 24, 2008                       2
+1.7.2                     June 11, 2009                         2
 
 
 
@@ -193,7 +193,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
 
-1.7.0                    October 24, 2008                       3
+1.7.2                     June 11, 2009                         3
 
 
 
@@ -240,26 +240,26 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
        C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg l\bld\bda\bap\bp.\b.c\bco\bon\bnf\bf
 
-       Sudo reads the _\b@_\bl_\bd_\ba_\bp_\b__\bc_\bo_\bn_\bf_\b@ file for LDAP-specific configuration.
+       Sudo reads the _\b/_\be_\bt_\bc_\b/_\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf file for LDAP-specific configuration.
        Typically, this file is shared amongst different LDAP-aware clients.
        As such, most of the settings are not s\bsu\bud\bdo\bo-specific.  Note that s\bsu\bud\bdo\bo
-       parses _\b@_\bl_\bd_\ba_\bp_\b__\bc_\bo_\bn_\bf_\b@ itself and may support options that differ from
+       parses _\b/_\be_\bt_\bc_\b/_\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf itself and may support options that differ from
        those described in the _\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf(4) manual.
 
        Also note that on systems using the OpenLDAP libraries, default values
        specified in _\b/_\be_\bt_\bc_\b/_\bo_\bp_\be_\bn_\bl_\bd_\ba_\bp_\b/_\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf or the user's _\b._\bl_\bd_\ba_\bp_\br_\bc files are
        not used.
 
-       Only those options explicitly listed in _\b@_\bl_\bd_\ba_\bp_\b__\bc_\bo_\bn_\bf_\b@ that are supported
-       by s\bsu\bud\bdo\bo are honored.  Configuration options are listed below in upper
-       case but are parsed in a case-independent manner.
+       Only those options explicitly listed in _\b/_\be_\bt_\bc_\b/_\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf that are
+       supported by s\bsu\bud\bdo\bo are honored.  Configuration options are listed below
+       in upper case but are parsed in a case-independent manner.
 
        U\bUR\bRI\bI ldap[s]://[hostname[:port]] ...
            Specifies a whitespace-delimited list of one or more URIs
 
 
 
-1.7.0                    October 24, 2008                       4
+1.7.2                     June 11, 2009                         4
 
 
 
@@ -325,7 +325,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
 
-1.7.0                    October 24, 2008                       5
+1.7.2                     June 11, 2009                         5
 
 
 
@@ -343,8 +343,8 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
            The R\bRO\bOO\bOT\bTB\bBI\bIN\bND\bDD\bDN\bN parameter specifies the identity, in the form of a
            Distinguished Name (DN), to use when performing privileged LDAP
            operations, such as _\bs_\bu_\bd_\bo_\be_\br_\bs queries.  The password corresponding to
-           the identity should be stored in _\b@_\bl_\bd_\ba_\bp_\b__\bs_\be_\bc_\br_\be_\bt_\b@.  If not specified,
-           the B\bBI\bIN\bND\bDD\bDN\bN identity is used (if any).
+           the identity should be stored in _\b/_\be_\bt_\bc_\b/_\bl_\bd_\ba_\bp_\b._\bs_\be_\bc_\br_\be_\bt.  If not
+           specified, the B\bBI\bIN\bND\bDD\bDN\bN identity is used (if any).
 
        L\bLD\bDA\bAP\bP_\b_V\bVE\bER\bRS\bSI\bIO\bON\bN number
            The version of the LDAP protocol to use when connecting to the
@@ -391,7 +391,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
 
-1.7.0                    October 24, 2008                       6
+1.7.2                     June 11, 2009                         6
 
 
 
@@ -457,7 +457,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
 
 
-1.7.0                    October 24, 2008                       7
+1.7.2                     June 11, 2009                         7
 
 
 
@@ -471,7 +471,7 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
        C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg n\bns\bss\bsw\bwi\bit\btc\bch\bh.\b.c\bco\bon\bnf\bf
 
        Unless it is disabled at build time, s\bsu\bud\bdo\bo consults the Name Service
-       Switch file, _\b@_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b__\bc_\bo_\bn_\bf_\b@, to specify the _\bs_\bu_\bd_\bo_\be_\br_\bs search order.
+       Switch file, _\b/_\be_\bt_\bc_\b/_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf, to specify the _\bs_\bu_\bd_\bo_\be_\br_\bs search order.
        Sudo looks for a line beginning with sudoers: and uses this to
        determine the search order.  Note that s\bsu\bud\bdo\bo does not stop searching
        after the first match and later matches take precedence over earlier
@@ -494,18 +494,60 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
            sudoers: ldap
 
-       If the _\b@_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b__\bc_\bo_\bn_\bf_\b@ file is not present or there is no sudoers line,
-       the following default is assumed:
+       If the _\b/_\be_\bt_\bc_\b/_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf file is not present or there is no sudoers
+       line, the following default is assumed:
 
            sudoers: files
 
-       Note that _\b@_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b__\bc_\bo_\bn_\bf_\b@ is supported even when the underlying
+       Note that _\b/_\be_\bt_\bc_\b/_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf is supported even when the underlying
        operating system does not use an nsswitch.conf file.
 
+       C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg n\bne\bet\bts\bsv\bvc\bc.\b.c\bco\bon\bnf\bf
+
+       On AIX systems, the _\b/_\be_\bt_\bc_\b/_\bn_\be_\bt_\bs_\bv_\bc_\b._\bc_\bo_\bn_\bf file is consulted instead of
+       _\b/_\be_\bt_\bc_\b/_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf.  s\bsu\bud\bdo\bo simply treats _\bn_\be_\bt_\bs_\bv_\bc_\b._\bc_\bo_\bn_\bf as a variant of
+       _\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf; information in the previous section unrelated to the
+       file format itself still applies.
+
+       To consult LDAP first followed by the local sudoers file (if it
+       exists), use:
+
+           sudoers = ldap, files
+
+       The local _\bs_\bu_\bd_\bo_\be_\br_\bs file can be ignored completely by using:
+
+           sudoers = ldap
+
+       To treat LDAP as authoratative and only use the local sudoers file if
+       the user is not present in LDAP, use:
+
+
+
+1.7.2                     June 11, 2009                         8
+
+
+
+
+
+SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
+
+
+           sudoers = ldap = auth, files
+
+       Note that in the above example, the auth qualfier only affects user
+       lookups; both LDAP and _\bs_\bu_\bd_\bo_\be_\br_\bs will be queried for Defaults entries.
+
+       If the _\b/_\be_\bt_\bc_\b/_\bn_\be_\bt_\bs_\bv_\bc_\b._\bc_\bo_\bn_\bf file is not present or there is no sudoers
+       line, the following default is assumed:
+
+           sudoers = files
+
 F\bFI\bIL\bLE\bES\bS
-       _\b@_\bl_\bd_\ba_\bp_\b__\bc_\bo_\bn_\bf_\b@             LDAP configuration file
+       _\b/_\be_\bt_\bc_\b/_\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf          LDAP configuration file
+
+       _\b/_\be_\bt_\bc_\b/_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b._\bc_\bo_\bn_\bf      determines sudoers source order
 
-       _\b@_\bn_\bs_\bs_\bw_\bi_\bt_\bc_\bh_\b__\bc_\bo_\bn_\bf_\b@         determines sudoers source order
+       _\b/_\be_\bt_\bc_\b/_\bn_\be_\bt_\bs_\bv_\bc_\b._\bc_\bo_\bn_\bf        determines sudoers source order on AIX
 
 E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
        E\bEx\bxa\bam\bmp\bpl\ble\be l\bld\bda\bap\bp.\b.c\bco\bon\bnf\bf
@@ -520,18 +562,6 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
          #port          389
          #
          # URI will override the host and port settings.
-
-
-
-1.7.0                    October 24, 2008                       8
-
-
-
-
-
-SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
-
-
          uri            ldap://ldapserver
          #uri            ldaps://secureldapserver
          #uri            ldaps://secureldapserver ldap://ldapserver
@@ -556,6 +586,18 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
          #
          # LDAP protocol version, defaults to 3
          #ldap_version 3
+
+
+
+1.7.2                     June 11, 2009                         9
+
+
+
+
+
+SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
+
+
          #
          # Define if you want to use an encrypted LDAP connection.
          # Typically, you must also set the port to 636 (ldaps).
@@ -586,18 +628,6 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
          #
          #tls_randfile /etc/egd-pool
          #
-
-
-
-1.7.0                    October 24, 2008                       9
-
-
-
-
-
-SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
-
-
          # You may restrict which ciphers are used.  Consult your SSL
          # documentation for which options go here.
          # Only supported when using OpenLDAP.
@@ -615,12 +645,32 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
          #tls_cert /etc/certs/client_cert.pem
          #tls_key  /etc/certs/client_key.pem
          #
-         # For SunONE or iPlanet LDAP, the file specified by tls_cert may
-         # contain CA certs and/or the client's cert.  If the client's
-         # cert is included, tls_key should be specified as well.
-         # For backward compatibility, sslpath may be used in place of tls_cert.
-         #tls_cert /var/ldap/cert7.db
-         #tls_key /var/ldap/key3.db
+         # For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+         # a directory, in which case the files in the directory must have the
+         # default names (e.g. cert8.db and key4.db), or the path to the cert
+         # and key files themselves.  However, a bug in version 5.0 of the LDAP
+         # SDK will prevent specific file names from working.  For this reason
+         # it is suggested that tls_cert and tls_key be set to a directory,
+         # not a file name.
+
+
+
+1.7.2                     June 11, 2009                        10
+
+
+
+
+
+SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
+
+
+         #
+         # The certificate database specified by tls_cert may contain CA certs
+         # and/or the client's cert.  If the client's cert is included, tls_key
+         # should be specified as well.
+         # For backward compatibility, "sslpath" may be used in place of tls_cert.
+         #tls_cert /var/ldap
+         #tls_key /var/ldap
          #
          # If using SASL authentication for LDAP (OpenSSL)
          # use_sasl yes
@@ -652,18 +702,6 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
 
         attributetype ( 1.3.6.1.4.1.15953.9.1.3
            NAME 'sudoCommand'
-
-
-
-1.7.0                    October 24, 2008                      10
-
-
-
-
-
-SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
-
-
            DESC 'Command(s) to be executed by sudo'
            EQUALITY caseExactIA5Match
            SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
@@ -680,6 +718,18 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
            EQUALITY caseExactIA5Match
            SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
+
+
+
+1.7.2                     June 11, 2009                        11
+
+
+
+
+
+SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
+
+
         attributetype ( 1.3.6.1.4.1.15953.9.1.6
            NAME 'sudoRunAsUser'
            DESC 'User(s) impersonated by sudo'
@@ -699,8 +749,6 @@ SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
                  sudoRunAsGroup $ sudoOption $ description )
            )
 
-       Add nsswitch.conf example?  Add more exhaustive sudoers ldif example?
-
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        _\bl_\bd_\ba_\bp_\b._\bc_\bo_\bn_\bf(4), _\bs_\bu_\bd_\bo_\be_\br_\bs(5)
 
@@ -719,17 +767,6 @@ S\bSU\bUP\bPP\bPO\bOR\bRT\bT
        http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
        the archives.
 
-
-
-1.7.0                    October 24, 2008                      11
-
-
-
-
-
-SUDOERS.LDAP(4)        MAINTENANCE COMMANDS       SUDOERS.LDAP(4)
-
-
 D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
        s\bsu\bud\bdo\bo is provided ``AS IS'' and any express or implied warranties,
        including, but not limited to, the implied warranties of
@@ -750,43 +787,6 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1.7.0                    October 24, 2008                      12
+1.7.2                     June 11, 2009                        12
 
 
index 998786c4cec5ef2631dcc49d349b500cd07d9210..e4e172f3a7bbe17a46b4919aeb28bd600d861943 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2003-2008
+.\" Copyright (c) 2003-2009
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -14,7 +14,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\" 
-.\" $Sudo: sudoers.ldap.man.in,v 1.11 2008/10/24 13:52:19 millert Exp $
+.\" $Sudo: sudoers.ldap.man.in,v 1.13 2009/06/11 20:29:12 millert Exp $
 .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "SUDOERS.LDAP @mansectform@"
-.TH SUDOERS.LDAP @mansectform@ "October 24, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+.TH SUDOERS.LDAP @mansectform@ "June 11, 2009" "1.7.2" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -176,13 +176,13 @@ It is still possible to have typos in a user or host name, but
 this will not prevent \fBsudo\fR from running.
 .IP "\(bu" 4
 It is possible to specify per-entry options that override the global
-default options.  \fI\f(CI@sysconfdir\fI@/sudoers\fR only supports default options and
+default options.  \fI@sysconfdir@/sudoers\fR only supports default options and
 limited options associated with user/host/commands/aliases.  The
 syntax is complicated and can be difficult for users to understand.
 Placing the options directly in the entry is more natural.
 .IP "\(bu" 4
 The \fBvisudo\fR program is no longer needed.  \fBvisudo\fR provides
-locking and syntax checking of the \fI\f(CI@sysconfdir\fI@/sudoers\fR file.
+locking and syntax checking of the \fI@sysconfdir@/sudoers\fR file.
 Since \s-1LDAP\s0 updates are atomic, locking is no longer necessary.
 Because syntax is checked when the data is inserted into \s-1LDAP\s0, there
 is no need for a specialized tool to check syntax.
@@ -208,7 +208,7 @@ container.
 .PP
 Sudo first looks for the \f(CW\*(C`cn=default\*(C'\fR entry in the SUDOers container.
 If found, the multi-valued \f(CW\*(C`sudoOption\*(C'\fR attribute is parsed in the
-same manner as a global \f(CW\*(C`Defaults\*(C'\fR line in \fI\f(CI@sysconfdir\fI@/sudoers\fR.  In
+same manner as a global \f(CW\*(C`Defaults\*(C'\fR line in \fI@sysconfdir@/sudoers\fR.  In
 the following example, the \f(CW\*(C`SSH_AUTH_SOCK\*(C'\fR variable will be preserved
 in the environment for all users.
 .PP
@@ -357,17 +357,17 @@ The schema for \fBsudo\fR in OpenLDAP form is included in the \s-1EXAMPLES\s0
 section.
 .Sh "Configuring ldap.conf"
 .IX Subsection "Configuring ldap.conf"
-Sudo reads the \fI\f(CI@ldap_conf\fI@\fR file for LDAP-specific configuration.
+Sudo reads the \fI@ldap_conf@\fR file for LDAP-specific configuration.
 Typically, this file is shared amongst different LDAP-aware clients.
 As such, most of the settings are not \fBsudo\fR\-specific.  Note that
-\&\fBsudo\fR parses \fI\f(CI@ldap_conf\fI@\fR itself and may support options
+\&\fBsudo\fR parses \fI@ldap_conf@\fR itself and may support options
 that differ from those described in the \fIldap.conf\fR\|(@mansectform@) manual.
 .PP
 Also note that on systems using the OpenLDAP libraries, default
 values specified in \fI/etc/openldap/ldap.conf\fR or the user's
 \&\fI.ldaprc\fR files are not used.
 .PP
-Only those options explicitly listed in \fI\f(CI@ldap_conf\fI@\fR that are
+Only those options explicitly listed in \fI@ldap_conf@\fR that are
 supported by \fBsudo\fR are honored.  Configuration options are listed
 below in upper case but are parsed in a case-independent manner.
 .IP "\fB\s-1URI\s0\fR ldap[s]://[hostname[:port]] ..." 4
@@ -435,7 +435,7 @@ The \fB\s-1BINDPW\s0\fR parameter specifies the password to use when performing
 The \fB\s-1ROOTBINDDN\s0\fR parameter specifies the identity, in the form of
 a Distinguished Name (\s-1DN\s0), to use when performing privileged \s-1LDAP\s0
 operations, such as \fIsudoers\fR queries.  The password corresponding
-to the identity should be stored in \fI\f(CI@ldap_secret\fI@\fR.
+to the identity should be stored in \fI@ldap_secret@\fR.
 If not specified, the \fB\s-1BINDDN\s0\fR identity is used (if any).
 .IP "\fB\s-1LDAP_VERSION\s0\fR number" 4
 .IX Item "LDAP_VERSION number"
@@ -541,8 +541,8 @@ See the \f(CW\*(C`ldap.conf\*(C'\fR entry in the \s-1EXAMPLES\s0 section.
 .Sh "Configuring nsswitch.conf"
 .IX Subsection "Configuring nsswitch.conf"
 Unless it is disabled at build time, \fBsudo\fR consults the Name
-Service Switch file, \fI\f(CI@nsswitch_conf\fI@\fR, to specify the \fIsudoers\fR
-search order.  Sudo looks for a line beginning with \f(CW\*(C`sudoers:\*(C'\fR and
+Service Switch file, \fI@nsswitch_conf@\fR, to specify the \fIsudoers\fR
+search order.  Sudo looks for a line beginning with \f(CW\*(C`sudoers\*(C'\fR: and
 uses this to determine the search order.  Note that \fBsudo\fR does
 not stop searching after the first match and later matches take
 precedence over earlier ones.
@@ -570,25 +570,66 @@ The local \fIsudoers\fR file can be ignored completely by using:
 \&    sudoers: ldap
 .Ve
 .PP
-If the \fI\f(CI@nsswitch_conf\fI@\fR file is not present or there is no
+If the \fI@nsswitch_conf@\fR file is not present or there is no
 sudoers line, the following default is assumed:
 .PP
 .Vb 1
 \&    sudoers: files
 .Ve
 .PP
-Note that \fI\f(CI@nsswitch_conf\fI@\fR is supported even when the underlying
+Note that \fI@nsswitch_conf@\fR is supported even when the underlying
 operating system does not use an nsswitch.conf file.
+.Sh "Configuring netsvc.conf"
+.IX Subsection "Configuring netsvc.conf"
+On \s-1AIX\s0 systems, the \fI@netsvc_conf@\fR file is consulted instead of
+\&\fI@nsswitch_conf@\fR.  \fBsudo\fR simply treats \fInetsvc.conf\fR as a
+variant of \fInsswitch.conf\fR; information in the previous section
+unrelated to the file format itself still applies.
+.PP
+To consult \s-1LDAP\s0 first followed by the local sudoers file (if it
+exists), use:
+.PP
+.Vb 1
+\&    sudoers = ldap, files
+.Ve
+.PP
+The local \fIsudoers\fR file can be ignored completely by using:
+.PP
+.Vb 1
+\&    sudoers = ldap
+.Ve
+.PP
+To treat \s-1LDAP\s0 as authoratative and only use the local sudoers file
+if the user is not present in \s-1LDAP\s0, use:
+.PP
+.Vb 1
+\&    sudoers = ldap = auth, files
+.Ve
+.PP
+Note that in the above example, the \f(CW\*(C`auth\*(C'\fR qualfier only affects
+user lookups; both \s-1LDAP\s0 and \fIsudoers\fR will be queried for \f(CW\*(C`Defaults\*(C'\fR
+entries.
+.PP
+If the \fI@netsvc_conf@\fR file is not present or there is no
+sudoers line, the following default is assumed:
+.PP
+.Vb 1
+\&    sudoers = files
+.Ve
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI\fI@ldap_conf\fI@\fR" 24
-.el .IP "\fI\f(CI@ldap_conf\fI@\fR" 24
+.ie n .IP "\fI@ldap_conf@\fR" 24
+.el .IP "\fI@ldap_conf@\fR" 24
 .IX Item "@ldap_conf@"
 \&\s-1LDAP\s0 configuration file
-.ie n .IP "\fI\fI@nsswitch_conf\fI@\fR" 24
-.el .IP "\fI\f(CI@nsswitch_conf\fI@\fR" 24
+.ie n .IP "\fI@nsswitch_conf@\fR" 24
+.el .IP "\fI@nsswitch_conf@\fR" 24
 .IX Item "@nsswitch_conf@"
 determines sudoers source order
+.ie n .IP "\fI@netsvc_conf@\fR" 24
+.el .IP "\fI@netsvc_conf@\fR" 24
+.IX Item "@netsvc_conf@"
+determines sudoers source order on \s-1AIX\s0
 .SH "EXAMPLES"
 .IX Header "EXAMPLES"
 .Sh "Example ldap.conf"
@@ -675,12 +716,20 @@ determines sudoers source order
 \&  #tls_cert /etc/certs/client_cert.pem
 \&  #tls_key  /etc/certs/client_key.pem
 \&  #
-\&  # For SunONE or iPlanet LDAP, the file specified by tls_cert may
-\&  # contain CA certs and/or the client\*(Aqs cert.  If the client\*(Aqs
-\&  # cert is included, tls_key should be specified as well.
-\&  # For backward compatibility, sslpath may be used in place of tls_cert.
-\&  #tls_cert /var/ldap/cert7.db
-\&  #tls_key /var/ldap/key3.db
+\&  # For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+\&  # a directory, in which case the files in the directory must have the
+\&  # default names (e.g. cert8.db and key4.db), or the path to the cert
+\&  # and key files themselves.  However, a bug in version 5.0 of the LDAP
+\&  # SDK will prevent specific file names from working.  For this reason
+\&  # it is suggested that tls_cert and tls_key be set to a directory,
+\&  # not a file name.
+\&  #
+\&  # The certificate database specified by tls_cert may contain CA certs
+\&  # and/or the client\*(Aqs cert.  If the client\*(Aqs cert is included, tls_key
+\&  # should be specified as well.
+\&  # For backward compatibility, "sslpath" may be used in place of tls_cert.
+\&  #tls_cert /var/ldap
+\&  #tls_key /var/ldap
 \&  #
 \&  # If using SASL authentication for LDAP (OpenSSL)
 \&  # use_sasl yes
@@ -748,9 +797,6 @@ schema directory (e.g. \fI/etc/openldap/schema\fR), add the proper
 \&          sudoRunAsGroup $ sudoOption $ description )
 \&    )
 .Ve
-.PP
-Add nsswitch.conf example?
-Add more exhaustive sudoers ldif example?
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
 \&\fIldap.conf\fR\|(@mansectform@), \fIsudoers\fR\|(5)
index 3b36dddda87b4365db739ff5853018fac639cc89..7d59cb2fe41ae7b394b388da152dd29a5182f7af 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2008
+Copyright (c) 2003-2009
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -14,7 +14,7 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-$Sudo: sudoers.ldap.pod,v 1.10 2008/05/10 13:18:47 millert Exp $
+$Sudo: sudoers.ldap.pod,v 1.14 2009/05/29 13:43:12 millert Exp $
 =pod
 
 =head1 NAME
@@ -457,7 +457,7 @@ See the C<ldap.conf> entry in the L<EXAMPLES> section.
 
 Unless it is disabled at build time, B<sudo> consults the Name
 Service Switch file, F<@nsswitch_conf@>, to specify the I<sudoers>
-search order.  Sudo looks for a line beginning with C<sudoers:> and
+search order.  Sudo looks for a line beginning with C<sudoers>: and
 uses this to determine the search order.  Note that B<sudo> does
 not stop searching after the first match and later matches take
 precedence over earlier ones.
@@ -487,6 +487,36 @@ sudoers line, the following default is assumed:
 Note that F<@nsswitch_conf@> is supported even when the underlying
 operating system does not use an nsswitch.conf file.
 
+=head2 Configuring netsvc.conf
+
+On AIX systems, the F<@netsvc_conf@> file is consulted instead of
+F<@nsswitch_conf@>.  B<sudo> simply treats I<netsvc.conf> as a
+variant of I<nsswitch.conf>; information in the previous section
+unrelated to the file format itself still applies.
+
+To consult LDAP first followed by the local sudoers file (if it
+exists), use:
+
+    sudoers = ldap, files
+
+The local I<sudoers> file can be ignored completely by using:
+
+    sudoers = ldap
+
+To treat LDAP as authoratative and only use the local sudoers file
+if the user is not present in LDAP, use:
+
+    sudoers = ldap = auth, files
+
+Note that in the above example, the C<auth> qualfier only affects
+user lookups; both LDAP and I<sudoers> will be queried for C<Defaults>
+entries.
+
+If the F<@netsvc_conf@> file is not present or there is no
+sudoers line, the following default is assumed:
+
+    sudoers = files
+
 =head1 FILES
 
 =over 24
@@ -499,6 +529,10 @@ LDAP configuration file
 
 determines sudoers source order
 
+=item F<@netsvc_conf@>
+
+determines sudoers source order on AIX
+
 =back
 
 =head1 EXAMPLES
@@ -586,12 +620,20 @@ determines sudoers source order
   #tls_cert /etc/certs/client_cert.pem
   #tls_key  /etc/certs/client_key.pem
   #
-  # For SunONE or iPlanet LDAP, the file specified by tls_cert may
-  # contain CA certs and/or the client's cert.  If the client's
-  # cert is included, tls_key should be specified as well.
-  # For backward compatibility, sslpath may be used in place of tls_cert.
-  #tls_cert /var/ldap/cert7.db
-  #tls_key /var/ldap/key3.db
+  # For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+  # a directory, in which case the files in the directory must have the
+  # default names (e.g. cert8.db and key4.db), or the path to the cert
+  # and key files themselves.  However, a bug in version 5.0 of the LDAP
+  # SDK will prevent specific file names from working.  For this reason
+  # it is suggested that tls_cert and tls_key be set to a directory,
+  # not a file name.
+  #
+  # The certificate database specified by tls_cert may contain CA certs
+  # and/or the client's cert.  If the client's cert is included, tls_key
+  # should be specified as well.
+  # For backward compatibility, "sslpath" may be used in place of tls_cert.
+  #tls_cert /var/ldap
+  #tls_key /var/ldap
   #
   # If using SASL authentication for LDAP (OpenSSL)
   # use_sasl yes
@@ -658,11 +700,6 @@ C<include> line in C<slapd.conf> and restart B<slapd>.
          sudoRunAsGroup $ sudoOption $ description )
     )
 
-=for comment
-
-Add nsswitch.conf example?
-Add more exhaustive sudoers ldif example?
-
 =head1 SEE ALSO
 
 L<ldap.conf(5)>, L<sudoers(5)>
index 533c8c70ce76d19160226e10e25d43b7c96edc5b..60d56edfe08a570157be565d885b653b40e734a5 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2008
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2009
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: sudoers.man.in,v 1.74 2008/12/03 20:58:41 millert Exp $
+.\" $Sudo: sudoers.man.in,v 1.80 2009/06/30 12:41:09 millert Exp $
 .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "SUDOERS @mansectform@"
-.TH SUDOERS @mansectform@ "December  3, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+.TH SUDOERS @mansectform@ "June 30, 2009" "1.7.2" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -254,6 +254,7 @@ The definitions of what constitutes a valid \fIalias\fR member follow.
 \&          \*(Aq!\*(Aq* \*(Aq#\*(Aquid |
 \&          \*(Aq!\*(Aq* \*(Aq%\*(Aqgroup |
 \&          \*(Aq!\*(Aq* \*(Aq+\*(Aqnetgroup |
+\&          \*(Aq!\*(Aq* \*(Aq%:\*(Aqnonunix_group |
 \&          \*(Aq!\*(Aq* User_Alias
 .Ve
 .PP
@@ -263,6 +264,23 @@ with '+') and \f(CW\*(C`User_Alias\*(C'\fRes.  Each list item may be prefixed wi
 zero or more '!' operators.  An odd number of '!' operators negate
 the value of the item; an even number just cancel each other out.
 .PP
+A \f(CW\*(C`username\*(C'\fR, \f(CW\*(C`group\*(C'\fR, \f(CW\*(C`netgroup\*(C'\fR and \f(CW\*(C`nonunix_groups\*(C'\fR may
+be enclosed in double quotes to avoid the need for escaping special
+characters.  Alternately, special characters may be specified in
+escaped hex mode, e.g. \ex20 for space.
+.PP
+The \f(CW\*(C`nonunix_group\*(C'\fR syntax depends on the underlying implementation.
+For instance, the \s-1QAS\s0 \s-1AD\s0 backend supports the following formats:
+.IP "\(bu" 4
+Group in the same domain: \*(L"Group Name\*(R"
+.IP "\(bu" 4
+Group in any domain: \*(L"Group Name@FULLY.QUALIFIED.DOMAIN\*(R"
+.IP "\(bu" 4
+Group \s-1SID:\s0 \*(L"S\-1\-2\-34\-5678901234\-5678901234\-5678901234\-567\*(R"
+.PP
+Note that quotes around group names are optional.  Unquoted strings must
+use a backslash (\e) to escape spaces and the '@' symbol.
+.PP
 .Vb 2
 \& Runas_List ::= Runas_Member |
 \&                Runas_Member \*(Aq,\*(Aq Runas_List
@@ -396,7 +414,7 @@ See \*(L"\s-1SUDOERS\s0 \s-1OPTIONS\s0\*(R" for a list of supported Defaults par
 \&
 \& Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
 \&
-\& Runas_Spec ::= \*(Aq(\*(Aq Runas_List? (: Runas_List)? \*(Aq)\*(Aq
+\& Runas_Spec ::= \*(Aq(\*(Aq Runas_List? (\*(Aq:\*(Aq Runas_List)? \*(Aq)\*(Aq
 \&
 \& Tag_Spec ::= (\*(AqNOPASSWD:\*(Aq | \*(AqPASSWD:\*(Aq | \*(AqNOEXEC:\*(Aq | \*(AqEXEC:\*(Aq |
 \&               \*(AqSETENV:\*(Aq | \*(AqNOSETENV:\*(Aq )
@@ -406,7 +424,8 @@ 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:
+The basic structure of a user specification is `who = where (as_whom)
+what'.  Let's break that down into its constituent parts:
 .Sh "Runas_Spec"
 .IX Subsection "Runas_Spec"
 A \f(CW\*(C`Runas_Spec\*(C'\fR determines the user and/or the group that a command
@@ -539,9 +558,10 @@ be overridden by use of the \f(CW\*(C`UNSETENV\*(C'\fR tag.
 .Sh "Wildcards"
 .IX Subsection "Wildcards"
 \&\fBsudo\fR allows shell-style \fIwildcards\fR (aka meta or glob characters)
-to be used in hostnames, pathnames and command line arguments in the
-\&\fIsudoers\fR file.  Wildcard matching is done via the \fB\s-1POSIX\s0\fR
-\&\fIfnmatch\fR\|(3) routine.  Note that these are \fInot\fR regular expressions.
+to be used in hostnames, pathnames and command line arguments in
+the \fIsudoers\fR file.  Wildcard matching is done via the \fB\s-1POSIX\s0\fR
+\&\fIglob\fR\|(3) and \fIfnmatch\fR\|(3) routines.  Note that these are \fInot\fR
+regular expressions.
 .ie n .IP "\*(C`*\*(C'" 8
 .el .IP "\f(CW\*(C`*\*(C'\fR" 8
 .IX Item "*"
@@ -564,10 +584,10 @@ Matches any character \fBnot\fR in the specified range.
 For any character \*(L"x\*(R", evaluates to \*(L"x\*(R".  This is used to
 escape special characters such as: \*(L"*\*(R", \*(L"?\*(R", \*(L"[\*(R", and \*(L"}\*(R".
 .PP
-\&\s-1POSIX\s0 character classes may also be used if your system's
-\&\fIfnmatch\fR\|(3) function supports them.  However, because the
-\&\f(CW\*(Aq:\*(Aq\fR character has special meaning in \fIsudoers\fR, it must
-be escaped.  For example:
+\&\s-1POSIX\s0 character classes may also be used if your system's \fIglob\fR\|(3)
+and \fIfnmatch\fR\|(3) functions support them.  However, because the
+\&\f(CW\*(Aq:\*(Aq\fR character has special meaning in \fIsudoers\fR, it must be
+escaped.  For example:
 .PP
 .Vb 1
 \&    /bin/ls [[\e:alpha\e:]]*
@@ -597,17 +617,19 @@ with \fBany\fR arguments.
 .Sh "Including other files from within sudoers"
 .IX Subsection "Including other files from within sudoers"
 It is possible to include other \fIsudoers\fR files from within the
-\&\fIsudoers\fR file currently being parsed using the \f(CW\*(C`#include\*(C'\fR
-directive, similar to the one used by the C preprocessor.  This is
-useful, for example, for keeping a site-wide \fIsudoers\fR file in
-addition to a per-machine local one.  For the sake of this example
-the site-wide \fIsudoers\fR will be \fI/etc/sudoers\fR and the per-machine
-one will be \fI/etc/sudoers.local\fR.  To include \fI/etc/sudoers.local\fR
-from \fI/etc/sudoers\fR we would use the following line in \fI/etc/sudoers\fR:
-.PP
-.Vb 1
-\& #include /etc/sudoers.local
-.Ve
+\&\fIsudoers\fR file currently being parsed using the \f(CW\*(C`#include\*(C'\fR and
+\&\f(CW\*(C`#includedir\*(C'\fR directives.
+.PP
+This can be used, for example, to keep a site-wide \fIsudoers\fR file
+in addition to a local, per-machine file.  For the sake of this
+example the site-wide \fIsudoers\fR will be \fI/etc/sudoers\fR and the
+per-machine one will be \fI/etc/sudoers.local\fR.  To include
+\&\fI/etc/sudoers.local\fR from within \fI/etc/sudoers\fR we would use the
+following line in \fI/etc/sudoers\fR:
+.Sp
+.RS 4
+\&\f(CW\*(C`#include /etc/sudoers.local\*(C'\fR
+.RE
 .PP
 When \fBsudo\fR reaches this line it will suspend processing of the
 current file (\fI/etc/sudoers\fR) and switch to \fI/etc/sudoers.local\fR.
@@ -615,6 +637,35 @@ Upon reaching the end of \fI/etc/sudoers.local\fR, the rest of
 \&\fI/etc/sudoers\fR will be processed.  Files that are included may
 themselves include other files.  A hard limit of 128 nested include
 files is enforced to prevent include file loops.
+.PP
+The filename may include the \f(CW%h\fR escape, signifying the short form
+of the hostname.  I.e., if the machine's hostname is \*(L"xerxes\*(R", then
+.PP
+\&\f(CW\*(C`#include /etc/sudoers.%h\*(C'\fR
+.PP
+will cause \fBsudo\fR to include the file \fI/etc/sudoers.xerxes\fR.
+.PP
+The \f(CW\*(C`#includedir\*(C'\fR directive can be used to create a \fIsudo.d\fR
+directory that the system package manager can drop \fIsudoers\fR rules
+into as part of package installation.  For example, given:
+.PP
+\&\f(CW\*(C`#includedir /etc/sudoers.d\*(C'\fR
+.PP
+\&\fBsudo\fR will read each file in \fI/etc/sudoers.d\fR, skipping file
+names that end in \f(CW\*(C`~\*(C'\fR or contain a \f(CW\*(C`.\*(C'\fR character to avoid causing
+problems with package manager or editor temporary/backup files.
+Files are parsed in sorted lexical order.  That is,
+\&\fI/etc/sudoers.d/01_first\fR will be parsed before
+\&\fI/etc/sudoers.d/10_second\fR.  Be aware that because the sorting is
+lexical, not numeric, \fI/etc/sudoers.d/1_whoops\fR would be loaded
+\&\fBafter\fR \fI/etc/sudoers.d/10_second\fR.  Using a consistent number
+of leading zeroes in the file names can be used to avoid such
+problems.
+.PP
+Note that unlike files included via \f(CW\*(C`#include\*(C'\fR, \fBvisudo\fR will not
+edit the files in a \f(CW\*(C`#includedir\*(C'\fR directory unless one of them
+contains a syntax error.  It is still possible to run \fBvisudo\fR
+with the \f(CW\*(C`\-f\*(C'\fR flag to edit the files directly.
 .Sh "Other special characters and reserved words"
 .IX Subsection "Other special characters and reserved words"
 The pound sign ('#') is used to indicate a comment (unless it is
@@ -787,11 +838,21 @@ the string \*(L"Password:\*(R".  If \fIpassprompt_override\fR is set, \fIpasspro
 will always be used.  This flag is \fIoff\fR by default.
 .IP "preserve_groups" 16
 .IX Item "preserve_groups"
-By default \fBsudo\fR will initialize the group vector to the list of
+By default, \fBsudo\fR will initialize the group vector to the list of
 groups the target user is in.  When \fIpreserve_groups\fR is set, the
 user's existing group vector is left unaltered.  The real and
 effective group IDs, however, are still set to match the target
 user.  This flag is \fIoff\fR by default.
+.IP "pwfeedback" 16
+.IX Item "pwfeedback"
+By default, \fBsudo\fR reads the password like most other Unix programs,
+by turning off echo until the user hits the return (or enter) key.
+Some users become confused by this as it appears to them that \fBsudo\fR
+has hung at this point.  When \fIpwfeedback\fR is set, \fBsudo\fR will
+provide visual feedback when the user presses a key.  Note that
+this does have a security impact as an onlooker may be able to
+determine the length of the password being entered.
+This flag is \fIoff\fR by default.
 .IP "requiretty" 16
 .IX Item "requiretty"
 If set, \fBsudo\fR will only run when the user is logged in to a real
@@ -848,6 +909,17 @@ If set and \fBsudo\fR is invoked with no arguments it acts as if the
 shell is determined by the \f(CW\*(C`SHELL\*(C'\fR environment variable if it is
 set, falling back on the shell listed in the invoking user's
 /etc/passwd entry if not).  This flag is \fIoff\fR by default.
+.IP "fast_glob" 16
+.IX Item "fast_glob"
+Normally, \fBsudo\fR uses the \fIglob\fR\|(3) function to do shell-style
+globbing when matching pathnames.  However, since it accesses the
+file system, \fIglob\fR\|(3) can take a long time to complete for some
+patterns, especially when the pattern references a network file
+system that is mounted on demand (automounted).  The \fIfast_glob\fR
+option causes \fBsudo\fR to use the \fIfnmatch\fR\|(3) function, which does
+not access the file system to do its matching.  The disadvantage
+of \fIfast_glob\fR is that it is unable to match relative pathnames
+such as \fI./ls\fR or \fI../bin/ls\fR.  This flag is \fIoff\fR by default.
 .IP "stay_setuid" 16
 .IX Item "stay_setuid"
 Normally, when \fBsudo\fR executes a command the real and effective
@@ -872,6 +944,14 @@ If set, users must authenticate on a per-tty basis.  Normally,
 the user running it.  With this flag enabled, \fBsudo\fR will use a
 file named for the tty the user is logged in on in that directory.
 This flag is \fI@tty_tickets@\fR by default.
+.IP "umask_override" 16
+.IX Item "umask_override"
+If set, \fBsudo\fR will set the umask as specified by \fIsudoers\fR without
+modification.  This makes it possible to specify a more permissive
+umask in \fIsudoers\fR than the user's own umask and matches historical
+behavior.  If \fIumask_override\fR is not set, \fBsudo\fR will set the
+umask to be the union of the user's umask and what is specified in
+\&\fIsudoers\fR.  This flag is \fIoff\fR by default.
 @LCMAN@.IP "use_loginclass" 16
 @LCMAN@.IX Item "use_loginclass"
 @LCMAN@If set, \fBsudo\fR will apply the defaults specified for the target user's
@@ -1043,11 +1123,13 @@ The value of \fIaskpass\fR may be overridden by the \f(CW\*(C`SUDO_ASKPASS\*(C'\
 environment variable.
 .IP "env_file" 12
 .IX Item "env_file"
-The \fIenv_file\fR options specifies the fully qualified path to a file
-containing variables to be set in the environment of the program
-being run.  Entries in this file should be of the form \f(CW\*(C`VARIABLE=value\*(C'\fR.
-Variables in this file are subject to other \fBsudo\fR environment
-settings such as \fIenv_keep\fR and \fIenv_check\fR.
+The \fIenv_file\fR options specifies the fully qualified path to a
+file containing variables to be set in the environment of the program
+being run.  Entries in this file should either be of the form
+\&\f(CW\*(C`VARIABLE=value\*(C'\fR or \f(CW\*(C`export VARIABLE=value\*(C'\fR.  The value may
+optionally be surrounded by single or double quotes.  Variables in
+this file are subject to other \fBsudo\fR environment settings such
+as \fIenv_keep\fR and \fIenv_check\fR.
 .IP "exempt_group" 12
 .IX Item "exempt_group"
 Users in this group are exempt from password and \s-1PATH\s0 requirements.
@@ -1183,15 +1265,16 @@ variables to check is displayed when \fBsudo\fR is run by root with
 the \fI\-V\fR option.
 .IP "env_delete" 16
 .IX Item "env_delete"
-Environment variables to be removed from the user's environment.
-The argument may be a double-quoted, space-separated list or a
-single value without double-quotes.  The list can be replaced, added
-to, deleted from, or disabled by using the \f(CW\*(C`=\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, and
-\&\f(CW\*(C`!\*(C'\fR operators respectively.  The default list of environment
-variables to remove is displayed when \fBsudo\fR is run by root with the
-\&\fI\-V\fR option.  Note that many operating systems will remove potentially
-dangerous variables from the environment of any setuid process (such
-as \fBsudo\fR).
+Environment variables to be removed from the user's environment
+when the \fIenv_reset\fR option is not in effect.  The argument may
+be a double-quoted, space-separated list or a single value without
+double-quotes.  The list can be replaced, added to, deleted from,
+or disabled by using the \f(CW\*(C`=\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, and \f(CW\*(C`!\*(C'\fR operators
+respectively.  The default list of environment variables to remove
+is displayed when \fBsudo\fR is run by root with the \fI\-V\fR option.
+Note that many operating systems will remove potentially dangerous
+variables from the environment of any setuid process (such as
+\&\fBsudo\fR).
 .IP "env_keep" 16
 .IX Item "env_keep"
 Environment variables to be preserved in the user's environment
@@ -1236,6 +1319,7 @@ these are a bit contrived.  First, we define our \fIaliases\fR:
 \& # Runas alias specification
 \& Runas_Alias    OP = root, operator
 \& Runas_Alias    DB = oracle, sybase
+\& Runas_Alias    ADMINGRP = adm, oper
 \&
 \& # Host alias specification
 \& Host_Alias     SPARC = bigtime, eclipse, moet, anchor :\e
@@ -1346,8 +1430,14 @@ The user \fBjoe\fR may only \fIsu\fR\|(1) to operator.
 .PP
 .Vb 1
 \& pete           HPPA = /usr/bin/passwd [A\-Za\-z]*, !/usr/bin/passwd root
+\&
+\& %opers         ALL = (: ADMINGRP) /usr/sbin/
 .Ve
 .PP
+Users in the \fBopers\fR group may run commands in \fI/usr/sbin/\fR as themselves
+with any group in the \fI\s-1ADMINGRP\s0\fR \f(CW\*(C`Runas_Alias\*(C'\fR (the \fBadm\fR and \fBoper\fR
+groups).
+.PP
 The user \fBpete\fR is allowed to change anyone's password except for
 root on the \fI\s-1HPPA\s0\fR machines.  Note that this assumes \fIpasswd\fR\|(1)
 does not take multiple usernames on the command line.
@@ -1524,7 +1614,7 @@ editor, a safer approach is to give the user permission to run
 \&\fBsudoedit\fR.
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
-\&\fIrsh\fR\|(1), \fIsu\fR\|(1), \fIfnmatch\fR\|(3), \fIsudo\fR\|(@mansectsu@), \fIvisudo\fR\|(8)
+\&\fIrsh\fR\|(1), \fIsu\fR\|(1), \fIfnmatch\fR\|(3), \fIglob\fR\|(3), \fIsudo\fR\|(@mansectsu@), \fIvisudo\fR\|(8)
 .SH "CAVEATS"
 .IX Header "CAVEATS"
 The \fIsudoers\fR file should \fBalways\fR be edited by the \fBvisudo\fR
index 63c49cf7d88e1155f81f3212aa2265aec293e2b9..a55ce0e6c60f4a92636d6be91aafe156d1c0d413 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 1994-1996, 1998-2005, 2007-2008
+Copyright (c) 1994-1996, 1998-2005, 2007-2009
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +18,7 @@ Sponsored in part by the Defense Advanced Research Projects
 Agency (DARPA) and Air Force Research Laboratory, Air Force
 Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-$Sudo: sudoers.pod,v 1.155 2008/12/03 20:57:13 millert Exp $
+$Sudo: sudoers.pod,v 1.173 2009/06/30 12:41:09 millert Exp $
 =pod
 
 =head1 NAME
@@ -116,6 +116,7 @@ The definitions of what constitutes a valid I<alias> member follow.
          '!'* '#'uid |
          '!'* '%'group |
          '!'* '+'netgroup |
+         '!'* '%:'nonunix_group |
          '!'* User_Alias
 
 A C<User_List> is made up of one or more usernames, uids (prefixed
@@ -124,6 +125,33 @@ with '+') and C<User_Alias>es.  Each list item may be prefixed with
 zero or more '!' operators.  An odd number of '!' operators negate
 the value of the item; an even number just cancel each other out.
 
+A C<username>, C<group>, C<netgroup> and C<nonunix_groups> may
+be enclosed in double quotes to avoid the need for escaping special
+characters.  Alternately, special characters may be specified in
+escaped hex mode, e.g. \x20 for space.
+
+The C<nonunix_group> syntax depends on the underlying implementation.
+For instance, the QAS AD backend supports the following formats:
+
+=over 4
+
+=item *
+
+Group in the same domain: "Group Name"
+
+=item *
+
+Group in any domain: "Group Name@FULLY.QUALIFIED.DOMAIN"
+
+=item *
+
+Group SID: "S-1-2-34-5678901234-5678901234-5678901234-567"
+
+=back
+
+Note that quotes around group names are optional.  Unquoted strings must
+use a backslash (\) to escape spaces and the '@' symbol.
+
  Runas_List ::= Runas_Member |
                Runas_Member ',' Runas_List
 
@@ -238,7 +266,7 @@ Defaults entries are parsed in the following order: generic, host
 and user Defaults first, then runas Defaults and finally command
 defaults.
 
-See L</"SUDOERS OPTIONS"> for a list of supported Defaults parameters.
+See L<"SUDOERS OPTIONS"> for a list of supported Defaults parameters.
 
 =head2 User Specification
 
@@ -250,7 +278,7 @@ See L</"SUDOERS OPTIONS"> for a list of supported Defaults parameters.
 
  Cmnd_Spec ::= Runas_Spec? Tag_Spec* Cmnd
 
- Runas_Spec ::= '(' Runas_List? (: Runas_List)? ')'
+ Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
 
  Tag_Spec ::= ('NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' |
               'SETENV:' | 'NOSETENV:' )
@@ -259,7 +287,8 @@ A B<user specification> determines which commands a user may run
 (and as what user) on specified hosts.  By default, commands are
 run as B<root>, but this can be changed on a per-command basis.
 
-Let's break that down into its constituent parts:
+The basic structure of a user specification is `who = where (as_whom)
+what'.  Let's break that down into its constituent parts:
 
 =head2 Runas_Spec
 
@@ -376,9 +405,10 @@ be overridden by use of the C<UNSETENV> tag.
 =head2 Wildcards
 
 B<sudo> allows shell-style I<wildcards> (aka meta or glob characters)
-to be used in hostnames, pathnames and command line arguments in the
-I<sudoers> file.  Wildcard matching is done via the B<POSIX>
-L<fnmatch(3)> routine.  Note that these are I<not> regular expressions.
+to be used in hostnames, pathnames and command line arguments in
+the I<sudoers> file.  Wildcard matching is done via the B<POSIX>
+L<glob(3)> and L<fnmatch(3)> routines.  Note that these are I<not>
+regular expressions.
 
 =over 8
 
@@ -405,10 +435,10 @@ escape special characters such as: "*", "?", "[", and "}".
 
 =back
 
-POSIX character classes may also be used if your system's
-L<fnmatch(3)> function supports them.  However, because the
-C<':'> character has special meaning in I<sudoers>, it must
-be escaped.  For example:
+POSIX character classes may also be used if your system's L<glob(3)>
+and L<fnmatch(3)> functions support them.  However, because the
+C<':'> character has special meaning in I<sudoers>, it must be
+escaped.  For example:
 
     /bin/ls [[\:alpha\:]]*
 
@@ -440,15 +470,21 @@ with B<any> arguments.
 =head2 Including other files from within sudoers
 
 It is possible to include other I<sudoers> files from within the
-I<sudoers> file currently being parsed using the C<#include>
-directive, similar to the one used by the C preprocessor.  This is
-useful, for example, for keeping a site-wide I<sudoers> file in
-addition to a per-machine local one.  For the sake of this example
-the site-wide I<sudoers> will be F</etc/sudoers> and the per-machine
-one will be F</etc/sudoers.local>.  To include F</etc/sudoers.local>
-from F</etc/sudoers> we would use the following line in F</etc/sudoers>:
+I<sudoers> file currently being parsed using the C<#include> and
+C<#includedir> directives.
 
- #include /etc/sudoers.local
+This can be used, for example, to keep a site-wide I<sudoers> file
+in addition to a local, per-machine file.  For the sake of this
+example the site-wide I<sudoers> will be F</etc/sudoers> and the
+per-machine one will be F</etc/sudoers.local>.  To include
+F</etc/sudoers.local> from within F</etc/sudoers> we would use the
+following line in F</etc/sudoers>:
+
+=over 4
+
+C<#include /etc/sudoers.local>
+
+=back
 
 When B<sudo> reaches this line it will suspend processing of the
 current file (F</etc/sudoers>) and switch to F</etc/sudoers.local>.
@@ -457,6 +493,35 @@ F</etc/sudoers> will be processed.  Files that are included may
 themselves include other files.  A hard limit of 128 nested include
 files is enforced to prevent include file loops.
 
+The filename may include the C<%h> escape, signifying the short form
+of the hostname.  I.e., if the machine's hostname is "xerxes", then
+
+C<#include /etc/sudoers.%h>
+
+will cause B<sudo> to include the file F</etc/sudoers.xerxes>.
+
+The C<#includedir> directive can be used to create a F<sudo.d>
+directory that the system package manager can drop I<sudoers> rules
+into as part of package installation.  For example, given:
+
+C<#includedir /etc/sudoers.d>
+
+B<sudo> will read each file in F</etc/sudoers.d>, skipping file
+names that end in C<~> or contain a C<.> character to avoid causing
+problems with package manager or editor temporary/backup files.
+Files are parsed in sorted lexical order.  That is,
+F</etc/sudoers.d/01_first> will be parsed before
+F</etc/sudoers.d/10_second>.  Be aware that because the sorting is
+lexical, not numeric, F</etc/sudoers.d/1_whoops> would be loaded
+B<after> F</etc/sudoers.d/10_second>.  Using a consistent number
+of leading zeroes in the file names can be used to avoid such
+problems.
+
+Note that unlike files included via C<#include>, B<visudo> will not
+edit the files in a C<#includedir> directory unless one of them
+contains a syntax error.  It is still possible to run B<visudo>
+with the C<-f> flag to edit the files directly.
+
 =head2 Other special characters and reserved words
 
 The pound sign ('#') is used to indicate a comment (unless it is
@@ -653,12 +718,23 @@ will always be used.  This flag is I<off> by default.
 
 =item preserve_groups
 
-By default B<sudo> will initialize the group vector to the list of
+By default, B<sudo> will initialize the group vector to the list of
 groups the target user is in.  When I<preserve_groups> is set, the
 user's existing group vector is left unaltered.  The real and
 effective group IDs, however, are still set to match the target
 user.  This flag is I<off> by default.
 
+=item pwfeedback
+
+By default, B<sudo> reads the password like most other Unix programs,
+by turning off echo until the user hits the return (or enter) key.
+Some users become confused by this as it appears to them that B<sudo>
+has hung at this point.  When I<pwfeedback> is set, B<sudo> will
+provide visual feedback when the user presses a key.  Note that
+this does have a security impact as an onlooker may be able to
+determine the length of the password being entered.
+This flag is I<off> by default.
+
 =item requiretty
 
 If set, B<sudo> will only run when the user is logged in to a real
@@ -723,6 +799,18 @@ shell is determined by the C<SHELL> environment variable if it is
 set, falling back on the shell listed in the invoking user's
 /etc/passwd entry if not).  This flag is I<off> by default.
 
+=item fast_glob
+
+Normally, B<sudo> uses the L<glob(3)> function to do shell-style
+globbing when matching pathnames.  However, since it accesses the
+file system, L<glob(3)> can take a long time to complete for some
+patterns, especially when the pattern references a network file
+system that is mounted on demand (automounted).  The I<fast_glob>
+option causes B<sudo> to use the L<fnmatch(3)> function, which does
+not access the file system to do its matching.  The disadvantage
+of I<fast_glob> is that it is unable to match relative pathnames
+such as F<./ls> or F<../bin/ls>.  This flag is I<off> by default.
+
 =item stay_setuid
 
 Normally, when B<sudo> executes a command the real and effective
@@ -750,6 +838,15 @@ the user running it.  With this flag enabled, B<sudo> will use a
 file named for the tty the user is logged in on in that directory.
 This flag is I<@tty_tickets@> by default.
 
+=item umask_override
+
+If set, B<sudo> will set the umask as specified by I<sudoers> without
+modification.  This makes it possible to specify a more permissive
+umask in I<sudoers> than the user's own umask and matches historical
+behavior.  If I<umask_override> is not set, B<sudo> will set the
+umask to be the union of the user's umask and what is specified in
+I<sudoers>.  This flag is I<off> by default.
+
 =item use_loginclass
 
 If set, B<sudo> will apply the defaults specified for the target user's
@@ -959,11 +1056,13 @@ environment variable.
 
 =item env_file
 
-The I<env_file> options specifies the fully qualified path to a file
-containing variables to be set in the environment of the program
-being run.  Entries in this file should be of the form C<VARIABLE=value>.
-Variables in this file are subject to other B<sudo> environment
-settings such as I<env_keep> and I<env_check>.
+The I<env_file> options specifies the fully qualified path to a
+file containing variables to be set in the environment of the program
+being run.  Entries in this file should either be of the form
+C<VARIABLE=value> or C<export VARIABLE=value>.  The value may
+optionally be surrounded by single or double quotes.  Variables in
+this file are subject to other B<sudo> environment settings such
+as I<env_keep> and I<env_check>.
 
 =item exempt_group
 
@@ -1128,15 +1227,16 @@ the I<-V> option.
 
 =item env_delete
 
-Environment variables to be removed from the user's environment.
-The argument may be a double-quoted, space-separated list or a
-single value without double-quotes.  The list can be replaced, added
-to, deleted from, or disabled by using the C<=>, C<+=>, C<-=>, and
-C<!> operators respectively.  The default list of environment
-variables to remove is displayed when B<sudo> is run by root with the
-I<-V> option.  Note that many operating systems will remove potentially
-dangerous variables from the environment of any setuid process (such
-as B<sudo>).
+Environment variables to be removed from the user's environment
+when the I<env_reset> option is not in effect.  The argument may
+be a double-quoted, space-separated list or a single value without
+double-quotes.  The list can be replaced, added to, deleted from,
+or disabled by using the C<=>, C<+=>, C<-=>, and C<!> operators
+respectively.  The default list of environment variables to remove
+is displayed when B<sudo> is run by root with the I<-V> option.
+Note that many operating systems will remove potentially dangerous
+variables from the environment of any setuid process (such as
+B<sudo>).
 
 =item env_keep
 
@@ -1190,6 +1290,7 @@ these are a bit contrived.  First, we define our I<aliases>:
  # Runas alias specification
  Runas_Alias   OP = root, operator
  Runas_Alias   DB = oracle, sybase
+ Runas_Alias   ADMINGRP = adm, oper
 
  # Host alias specification
  Host_Alias    SPARC = bigtime, eclipse, moet, anchor :\
@@ -1283,6 +1384,12 @@ The user B<joe> may only L<su(1)> to operator.
 
  pete          HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
 
+ %opers                ALL = (: ADMINGRP) /usr/sbin/
+
+Users in the B<opers> group may run commands in F</usr/sbin/> as themselves
+with any group in the I<ADMINGRP> C<Runas_Alias> (the B<adm> and B<oper>
+groups).
+
 The user B<pete> is allowed to change anyone's password except for
 root on the I<HPPA> machines.  Note that this assumes L<passwd(1)>
 does not take multiple usernames on the command line.
@@ -1438,7 +1545,7 @@ B<sudoedit>.
 
 =head1 SEE ALSO
 
-L<rsh(1)>, L<su(1)>, L<fnmatch(3)>, L<sudo(8)>, L<visudo(8)>
+L<rsh(1)>, L<su(1)>, L<fnmatch(3)>, L<glob(3)>, L<sudo(8)>, L<visudo(8)>
 
 =head1 CAVEATS
 
diff --git a/term.c b/term.c
new file mode 100644 (file)
index 0000000..d962fe6
--- /dev/null
+++ b/term.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#else
+# ifdef HAVE_TERMIO_H
+#  include <termio.h>
+# else
+#  include <sgtty.h>
+#  include <sys/ioctl.h>
+# endif /* HAVE_TERMIO_H */
+#endif /* HAVE_TERMIOS_H */
+
+#include "sudo.h"
+
+#ifndef lint
+__unused static const char rcsid[] = "$Sudo: term.c,v 1.4 2009/02/25 10:47:12 millert Exp $";
+#endif /* lint */
+
+#ifndef TCSASOFT
+# define TCSASOFT      0
+#endif
+#ifndef ECHONL
+# define ECHONL                0
+#endif
+#ifndef IEXTEN
+# define IEXTEN                0
+#endif
+
+#ifndef _POSIX_VDISABLE
+# ifdef VDISABLE
+#  define _POSIX_VDISABLE      VDISABLE
+# else
+#  define _POSIX_VDISABLE      0
+# endif
+#endif
+
+/*
+ * Compat macros for non-termios systems.
+ */
+#ifndef HAVE_TERMIOS_H
+# ifdef HAVE_TERMIO_H
+#  undef termios
+#  define termios              termio
+#  define tcgetattr(f, t)      ioctl(f, TCGETA, t)
+#  define tcsetattr(f, a, t)   ioctl(f, a, t)
+#  undef TCSAFLUSH
+#  define TCSAFLUSH            TCSETAF
+# else /* SGTTY */
+#  undef termios
+#  define termios              sgttyb
+#  define c_lflag              sg_flags
+#  define tcgetattr(f, t)      ioctl(f, TIOCGETP, t)
+#  define tcsetattr(f, a, t)   ioctl(f, a, t)
+#  undef TCSAFLUSH
+#  define TCSAFLUSH            TIOCSETP
+# endif /* HAVE_TERMIO_H */
+#endif /* HAVE_TERMIOS_H */
+
+typedef struct termios sudo_term_t;
+
+static sudo_term_t term, oterm;
+static int changed;
+int term_erase;
+int term_kill;
+
+int
+term_restore(fd)
+    int fd;
+{
+    if (changed) {
+       if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &oterm) != 0)
+           return(0);
+       changed = 0;
+    }
+    return(1);
+}
+
+int
+term_noecho(fd)
+    int fd;
+{
+    if (!changed && tcgetattr(fd, &oterm) != 0)
+       return(0);
+    (void) memcpy(&term, &oterm, sizeof(term));
+    CLR(term.c_lflag, ECHO|ECHONL);
+#ifdef VSTATUS
+    term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+#endif
+    if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
+       changed = 1;
+       return(1);
+    }
+    return(0);
+}
+
+#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
+int
+term_raw(fd)
+    int fd;
+{
+    if (!changed && tcgetattr(fd, &oterm) != 0)
+       return(0);
+    (void) memcpy(&term, &oterm, sizeof(term));
+    /* Set terminal to half-cooked mode */
+    term.c_cc[VMIN] = 1;
+    term.c_cc[VTIME] = 0;
+    CLR(term.c_lflag, ECHO | ECHONL | ICANON | IEXTEN);
+    SET(term.c_lflag, ISIG);
+#ifdef VSTATUS
+    term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+#endif
+    if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
+       term_erase = term.c_cc[VERASE];
+       term_kill = term.c_cc[VKILL];
+       changed = 1;
+       return(1);
+    }
+    return(0);
+}
+
+#else /* SGTTY */
+
+int
+term_raw(fd)
+    int fd;
+{
+    if (!changed && ioctl(fd, TIOCGETP, &oterm) != 0)
+       return(0);
+    (void) memcpy(&term, &oterm, sizeof(term));
+    /* Set terminal to half-cooked mode */
+    CLR(term.c_lflag, ECHO);
+    SET(term.sg_flags, CBREAK);
+    if (ioctl(fd, TIOCSETP, &term) == 0) {
+       term_erase = term.sg_erase;
+       term_kill = term.sg_kill;
+       changed = 1;
+       return(1);
+    }
+    return(0);
+}
+
+#endif
index 0eaf1d737cf55ba0fd0da47a78b0d4fc5802260d..c961432edd7058a83c76739bd04ecc44d848ef58 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -71,7 +71,7 @@
 #endif /* HAVE_FNMATCH */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: testsudoers.c,v 1.128 2008/11/19 17:01:20 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: testsudoers.c,v 1.131 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
 
@@ -373,8 +373,9 @@ set_fqdn()
 }
 
 FILE *
-open_sudoers(path, keepopen)
+open_sudoers(path, isdir, keepopen)
     const char *path;
+    int isdir;
     int *keepopen;
 {
     return(fopen(path, "r"));
@@ -386,11 +387,11 @@ init_envtables()
     return;
 }
 
-void
+int
 set_perms(perm)
     int perm;
 {
-    return;
+    return(1);
 }
 
 void
index 62faead2345f6c3d38cbbde484c0f6b42fde99f5..503cb972d4ad6516ae44ebab85c7aba2796fe948 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 
 #include <sys/types.h>
 #include <sys/param.h>
-#ifdef HAVE_SYS_BSDTYPES_H
-# include <sys/bsdtypes.h>
-#endif /* HAVE_SYS_BSDTYPES_H */
-#include <sys/time.h>
 #include <stdio.h>
 #ifdef STDC_HEADERS
 # include <stdlib.h>
 #include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
-#ifdef HAVE_TERMIOS_H
-# include <termios.h>
-#else
-# ifdef HAVE_TERMIO_H
-#  include <termio.h>
-# else
-#  include <sgtty.h>
-#  include <sys/ioctl.h>
-# endif /* HAVE_TERMIO_H */
-#endif /* HAVE_TERMIOS_H */
 
 #include "sudo.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.126 2008/12/09 20:55:49 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.131 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
-#ifndef TCSASOFT
-# define TCSASOFT      0
-#endif
-#ifndef ECHONL
-# define ECHONL        0
-#endif
-
-#ifndef _POSIX_VDISABLE
-# ifdef VDISABLE
-#  define _POSIX_VDISABLE      VDISABLE
-# else
-#  define _POSIX_VDISABLE      0
-# endif
-#endif
-
-/*
- * Compat macros for non-termios systems.
- */
-#ifndef HAVE_TERMIOS_H
-# ifdef HAVE_TERMIO_H
-#  undef termios
-#  define termios              termio
-#  define tcgetattr(f, t)      ioctl(f, TCGETA, t)
-#  define tcsetattr(f, a, t)   ioctl(f, a, t)
-#  undef TCSAFLUSH
-#  define TCSAFLUSH            TCSETAF
-# else
-#  undef termios
-#  define termios              sgttyb
-#  define c_lflag              sg_flags
-#  define tcgetattr(f, t)      ioctl(f, TIOCGETP, t)
-#  define tcsetattr(f, a, t)   ioctl(f, a, t)
-#  undef TCSAFLUSH
-#  define TCSAFLUSH            TIOCSETP
-# endif /* HAVE_TERMIO_H */
-#endif /* HAVE_TERMIOS_H */
-
 static volatile sig_atomic_t signo;
 
 static void handler __P((int));
-static char *getln __P((int, char *, size_t));
+static char *getln __P((int, char *, size_t, int));
 static char *sudo_askpass __P((const char *));
 
+extern int term_restore __P((int));
+extern int term_noecho __P((int));
+extern int term_raw __P((int));
+
 /*
  * Like getpass(3) but with timeout and echo flags.
  */
@@ -128,10 +81,9 @@ tgetpass(prompt, timeout, flags)
 {
     sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
     sigaction_t savetstp, savettin, savettou;
-    struct termios term, oterm;
     char *pass;
     static char buf[SUDO_PASS_MAX + 1];
-    int input, output, save_errno;
+    int input, output, save_errno, neednl;;
 
     (void) fflush(stdout);
 
@@ -167,19 +119,10 @@ restart:
     (void) sigaction(SIGTTIN, &sa, &savettin);
     (void) sigaction(SIGTTOU, &sa, &savettou);
 
-    /* Turn echo off/on as specified by flags.  */
-    if (tcgetattr(input, &oterm) == 0) {
-       (void) memcpy(&term, &oterm, sizeof(term));
-       if (!ISSET(flags, TGP_ECHO))
-           CLR(term.c_lflag, ECHO|ECHONL);
-#ifdef VSTATUS
-       term.c_cc[VSTATUS] = _POSIX_VDISABLE;
-#endif
-       (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
-    } else {
-       zero_bytes(&term, sizeof(term));
-       zero_bytes(&oterm, sizeof(oterm));
-    }
+    if (def_pwfeedback)
+       neednl = term_raw(input);
+    else
+       neednl = term_noecho(input);
 
     /* No output if we are already backgrounded. */
     if (signo != SIGTTOU && signo != SIGTTIN) {
@@ -188,20 +131,16 @@ restart:
 
        if (timeout > 0)
            alarm(timeout);
-       pass = getln(input, buf, sizeof(buf));
+       pass = getln(input, buf, sizeof(buf), def_pwfeedback);
        alarm(0);
        save_errno = errno;
 
-       if (!ISSET(term.c_lflag, ECHO))
+       if (neednl)
            (void) write(output, "\n", 1);
     }
 
     /* Restore old tty settings and signals. */
-    if (memcmp(&term, &oterm, sizeof(term)) != 0) {
-       while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
-           errno == EINTR)
-           continue;
-    }
+    term_restore(input);
     (void) sigaction(SIGALRM, &savealrm, NULL);
     (void) sigaction(SIGINT, &saveint, NULL);
     (void) sigaction(SIGHUP, &savehup, NULL);
@@ -269,35 +208,64 @@ sudo_askpass(prompt)
 
     /* Get response from child (askpass) and restore SIGPIPE handler */
     (void) close(pfd[1]);
-    pass = getln(pfd[0], buf, sizeof(buf));
+    pass = getln(pfd[0], buf, sizeof(buf), 0);
     (void) close(pfd[0]);
     (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
 
     return(pass);
 }
 
+extern int term_erase, term_kill;
+
 static char *
-getln(fd, buf, bufsiz)
+getln(fd, buf, bufsiz, feedback)
     int fd;
     char *buf;
     size_t bufsiz;
+    int feedback;
 {
+    size_t left = bufsiz;
     ssize_t nr = -1;
     char *cp = buf;
     char c = '\0';
 
-    if (bufsiz == 0) {
+    if (left == 0) {
        errno = EINVAL;
        return(NULL);                   /* sanity */
     }
 
-    while (--bufsiz) {
+    while (--left) {
        nr = read(fd, &c, 1);
        if (nr != 1 || c == '\n' || c == '\r')
            break;
+       if (feedback) {
+           if (c == term_kill) {
+               while (cp > buf) {
+                   (void) write(fd, "\b \b", 3);
+                   --cp;
+               }
+               left = bufsiz;
+               continue;
+           } else if (c == term_erase) {
+               if (cp > buf) {
+                   (void) write(fd, "\b \b", 3);
+                   --cp;
+                   left++;
+               }
+               continue;
+           }
+           (void) write(fd, "*", 1);
+       }
        *cp++ = c;
     }
     *cp = '\0';
+    if (feedback) {
+       /* erase stars */
+       while (cp > buf) {
+           (void) write(fd, "\b \b", 3);
+           --cp;
+       }
+    }
 
     return(nr == 1 ? buf : NULL);
 }
diff --git a/toke.c b/toke.c
index 0fd8ef954fae96ea93a238985a32648427d73002..a4bcb8eaa53d73d2a25ea2f43919d32221981fd0 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -3,7 +3,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /home/cvs/courtesan/sudo/toke.c,v 1.27 2008/11/24 00:42:20 millert Exp $
+ * $Header: /home/cvs/courtesan/sudo/toke.c,v 1.36 2009/05/27 00:47:17 millert Exp $
  */
 
 #define FLEX_SCANNER
@@ -288,69 +288,71 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 48
-#define YY_END_OF_BUFFER 49
-static yyconst short int yy_accept[534] =
+#define YY_NUM_RULES 50
+#define YY_END_OF_BUFFER 51
+static yyconst short int yy_accept[554] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,   49,   36,   44,   43,   42,   47,   36,   37,
-       38,   36,   39,   36,   36,   36,   36,   41,   40,   47,
-       32,   32,   32,   32,   32,   32,   47,   36,   36,   44,
-       47,   32,   32,   32,   32,   32,    1,   47,   36,   36,
-       16,   15,   16,   15,   15,   47,   47,   47,    2,    8,
-        7,    8,    3,    8,    4,   47,   12,   12,   12,   10,
-       11,   36,    0,   44,   42,    0,   46,    0,   36,   27,
-        0,   26,    0,   35,   35,    0,   36,   36,    0,   36,
-       36,   36,   36,    0,   30,   32,   32,   32,   32,   32,
-
-       32,   36,   45,   36,   44,    0,    0,    0,    0,    0,
-        0,   36,   36,   36,   36,   36,    1,   33,   33,    0,
-       36,   16,   16,   14,   13,   14,    0,    2,    8,    0,
-        5,    6,    8,    8,   12,    0,   12,   12,    0,    9,
-        0,    0,   36,   36,   36,   36,   36,    0,    0,   30,
-       30,   32,   32,   32,   32,   32,   32,   32,   36,    0,
-        0,    0,    0,    0,    0,   36,   36,   36,   36,   36,
-        0,   36,    9,   36,   36,   36,   36,   36,   36,    0,
-       31,   31,   31,    0,    0,   30,   30,   30,   30,   30,
-       30,   30,   32,   32,   32,   32,   32,   32,   32,   36,
-
-        0,    0,    0,    0,    0,    0,   36,   36,   36,   36,
-       36,   36,   36,    0,    0,   31,   31,   31,    0,   30,
-       30,    0,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,    0,   23,   32,   32,   32,   32,   32,
-       36,    0,    0,    0,    0,   36,   36,   36,   36,   36,
-       36,   36,   36,    0,   31,    0,   30,   30,   30,    0,
-        0,    0,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   32,   32,   32,   32,   32,
-       36,    0,    0,    0,   36,   36,   36,   28,   28,   28,
-        0,    0,   30,   30,   30,   30,   30,   30,   30,    0,
-
-        0,    0,    0,    0,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,    0,   22,
-       32,   32,    0,   21,    0,   24,   36,    0,    0,    0,
-       36,   36,   36,   36,   28,   28,   28,   28,    0,   30,
-        0,   30,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,    0,    0,    0,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,   32,   32,
-       34,    0,    0,    0,   36,   18,   33,   36,   29,   29,
-       29,   30,    0,    0,    0,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,    0,    0,
-
-        0,    0,    0,   30,   30,   30,   30,   30,   30,   30,
-       30,    0,   20,    0,   25,    0,   18,    0,   36,    0,
-       36,   36,   36,   29,   29,   29,   29,   29,    0,    0,
-        0,    0,    0,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,    0,    0,   19,   18,    0,   18,    0,
-       36,   36,   36,   29,   29,    0,    0,    0,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   19,    0,   17,   36,
-       36,   36,   36,   36,    0,    0,    0,    0,    0,   30,
-
-       30,   30,   30,   30,   30,   30,   30,   36,   36,   36,
-       30,   30,   30,   30,   30,   30,   36,   36,   36,   36,
-       36,   30,   30,   30,   30,   30,   28,   28,   28,   28,
-       28,   28,    0
+        0,    0,   51,   38,   46,   45,   44,   38,   49,   38,
+       39,   40,   38,   41,   38,   38,   38,   38,   43,   42,
+       49,   33,   33,   33,   33,   33,   33,   49,   38,   38,
+       46,   49,   33,   33,   33,   33,   33,    1,   49,   38,
+       38,   16,   15,   16,   15,   15,   49,   49,   49,    2,
+        8,    7,    8,    3,    8,    4,   49,   12,   12,   12,
+       10,   11,   38,    0,   46,   44,   38,    0,    0,    0,
+       48,    0,   38,   28,    0,    0,   27,    0,   36,   36,
+        0,   38,   38,    0,   38,   38,   38,   38,    0,   31,
+
+       33,   33,   33,   33,   33,   33,   38,   47,   38,   46,
+        0,    0,    0,    0,    0,    0,   38,   38,   38,   38,
+       38,    1,    0,   34,   34,    0,   38,   16,   16,   14,
+       13,   14,    0,    0,    2,    8,    0,    5,    6,    8,
+        8,   12,    0,   12,   12,    0,    9,   37,   37,    0,
+        0,   28,    0,    0,   38,   38,   38,   38,   38,    0,
+        0,   31,   31,   33,   33,   33,   33,   33,   33,   33,
+       38,    0,    0,    0,    0,    0,    0,   38,   38,   38,
+       38,   38,    0,   38,    9,    0,   38,   38,   38,   38,
+       38,   38,    0,   32,   32,   32,    0,    0,   31,   31,
+
+       31,   31,   31,   31,   31,   33,   33,   33,   33,   33,
+       33,   33,   38,    0,    0,    0,    0,    0,    0,   38,
+       38,   38,   38,   38,   38,   38,    0,    0,   32,   32,
+       32,    0,   31,   31,    0,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,    0,   24,   33,   33,
+       33,   33,   33,   38,    0,    0,    0,    0,   38,   38,
+       38,   38,   38,   38,   38,   38,    0,   32,    0,   31,
+       31,   31,    0,    0,    0,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   33,   33,
+       33,   33,   33,   38,    0,    0,    0,   38,   38,   38,
+
+       29,   29,   29,    0,    0,   31,   31,   31,   31,   31,
+       31,   31,    0,    0,    0,    0,    0,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+       31,    0,   23,   33,   33,    0,   22,    0,   25,   38,
+        0,    0,    0,   38,   38,   38,   38,   29,   29,   29,
+       29,    0,   31,    0,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,    0,    0,    0,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+       31,   33,   33,   35,    0,    0,    0,   38,   19,   34,
+       38,   30,   30,   30,   31,    0,    0,    0,   31,   31,
+
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+       31,    0,    0,    0,    0,    0,   31,   31,   31,   31,
+       31,   31,   31,   31,    0,   21,    0,   26,    0,   19,
+        0,    0,   38,    0,   38,   38,   38,   30,   30,   30,
+       30,   30,    0,    0,    0,    0,    0,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,    0,    0,    0,
+       20,   19,    0,   19,    0,   38,   38,   38,   30,   30,
+        0,    0,    0,   31,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+
+       31,   20,    0,   17,    0,   38,   38,   38,   38,   38,
+        0,    0,    0,    0,    0,   31,   31,   31,   31,   31,
+       31,   31,   31,    0,   38,   38,   38,   31,   31,   31,
+       31,   31,   31,    0,   38,   38,   38,   38,   38,   31,
+       31,   31,   31,   31,    0,   18,   29,   29,   29,   29,
+       29,   29,    0
     } ;
 
 static yyconst int yy_ec[256] =
@@ -396,527 +398,545 @@ static yyconst int yy_meta[63] =
        12,   12
     } ;
 
-static yyconst short int yy_base[594] =
+static yyconst short int yy_base[620] =
     {   0,
         0,   61,   62,   63,   69,   84,  128,  189,  250,  294,
-       80,  101, 2227, 2181, 2223, 3353, 2220,  337, 2164, 3353,
-     3353, 2154, 3353,  107,  347,  119,  137, 2172, 3353, 3353,
-      399, 2143,  446, 2141, 2139, 2098,  497,  145,   35,  167,
-      521, 2073, 2042, 2034, 2019, 2010, 2065,  193,  256,   55,
-        0, 3353, 2062,    0, 3353,  264,  573,  110,    0, 2020,
-     3353,   73, 3353,   76, 3353,  117, 2016,  105,  106, 3353,
-      142, 2014,  306, 2056, 2053, 2051, 3353,  201,  209, 1993,
-      506, 1990,  543,  276, 1989,  554,  306,  581, 2002, 2002,
-      325,  364,  317, 1982,   55,  618,    0, 1971,  240, 1963,
-
-     1961,  125, 3353,   98,  523, 1936, 1923, 1913, 1908, 1909,
-      146,  115,  219,   29,  212,  149, 1966,  481, 1922,  649,
-      154,    0, 1954,  256, 3353, 3353,  284,    0, 1897,  674,
-     3353, 3353, 1875,  484, 1848, 1885,  271,  307,  288, 1860,
-     1858,  676,  688,  720,  752,  784, 1846, 1835,  821,  268,
-      859,  896, 1820, 1799, 1814, 1809, 1786, 1792,  236, 1765,
-     1754, 1745, 1726, 1698,  300,  157, 1701,  259,   79,  329,
-      691,  344, 1711,  598,  348,  935,  967,  703,  366, 1688,
-     1687,  733,  455, 1686, 1670,  464,  709,  999,  760,  606,
-     1037,  770, 1669,  401, 1643, 1635, 1632, 1613, 1620,  356,
-
-     1604, 1578, 1563, 1575, 1547,  369,  435,  503,  233,  466,
-     1076, 1108, 1140, 1581, 1580,  801, 1565, 1563, 1562, 1545,
-      467,  838,  557,  876,  559, 1172,    0,  915, 1183,  943,
-      742, 1221,  953,  511, 3353, 1538, 1515, 1521, 1521, 1509,
-      483, 1477, 1460, 1461,  543,  363,   21,  532,  979,  505,
-     1260, 1292,  989, 1496, 1479, 1468, 1467, 1322,  468, 1019,
-     1056, 1086,  630,  648,  670, 1094,  926, 1361,    0, 1118,
-     1372, 1127,  846, 1410, 1150,  582, 1447, 1438,  583,  640,
-      636, 1409, 1381,  641,  632,  459,  638, 1448, 1479, 1510,
-     1411, 1393, 1381, 1158, 1542, 1200,  884, 1579, 1240, 1268,
-
-     1385, 1278, 1302, 1312,  674,  720, 1067, 1251, 1339, 1383,
-     1618,    0, 1394, 1629, 1427, 1208, 1667, 1458,  694, 3353,
-     1318, 1306,  743, 3353,  806, 3353,  749, 1292, 1274,  605,
-      923,  751,  876, 1466,  784, 1705, 1736, 1489, 1280, 1243,
-     1496,  771, 1519,  968, 1768,    0,  565, 1779, 1527, 1347,
-     1816, 1561, 1598, 1648, 1686, 1047, 1231, 1677, 1715, 1715,
-     1746, 1855,    0, 1748, 1866, 1724, 1435, 1757,  824,  918,
-     1219, 1194, 1187,  657,  667, 1895, 1165, 1927, 1959, 1991,
-     2023, 1160, 1798, 1835, 1886, 1158,  980, 1127, 1907, 1141,
-     2055,    0,  724, 2066, 1915, 1935, 2103, 1943, 1967, 1069,
-
-     1977, 2001, 2011, 1278, 1312, 1877,  813,  832, 2142,    0,
-      862, 1099, 3353, 1116, 3353, 1033, 2029,  976,  878, 1019,
-     1000, 2083, 1018, 2152, 2184, 2216, 2248, 2046, 2120,  997,
-     2162, 2172, 2194,  969,  898, 1293, 1392, 2200, 1543, 2280,
-        0, 1003, 2291, 2224, 2031, 2328, 2234, 2257, 2266, 2309,
-     1561,  871, 1029,  749,  761,  668,  650, 2359,  626, 2384,
-     2397, 2429, 2461, 2381, 1894, 2411, 2439, 2449,  628,  546,
-     1599, 1649, 2469, 1780, 2493,    0, 1097, 2504, 2477, 2091,
-     2523,  544, 2542, 2551, 2420,  521, 3353,  513, 3353, 2559,
-     1138, 2591, 2623, 2570, 2576,  488, 2602, 2612, 2633,  460,
-
-      381, 1799,  359,  303, 2641,    0, 1186, 2655, 2687, 2719,
-     2663, 2671, 2695,  289,    0,  182, 2703, 1289, 2751, 2783,
-     2733, 3353, 2739, 2763, 2128, 3353, 2771, 2791, 2801,  126,
-     2821, 2813, 3353, 2866, 2879, 2892, 2905, 2918, 2931, 2944,
-     2957, 2970, 2975, 2988, 3001, 3003, 3016, 3029, 3042, 3055,
-     3068, 3073, 3079, 3092, 3097, 3103, 3108, 3113, 3118, 3124,
-     3129, 3134, 3139, 3145, 3152, 3157, 3162, 3167, 3173, 3180,
-     3185, 3190, 3196, 3203, 3208, 3215, 3221, 3228, 3233, 3240,
-     3246, 3253, 3266, 3279, 3284, 3291, 3297, 3310, 3315, 3322,
-     3327, 3334, 3339
-
+       80,  101, 2349, 2303, 2345, 3488, 2316,  338,  381,   52,
+     3488, 3488, 2272, 3488,  107,  391,  119,  137, 2292, 3488,
+     3488,  443, 2271,  490, 2270, 2260, 2253,  541,  145,   55,
+      167,  565, 2228, 2232, 2224, 2219, 2206, 2254,  193,  256,
+       56,    0, 3488, 2249,    0, 3488,  264,  617,   77,    0,
+     2199, 3488,   82, 3488,   99, 3488,  110, 2189,  126,  106,
+     3488,  145, 2179,  306, 2185, 2182,  639, 2145, 2144, 2135,
+     3488,  201,  209,   74, 2082,  347, 2079,  550,  276, 2078,
+      587,  410,  669, 2098, 2104,  306,  358,  317, 2092,  179,
+
+      706,    0, 2083,  240, 2075, 2071,  389, 3488,   76,  355,
+     2039, 2041, 2033, 2021, 2000,   63,  115,  219,   29,  212,
+       98, 2056,  507,  361, 1986,  598,  154,    0, 2024,  256,
+     3488, 3488,  636,  284,    0, 1982,  567, 3488, 3488, 1981,
+      532, 1979, 1994,  271,  300,  288, 1975, 1905, 3488, 1944,
+     1916, 1873,  669,  603,  745,  777,  809,  841, 1902, 1876,
+      878,  268,  916,  953, 1869, 1854, 1854, 1849, 1841, 1831,
+      236, 1805, 1788, 1746, 1748, 1719,  317,  157, 1722,  307,
+      266,  258,  777,  296, 1766, 1764,  686,  402,  992, 1024,
+      725,  337, 1727, 1726,  787,  499, 1708, 1707,  343,  755,
+
+     1056,  796,  694, 1094,  819, 1705,  393, 1681, 1673, 1671,
+     1639, 1646,  373, 1629, 1616, 1601, 1614, 1586,  543,  400,
+      556,  233,  506, 1133, 1165, 1197, 1620, 1619,  827, 1619,
+     1602, 1601, 1590,  540,  858,  546,  895,  602, 1229,    0,
+      935, 1240,  970,  731, 1278, 1002,  601, 3488, 1581, 1571,
+     1577, 1577, 1537,  486, 1532, 1515, 1470,  387,  343,  380,
+      616, 1010,  423, 1317, 1349, 1044, 1470, 1469, 1451, 1450,
+     1379,  645, 1076, 1113, 1143,  652,  983, 1035, 1151, 1042,
+     1418,    0, 1175, 1429, 1184,  866, 1467, 1207,  644, 1430,
+     1436,  648,  672,  625, 1428, 1400,  680,  576,  487,  715,
+
+     1505, 1536, 1567, 1430, 1382, 1381, 1215, 1599, 1257,  903,
+     1636, 1297, 1325, 1347, 1335, 1359, 1369,  841, 1024, 1067,
+     1124, 1396, 1308, 1675,    0, 1448, 1686, 1484, 1265, 1724,
+     1515,  955, 3488, 1329, 1282,  956, 3488,  975, 3488,  807,
+     1266, 1244,  591, 1074,  569,  917, 1523,  155, 1762, 1793,
+     1546, 1280, 1243, 1553,  768, 1576,  810, 1825,    0,  429,
+     1836, 1584, 1404, 1873, 1618, 1655, 1705, 1743, 1288, 1335,
+     1734, 1772, 1772, 1803, 1912,    0, 1805, 1923, 1781, 1492,
+     1814,  993, 1156, 1221, 1211, 1181,  730,  635, 1952, 1194,
+     1984, 2016, 2048, 2080, 1153, 1855, 1892, 1943, 1152, 1184,
+
+     1198, 1964, 1350, 2112,    0,  762, 2123, 1972, 1992, 2160,
+     2000, 2024, 1126, 2034, 2058, 2068, 1369, 1609, 1934,  772,
+      806, 2199,    0,  844, 1173, 3488, 1468, 3488, 1090, 2086,
+     1389,  142,  991, 1076, 1075, 2140, 1038, 2209, 2241, 2273,
+     2305, 2103, 2177, 1088, 2219, 2229, 2251, 1077, 1076, 1656,
+     1706, 2257, 1837, 2337,    0,  881, 2348, 2281, 2088, 2385,
+     2291, 2314, 2323, 2366, 1855,  981,  927,  934,  957,  902,
+      898,  808, 2416,  743, 2441, 2454, 2486, 2518, 2438, 1951,
+     2468, 2496, 2506,  757,  716, 1893, 2001, 2526, 2035, 2550,
+        0, 1012, 2561, 2534, 2148, 2580,  647, 2599, 2608, 2477,
+
+      634, 3488,  629, 3488, 1051, 2616, 1195, 2648, 2680, 2627,
+     2633,  594, 2659, 2669, 2690,  573,  566, 2049,  557,  549,
+     2698,    0, 1045, 1545, 2712, 2744, 2776, 2720, 2728, 2752,
+      509,    0,  455,  357, 2760, 1535, 2808, 2840, 2790, 3488,
+     2796, 2820, 2185, 3488,  345, 3488, 2828, 2848, 2858,   25,
+     2878, 2870, 3488, 2923, 2936, 2949, 2962, 2975, 2988, 3001,
+     3014, 3027, 3040, 3045, 3058, 3071, 3073, 3086, 3099, 3112,
+     3125, 3138, 3151, 3164, 3177, 3182, 3188, 3201, 3214, 3219,
+     3225, 3230, 3235, 3240, 3246, 3251, 3256, 3261, 3267, 3274,
+     3279, 3284, 3289, 3295, 3302, 3307, 3312, 3318, 3325, 3330,
+
+     3337, 3343, 3350, 3355, 3362, 3368, 3375, 3388, 3401, 3406,
+     3413, 3419, 3432, 3437, 3444, 3449, 3456, 3461, 3474
     } ;
 
-static yyconst short int yy_def[594] =
+static yyconst short int yy_def[620] =
     {   0,
-      533,    1,    1,    1,  534,  534,  535,  535,  536,  536,
-      537,  537,  533,  538,  533,  533,  533,  539,  540,  533,
-      533,  541,  533,  542,  538,   25,   25,  543,  533,  533,
-      533,   31,   31,   33,   33,   33,  538,   25,  538,  533,
-      539,   31,   31,   33,   33,   33,  533,  533,  544,  538,
-      545,  533,  545,  545,  533,  533,  539,  533,  546,  547,
-      533,  547,  533,  547,  533,  548,  549,  549,  549,  533,
-      533,  538,  538,  533,  533,  550,  533,  533,  533,  540,
-      540,  541,  541,  542,  551,  538,  538,   25,  543,   88,
-       88,   88,   88,  552,  553,   31,   33,   33,   33,   33,
-
-       33,  538,  533,  538,  533,  533,  533,  533,  533,  533,
-      550,  538,   88,  538,  538,  538,  533,  544,  554,  538,
-      538,  545,  545,  533,  533,  533,  533,  546,  547,  547,
-      533,  533,  547,  547,  549,  533,  549,  549,  533,  533,
-      550,  533,  538,  538,  538,   88,  146,  555,  533,  556,
-      533,   31,   33,   33,   33,   33,   33,   33,  538,  533,
-      533,  533,  533,  533,  550,  538,  146,  538,  538,  538,
-      533,  538,  533,  538,  538,  538,  538,  538,  538,  557,
-      558,  558,  182,  559,  558,  560,  151,  533,  188,  188,
-      533,  188,   33,   33,   33,   33,   33,   33,   33,  538,
-
-      533,  533,  533,  533,  533,  550,  538,  538,  538,  538,
-      538,  538,  538,  533,  561,  561,  216,  561,  562,  563,
-      564,  533,  565,  191,  565,  565,  226,  565,  533,  229,
-      229,  533,  229,  533,  533,   33,   33,   33,   33,   33,
-      538,  533,  533,  533,  550,  538,  538,  538,  538,  538,
-      538,  538,  538,  566,  566,  567,  568,  533,  533,  533,
-      533,  533,  569,  569,  570,  232,  570,  570,  268,  570,
-      533,  271,  271,  533,  271,   33,   33,   33,   33,   33,
-      538,  533,  533,  550,  538,  538,  538,  538,  538,  538,
-      533,  571,  572,  258,  533,  295,  295,  533,  295,  533,
-
-      533,  533,  533,  533,  533,  573,  573,  574,  274,  574,
-      574,  311,  574,  533,  314,  314,  533,  314,  533,  533,
-       33,   33,  533,  533,  533,  533,  538,  533,  533,  550,
-      538,  538,  538,  538,  538,  538,  538,  538,  533,  575,
-      533,  576,  298,  576,  576,  345,  345,  533,  348,  348,
-      533,  348,  533,  533,  533,  533,  577,  577,  578,  317,
-      578,  578,  362,  578,  533,  365,  365,  365,   33,   33,
-      538,  533,  533,  550,  538,  538,  538,  538,  538,  538,
-      538,  533,  533,  533,  533,  579,  579,  580,  351,  580,
-      580,  391,  391,  533,  394,  394,  533,  394,  533,  533,
-
-      533,  533,  533,  533,  581,  581,  582,  582,  582,  409,
-      409,  533,  533,  533,  533,  533,  533,  550,  538,  583,
-      584,  538,  538,  538,  538,  538,  538,  538,  533,  533,
-      533,  533,  533,  533,  585,  585,  586,  397,  586,  586,
-      440,  440,  533,  443,  443,  533,  443,  533,  533,  533,
-      533,  587,  587,  533,  588,  538,  583,  583,  584,  584,
-      538,  538,  538,  538,  538,  533,  533,  533,  533,  589,
-      589,  590,  446,  590,  590,  475,  475,  533,  478,  478,
-      478,  533,  533,  533,  533,  533,  533,  588,  533,  538,
-      538,  538,  538,  538,  533,  533,  533,  533,  533,  533,
-
-      591,  591,  592,  592,  592,  505,  505,  538,  538,  538,
-      533,  533,  533,  533,  593,  593,  538,  538,  538,  538,
-      538,  533,  533,  533,  533,  533,  538,  538,  538,  538,
-      538,  538,    0,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533
-
+      553,    1,    1,    1,  554,  554,  555,  555,  556,  556,
+      557,  557,  553,  558,  553,  553,  553,  559,  560,  561,
+      553,  553,  562,  553,  563,  558,   26,   26,  564,  553,
+      553,  553,   32,   32,   34,   34,   34,  558,   26,  558,
+      553,  560,   32,   32,   34,   34,   34,  553,  553,  565,
+      558,  566,  553,  566,  566,  553,  553,  560,  553,  567,
+      568,  553,  568,  553,  568,  553,  569,  570,  570,  570,
+      553,  553,  558,  558,  553,  553,  559,  571,  559,  572,
+      553,  573,  553,  561,  574,  561,  562,  562,  563,  575,
+      558,  558,   26,  564,   93,   93,   93,   93,  576,  577,
+
+       32,   34,   34,   34,   34,   34,  558,  553,  558,  553,
+      553,  553,  553,  553,  553,  572,  558,   93,  558,  558,
+      558,  553,  553,  565,  578,  558,  558,  566,  566,  553,
+      553,  553,  573,  553,  567,  568,  568,  553,  553,  568,
+      568,  570,  553,  570,  570,  553,  553,  558,  553,  572,
+      579,  574,  574,  553,  558,  558,  558,   93,  158,  580,
+      553,  581,  553,   32,   34,   34,   34,   34,   34,   34,
+      558,  553,  553,  553,  553,  553,  572,  558,  158,  558,
+      558,  558,  553,  558,  553,  579,  558,  558,  558,  558,
+      558,  558,  582,  583,  583,  195,  584,  583,  585,  163,
+
+      553,  201,  201,  553,  201,   34,   34,   34,   34,   34,
+       34,   34,  558,  553,  553,  553,  553,  553,  572,  558,
+      558,  558,  558,  558,  558,  558,  553,  586,  586,  229,
+      586,  587,  588,  589,  553,  590,  204,  590,  590,  239,
+      590,  553,  242,  242,  553,  242,  553,  553,   34,   34,
+       34,   34,   34,  558,  553,  553,  553,  572,  558,  558,
+      558,  558,  558,  558,  558,  558,  591,  591,  592,  593,
+      553,  553,  553,  553,  553,  594,  594,  595,  245,  595,
+      595,  281,  595,  553,  284,  284,  553,  284,   34,   34,
+       34,   34,   34,  558,  553,  553,  572,  558,  558,  558,
+
+      558,  558,  558,  553,  596,  597,  271,  553,  308,  308,
+      553,  308,  553,  553,  553,  553,  553,  553,  598,  598,
+      599,  287,  599,  599,  324,  599,  553,  327,  327,  553,
+      327,  553,  553,   34,   34,  553,  553,  553,  553,  558,
+      553,  553,  572,  558,  558,  558,  558,  558,  558,  558,
+      558,  553,  600,  553,  601,  311,  601,  601,  358,  358,
+      553,  361,  361,  553,  361,  553,  553,  553,  553,  602,
+      602,  603,  330,  603,  603,  375,  603,  553,  378,  378,
+      378,   34,   34,  558,  553,  553,  572,  558,  558,  558,
+      558,  558,  558,  558,  553,  553,  553,  553,  604,  604,
+
+      605,  364,  605,  605,  404,  404,  553,  407,  407,  553,
+      407,  553,  553,  553,  553,  553,  553,  606,  606,  607,
+      607,  607,  422,  422,  553,  553,  553,  553,  553,  553,
+      572,  572,  558,  608,  609,  558,  558,  558,  558,  558,
+      558,  558,  553,  553,  553,  553,  553,  553,  610,  610,
+      611,  410,  611,  611,  454,  454,  553,  457,  457,  553,
+      457,  553,  553,  553,  553,  612,  612,  553,  613,  572,
+      558,  608,  608,  609,  609,  558,  558,  558,  558,  558,
+      553,  553,  553,  553,  614,  614,  615,  460,  615,  615,
+      490,  490,  553,  493,  493,  493,  553,  553,  553,  553,
+
+      553,  553,  613,  553,  572,  558,  558,  558,  558,  558,
+      553,  553,  553,  553,  553,  553,  616,  616,  617,  617,
+      617,  521,  521,  572,  558,  558,  558,  553,  553,  553,
+      553,  618,  618,  619,  558,  558,  558,  558,  558,  553,
+      553,  553,  553,  553,  619,  553,  558,  558,  558,  558,
+      558,  558,    0,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553
     } ;
 
-static yyconst short int yy_nxt[3416] =
+static yyconst short int yy_nxt[3551] =
     {   0,
-       14,   15,   16,   17,   14,   18,   19,   20,   21,   14,
-       22,   23,   14,   14,   24,   25,   26,   27,   25,   25,
-       25,   25,   25,   28,   29,   30,   14,   31,   31,   31,
-       31,   32,   33,   33,   34,   33,   35,   33,   36,   33,
-       33,   33,   33,   33,   37,   14,   38,   38,   38,   38,
-       38,   38,   14,   14,   14,   14,   14,   14,   14,   39,
-       14,   14,   40,   47,   47,   73,   41,   48,   48,  149,
-       15,   52,   53,   73,   54,  286,   49,   49,  151,   73,
-       55,   68,   16,   69,   70,   15,   52,   53,  168,   54,
-       42,   43,   55,   54,   44,   55,  104,  131,   45,   73,
-
-      132,   46,   68,   16,   69,   70,  137,   55,   54,  138,
-       85,  127,  103,   56,   85,   85,  121,  130,  134,  103,
-      130,   50,   50,   73,   71,  209,  127,  103,   56,   15,
-       16,   17,   85,   57,   91,   91,   91,   91,   91,   91,
-       91,   91,   73,  139,  140,   71,  135,  159,   77,  136,
-      136,   86,   92,   92,   92,   92,   92,   93,   72,   73,
-       90,   90,   90,   90,   90,   90,   90,   90,  105,   73,
-       73,  166,   58,   59,   59,   59,   59,   59,   59,   59,
-       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
-       15,   16,   17,   73,   57,  341,  106,  107,   73,  170,
-
-      108,   73,  165,  172,  109,   78,  207,  110,   79,   79,
-       79,   79,   79,   79,   79,   79,   79,   79,   79,   79,
-       79,   79,   79,   79,   79,   79,   79,   79,   79,   79,
-       79,   79,   72,   58,   59,   59,   59,   59,   59,   59,
-       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
-       59,   15,   16,   17,   61,   57,   73,  127,  103,  119,
-       62,   63,   64,  119,  119,  124,  103,  125,  169,  126,
-      167,  154,  137,  125,   65,  126,  155,   73,  156,   85,
-       73,  119,  149,   85,   85,  127,  103,  126,  126,  139,
-      140,  187,  207,  200,   66,   15,   16,   17,   61,   57,
-
-      120,   85,   77,   73,   62,   63,   64,   72,  126,   72,
-      138,   72,  473,   72,   72,  136,  533,   72,   65,  207,
-       86,  143,  144,  145,  143,  143,  143,  143,  143,   72,
-       72,   72,  147,  147,  147,  147,  147,  147,   66,   77,
-      147,  147,  147,  147,  147,  147,  147,  147,  206,   78,
-       73,  136,   79,   79,   79,   79,   79,   79,   79,   79,
-       87,  174,   88,   88,   88,   88,   88,   88,   88,   88,
-       89,   77,  341,   73,   90,   90,   90,   90,   90,  147,
-      147,  147,  147,  147,  147,  147,  147,  207,   73,   89,
-      285,   73,   73,   90,   90,   90,   90,   90,   90,   72,
-
-       73,  210,  234,   72,  473,   72,  241,   73,   72,   72,
-       73,   72,   72,   72,   96,   96,   96,   96,   96,   96,
-       96,   96,   89,  245,  235,   72,   96,   96,   96,   96,
-       96,   97,   97,   97,   97,   97,   97,   97,   97,   97,
-       97,   97,   97,   73,   97,   90,   90,   90,   90,   90,
-       90,   72,   72,   72,   72,   72,   72,   72,   72,   72,
-       72,   97,   97,   97,   97,   97,   97,   97,   97,  533,
-      218,  218,  218,   97,   97,   97,   97,   97,  149,   73,
-      246,  149,  149,  438,  119,  127,  103,  187,  119,  119,
-      187,  187,   72,   72,   72,   72,   72,   72,  102,  103,
-
-       72,  495,   72,   73,   72,   72,  119,   80,   72,   80,
-       73,   80,  234,   80,   80,  489,  248,   80,  249,  332,
-       72,   72,   72,   77,  105,  120,   89,   73,  130,   80,
-       80,   80,  281,   78,  235,  149,   79,   79,   79,   79,
-       79,   79,   79,   79,   82,   77,   82,   73,   82,   73,
-       82,   82,  106,  107,   82,   84,  108,   72,  149,   84,
-      109,   72,   72,  110,  247,   84,   82,   82,   82,  438,
-      222,  149,  533,  149,  111,   77,   73,   84,   84,   72,
-      224,  287,  224,  319,  323,  533,  386,  386,  533,  533,
-      533,  533,  533,  533,  533,  533,  146,  146,  146,  146,
-
-      146,  146,  146,  146,  284,  320,  324,   77,  146,  146,
-      146,  146,  146,  211,  212,  213,  211,  211,  211,  211,
-      211,  227,  227,  227,  227,  227,  228,  146,  146,  146,
-      146,  146,  146,  152,  152,  152,  152,  152,  152,  152,
-      152,  325,   73,   77,  149,  152,  152,  152,  152,  152,
-      118,  389,   72,  224,  118,  374,   72,   72,  418,   77,
-      118,  222,  149,  326,  146,  146,  146,  146,  146,  146,
-      460,  224,  118,  118,   72,  129,   73,   85,  129,  129,
-       73,   85,   73,  222,  149,  129,  331,   85,  149,  327,
-      330,  333,  119,  266,  458,  319,  119,  224,  129,   85,
-
-       85,  174,  119,  175,  175,  175,  175,  175,  175,  175,
-      175,   73,   73,  419,  119,  119,  174,  320,  175,  175,
-      175,  175,  175,  175,  192,  192,  192,  192,  192,  192,
-      192,  192,   73,  174,  149,  176,  176,  176,  176,  176,
-      176,  176,  176,  266,  323,  435,  435,   73,  216,  216,
-      217,  218,  218,  218,  218,  218,  184,  269,  269,  269,
-      269,  269,  270,  489,   73,  174,  324,  177,  177,  177,
-      177,  177,  178,  175,  175,  226,  226,  226,  226,  226,
-      226,  226,  226,  533,  341,  225,  225,  225,  225,  225,
-      225,  225,  225,   73,  343,   73,   73,   72,  334,  179,
-
-      179,  179,  179,  179,  179,  179,  179,  325,  487,  371,
-      376,  179,  179,  179,  179,  179,  255,  255,  255,  255,
-      255,  255,  255,  255,  184,  412,  222,  149,   73,  326,
-      179,  179,  179,  179,  179,  179,  181,  182,  183,  183,
-      183,  183,  183,  183,  184,  533,  149,  413,  185,  185,
-      185,  185,  185,  260,  261,  262,  260,  260,  260,  260,
-      260,  312,  312,  312,  312,  312,  313,  185,  185,  185,
-      185,  185,  185,  149,  188,  189,  190,  188,  188,  188,
-      188,  188,  191,  452,  452,  149,  192,  192,  192,  192,
-      192,  233,  233,  233,  233,  233,  233,  233,  233,  346,
-
-      346,  346,  346,  346,  347,  192,  192,  192,  192,  192,
-      192,  193,  193,  193,  193,  193,  193,  193,  193,  414,
-       73,  389,   73,  193,  193,  193,  193,  193,  222,  149,
-      264,  264,  264,  264,  264,  264,  377,  456,  224,  533,
-      149,  415,  179,  179,  179,  179,  179,  179,  174,  266,
-      175,  175,  175,  175,  175,  175,  175,  175,  268,  268,
-      268,  268,  268,  268,  268,  268,  533,   73,  267,  267,
-      267,  267,  267,  267,  267,  267,  375,  418,   77,   73,
-      174,  533,  175,  175,  175,  175,  175,  175,  175,  175,
-      455,  343,  343,  341,  288,  289,  290,  288,  288,  288,
-
-      288,  288,  249,  343,  250,  250,  250,  250,  250,  250,
-      429,   73,  222,  149,  223,  223,  223,  223,  223,  223,
-      223,  223,  224,   73,  470,  470,  225,  225,  225,  225,
-      225,  422,  300,   73,  301,  301,  301,  301,  301,  301,
-      301,  301,  222,  149,  460,  225,  225,  225,  225,  225,
-      225,  149,  229,  230,  231,  229,  229,  229,  229,  229,
-      232,  149,   73,  458,  233,  233,  233,  233,  233,  300,
-      266,  302,  302,  302,  302,  302,  302,  302,  302,  454,
-      222,  149,  399,  233,  233,  233,  233,  233,  233,  249,
-      266,  250,  250,  250,  250,  250,  250,  250,  250,  300,
-
-      412,  303,  303,  303,  303,  303,  304,  301,  301,  275,
-      275,  275,  275,  275,  275,  275,  275,  414,  501,  501,
-       73,  249,  413,  251,  251,  251,  251,  251,  251,  251,
-      251,  222,  149,  307,  307,  307,  307,  307,  307,  415,
-      341,  266,  311,  311,  311,  311,  311,  311,  311,  311,
-      389,  490,   73,  249,  533,  252,  252,  252,  252,  252,
-      253,  250,  250,  533,  389,  310,  310,  310,  310,  310,
-      310,  310,  310,  299,  299,  299,  299,  299,  299,  299,
-      299,  343,   73,  294,   73,  222,  149,  264,  264,  264,
-      264,  264,  264,  264,  264,  224,  222,  149,  265,  265,
-
-      265,  265,  265,  265,  265,  265,  266,  515,  515,   73,
-      267,  267,  267,  267,  267,  345,  345,  345,  345,  345,
-      345,  345,  345,  363,  363,  363,  363,  363,  364,  267,
-      267,  267,  267,  267,  267,  149,  271,  272,  273,  271,
-      271,  271,  271,  271,  274,  149,  417,  416,  275,  275,
-      275,  275,  275,  533,  309,  344,  344,  344,  344,  344,
-      344,  344,  344,   73,  222,  149,  294,  275,  275,  275,
-      275,  275,  275,  249,  309,  250,  250,  250,  250,  250,
-      250,  250,  250,  353,  354,  355,  353,  353,  353,  353,
-      353,  300,  149,  301,  301,  301,  301,  301,  301,  301,
-
-      301,  309,  517,  220,   73,  249,  341,  250,  250,  250,
-      250,  250,  250,  250,  250,  300,  389,  301,  301,  301,
-      301,  301,  301,  301,  301,  300,  149,  301,  301,  301,
-      301,  301,  301,   73,  373,  360,   73,  295,  296,  297,
-      295,  295,  295,  295,  295,  298,  372,  370,  369,  299,
-      299,  299,  299,  299,  318,  318,  318,  318,  318,  318,
-      318,  318,  392,  392,  392,  392,  392,  393,  299,  299,
-      299,  299,  299,  299,  222,  149,  307,  307,  307,  307,
-      307,  307,  307,  307,  266,  222,  149,  308,  308,  308,
-      308,  308,  308,  308,  308,  309,  533,  149,  300,  310,
-
-      310,  310,  310,  310,  294,  341,  309,  222,  149,  358,
-      358,  358,  358,  358,  358,  438,  220,  309,  310,  310,
-      310,  310,  310,  310,  149,  314,  315,  316,  314,  314,
-      314,  314,  314,  317,  184,  329,  328,  318,  318,  318,
-      318,  318,  362,  362,  362,  362,  362,  362,  362,  362,
-      410,  410,  410,  410,  410,  411,  318,  318,  318,  318,
-      318,  318,  334,  335,  335,  335,  335,  335,  335,  335,
-      335,  533,  322,  361,  361,  361,  361,  361,  361,  361,
-      361,  378,  379,  380,  381,  378,  378,  378,  378,  321,
-      294,  220,   73,  334,  336,  336,  336,  336,  336,  336,
-
-      336,  336,  184,  334,  335,  335,  335,  335,  335,  335,
-       73,  383,  384,  385,  383,  383,  383,  383,  383,  184,
-      242,  283,  282,   73,  334,  337,  337,  337,  337,  337,
-      338,  335,  335,   73,  352,  352,  352,  352,  352,  352,
-      352,  352,  391,  391,  391,  391,  391,  391,  391,  391,
-      280,  279,  278,  277,   73,  341,  533,  342,  342,  342,
-      342,  342,  342,  342,  342,  343,  438,  276,  258,  344,
-      344,  344,  344,  344,  533,  149,  390,  390,  390,  390,
-      390,  390,  390,  390,  360,  220,  184,  254,  344,  344,
-      344,  344,  344,  344,  348,  349,  350,  348,  348,  348,
-
-      348,  348,  351,  184,   95,  242,  352,  352,  352,  352,
-      352,  399,  341,  400,  400,  400,  400,  400,  400,  400,
-      400,  244,  438,  242,  243,  352,  352,  352,  352,  352,
-      352,  222,  149,  358,  358,  358,  358,  358,  358,  358,
-      358,  309,  222,  149,  359,  359,  359,  359,  359,  359,
-      359,  359,  360,  242,  240,  239,  361,  361,  361,  361,
-      361,  399,  341,  401,  401,  401,  401,  401,  401,  401,
-      401,  238,  473,  237,  236,  361,  361,  361,  361,  361,
-      361,  149,  365,  366,  367,  365,  365,  365,  365,  365,
-      222,  149,   89,  184,  368,  368,  368,  368,  368,  399,
-
-      309,  402,  402,  402,  402,  402,  403,  400,  400,  220,
-      184,   95,  173,  368,  368,  368,  368,  368,  368,  334,
-      335,  335,  335,  335,  335,  335,  335,  335,  222,  149,
-      368,  368,  368,  368,  368,  368,  368,  368,  360,  409,
-      409,  409,  409,  409,  409,  409,  409,  208,  205,   73,
-      334,  335,  335,  335,  335,  335,  335,  335,  335,  533,
-      149,  222,  149,  406,  406,  406,  406,  406,  406,  360,
-      533,  360,  408,  408,  408,  408,  408,  408,  408,  408,
-       73,  341,  204,  387,  387,  387,  387,  387,  387,  387,
-      387,  343,  341,  533,  388,  388,  388,  388,  388,  388,
-
-      388,  388,  389,  473,  203,  202,  390,  390,  390,  390,
-      390,  429,  341,  430,  430,  430,  430,  430,  430,  430,
-      430,  201,  473,  199,  198,  390,  390,  390,  390,  390,
-      390,  394,  395,  396,  394,  394,  394,  394,  394,  397,
-      197,  196,  195,  398,  398,  398,  398,  398,  429,  194,
-      431,  431,  431,  431,  431,  431,  431,  431,   95,   87,
-       77,  173,  398,  398,  398,  398,  398,  398,  222,  149,
-      406,  406,  406,  406,  406,  406,  406,  406,  360,  222,
-      149,  407,  407,  407,  407,  407,  407,  407,  407,  135,
-      222,  149,  136,  408,  408,  408,  408,  408,  420,  429,
-
-      360,  432,  432,  432,  432,  432,  433,  430,  430,  465,
-      465,  465,  408,  408,  408,  408,  408,  408,  420,  130,
-      420,  421,  398,  398,  398,  398,  398,  398,  398,  398,
-      440,  440,  440,  440,  440,  440,  440,  440,   73,   73,
-      422,  130,  423,  423,  423,  423,  423,  423,  423,  423,
-      441,  441,  441,  441,  441,  442,  533,  123,  439,  439,
-      439,  439,  439,  439,  439,  439,  171,  117,  164,  163,
-      162,   73,  422,  161,  424,  424,  424,  424,  424,  424,
-      424,  424,  448,  449,  450,  448,  448,  448,  448,  448,
-      399,  160,  400,  400,  400,  400,  400,  400,  400,  400,
-
-      158,  157,  153,   73,  422,   95,  425,  425,  425,  425,
-      425,  426,  427,  427,  399,   72,  400,  400,  400,  400,
-      400,  400,  400,  400,  399,   95,  400,  400,  400,  400,
-      400,  400,  420,  142,   83,   73,  422,   81,  428,  428,
-      428,  423,  423,  423,  423,  423,  476,  476,  476,  476,
-      476,  477,  420,   77,  420,  420,   75,   74,   73,  422,
-      136,  465,  465,  465,  130,  123,  117,   73,  341,  116,
-      436,  436,  436,  436,  436,  436,  436,  436,  389,  341,
-      115,  437,  437,  437,  437,  437,  437,  437,  437,  438,
-       73,  114,  113,  439,  439,  439,  439,  439,  461,  462,
-
-      463,  461,  461,  461,  461,  461,  506,  506,  506,  506,
-      506,  507,  439,  439,  439,  439,  439,  439,  443,  444,
-      445,  443,  443,  443,  443,  443,  446,   73,  112,  101,
-      447,  447,  447,  447,  447,  466,  467,  468,  466,  466,
-      466,  466,  466,  522,  522,  522,  522,  522,  522,  447,
-      447,  447,  447,  447,  447,  222,  149,  453,  453,  453,
-      453,  453,  453,  453,  453,  422,  100,  427,  427,  427,
-      427,  427,  427,  427,  427,  429,   99,  430,  430,  430,
-      430,  430,  430,  430,  430,  429,   98,  430,  430,  430,
-      430,  430,  430,  430,  430,   95,   73,  422,   83,  427,
-
-      427,  427,  427,  427,  427,  427,  427,  429,   81,  430,
-      430,  430,  430,  430,  430,  447,  447,  447,  447,  447,
-      447,  447,  447,   75,   74,   73,  533,  533,   73,  422,
-      533,  427,  427,  427,  427,  427,  427,  464,  464,  475,
-      475,  475,  475,  475,  475,  475,  475,  533,  533,  474,
-      474,  474,  474,  474,  474,  474,  474,  533,  533,  533,
-       73,  422,  533,  464,  464,  464,  464,  464,  464,  464,
-      464,  149,  482,  482,  482,  482,  482,  482,  482,  482,
-      149,  483,  483,  483,  483,  483,  483,  483,  483,  533,
-      533,  533,   73,  341,  533,  471,  471,  471,  471,  471,
-
-      471,  471,  471,  438,  341,  533,  472,  472,  472,  472,
-      472,  472,  472,  472,  473,  533,  533,  533,  474,  474,
-      474,  474,  474,  149,  484,  484,  484,  484,  484,  485,
-      482,  482,  533,  533,  533,  533,  533,  474,  474,  474,
-      474,  474,  474,  478,  479,  480,  478,  478,  478,  478,
-      478,  533,  533,  533,  533,  481,  481,  481,  481,  481,
-      457,  533,  457,  533,  457,  533,  457,  457,  533,  533,
-      457,  533,  533,  533,  481,  481,  481,  481,  481,  481,
-      533,  533,  457,  457,  457,  459,  533,  459,  533,  459,
-      533,  459,  459,  533,  533,  459,  464,  464,  464,  464,
-
-      464,  464,  464,  464,  533,  533,  533,  459,  459,  459,
-      490,  533,  491,  491,  491,  491,  491,  491,  491,  491,
-      533,  533,  533,  533,  495,   73,  496,  496,  496,  496,
-      496,  496,  496,  496,  149,  482,  482,  482,  482,  482,
-      482,   73,  490,  533,  492,  492,  492,  492,  492,  492,
-      492,  492,  495,  533,  497,  497,  497,  497,  497,  497,
-      497,  497,  495,  533,  498,  498,  498,  498,  498,  499,
-      496,  496,  533,   73,  490,  533,  493,  493,  493,  493,
-      493,  494,  491,  491,  481,  481,  481,  481,  481,  481,
-      481,  481,  505,  505,  505,  505,  505,  505,  505,  505,
-
-      533,  533,  533,  533,  533,   73,  341,  533,  502,  502,
-      502,  502,  502,  502,  502,  502,  473,  341,  533,  503,
-      503,  503,  503,  503,  503,  503,  503,  533,  533,  533,
-      533,  504,  504,  504,  504,  504,  533,  533,  504,  504,
-      504,  504,  504,  504,  504,  504,  533,  533,  533,  533,
-      504,  504,  504,  504,  504,  504,  149,  482,  482,  482,
-      482,  482,  482,  482,  482,  149,  482,  482,  482,  482,
-      482,  482,  482,  482,  508,  509,  510,  508,  508,  508,
-      508,  508,  533,  490,  533,  491,  491,  491,  491,  491,
-      491,  511,  512,  513,  511,  511,  511,  511,  511,  533,
-
-      533,  533,  533,   73,  490,  533,  491,  491,  491,  491,
-      491,  491,  491,  491,   73,  495,  533,  496,  496,  496,
-      496,  496,  496,  496,  496,  495,  533,  496,  496,  496,
-      496,  496,  496,  496,  496,   73,  490,  533,  491,  491,
-      491,  491,  491,  491,  491,  491,  495,  533,  496,  496,
-      496,  496,  496,  496,  341,  533,  516,  516,  516,  516,
-      516,  516,  516,  516,  533,  533,  533,   73,  517,  533,
-      518,  518,  518,  518,  518,  518,  518,  518,  522,  522,
-      522,  522,  522,  522,  522,  522,  523,  523,  523,  523,
-      523,  523,  523,  523,  533,  533,  533,  533,  533,   73,
-
-      517,  533,  519,  519,  519,  519,  519,  519,  519,  519,
-      524,  524,  524,  524,  524,  525,  522,  522,  527,  528,
-      529,  527,  527,  527,  527,  527,  533,  533,  533,  533,
-      533,   73,  517,  533,  520,  520,  520,  520,  520,  521,
-      518,  518,  533,  533,  533,  533,  517,   73,  518,  518,
-      518,  518,  518,  518,  522,  522,  522,  522,  522,  522,
-      522,  522,  533,   73,  517,  533,  518,  518,  518,  518,
-      518,  518,  518,  518,  533,  533,  533,   73,  522,  522,
-      522,  522,  522,  522,  522,  522,  530,  530,  530,  530,
-      530,  530,  530,  530,  533,   73,  517,  533,  518,  518,
-
-      518,  518,  518,  518,  518,  518,  527,  527,  527,  527,
-      527,  527,  527,  527,  533,   73,  531,  531,  531,  531,
-      531,  532,  530,  530,  533,  533,  533,   73,  530,  530,
-      530,  530,  530,  530,  533,   73,  530,  530,  530,  530,
-      530,  530,  530,  530,  533,   73,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,   73,  533,  533,
-      533,  533,  533,  533,  533,   73,   51,   51,   51,   51,
-       51,   51,   51,   51,   51,   51,   51,   51,   51,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   60,   60,   60,   60,   60,   60,   60,   60,
-
-       60,   60,   60,   60,   60,   67,   67,   67,   67,   67,
-       67,   67,   67,   67,   67,   67,   67,   67,   72,  533,
-      533,  533,   72,  533,   72,   72,   72,  533,   72,   72,
-       72,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   80,  533,  533,  533,   80,  533,
-       80,   80,   80,  533,   80,   80,   80,   82,  533,  533,
-      533,   82,  533,   82,   82,   82,  533,   82,   82,   82,
-       84,  533,  533,   84,   84,  533,   84,   84,   84,  533,
-       84,   84,   84,   94,   94,  533,  533,   94,  118,  533,
-      533,  118,  118,  533,  118,  118,  118,  533,  118,  118,
-
-      118,  122,  533,  533,  122,  122,  122,  122,  122,  122,
-      533,  533,  122,  122,  128,  128,  129,  533,  533,  129,
-      533,  533,  129,  129,  129,  129,  129,  129,  129,  133,
-      133,  133,  133,  133,  133,  133,  133,  133,  133,  133,
-      133,  133,  135,  135,  533,  135,  533,  135,  135,  135,
-      135,  135,  135,  135,  135,  141,  141,  141,  141,  141,
-      141,  141,  141,  141,  141,  141,  141,  141,   85,  533,
-      533,   85,   85,  533,   85,   85,   85,  533,   85,   85,
-       85,  148,  148,  533,  533,  148,  150,  150,  150,  533,
-      533,  150,  119,  533,  533,  119,  119,  533,  119,  119,
-
-      119,  533,  119,  119,  119,  180,  180,  533,  533,  180,
-      186,  186,  186,  533,  533,  186,  214,  214,  533,  533,
-      214,  215,  215,  533,  533,  215,  219,  219,  533,  533,
-      219,  221,  221,  221,  533,  533,  221,  254,  254,  533,
-      533,  254,  256,  256,  533,  533,  256,  257,  257,  533,
-      533,  257,  259,  259,  259,  533,  533,  259,  263,  263,
-      263,  263,  533,  533,  263,  291,  291,  533,  533,  291,
-      292,  292,  533,  533,  292,  293,  293,  533,  533,  293,
-      305,  305,  305,  533,  533,  305,  306,  306,  306,  306,
-      533,  533,  306,  339,  339,  533,  533,  339,  340,  340,
-
-      533,  533,  340,  356,  356,  356,  533,  533,  356,  357,
-      357,  357,  357,  533,  533,  357,  382,  382,  533,  533,
-      382,  386,  533,  386,  386,  533,  533,  386,  404,  404,
-      404,  533,  533,  404,  405,  405,  405,  405,  533,  533,
-      405,  434,  434,  533,  533,  434,  435,  533,  435,  435,
-      533,  533,  435,  451,  451,  451,  533,  533,  451,  452,
-      452,  452,  533,  533,  533,  452,  457,  533,  533,  533,
-      457,  533,  457,  457,  457,  533,  457,  457,  457,  459,
-      533,  533,  533,  459,  533,  459,  459,  459,  533,  459,
-      459,  459,  469,  469,  533,  533,  469,  470,  533,  470,
-
-      470,  533,  533,  470,  486,  486,  533,  533,  533,  486,
-      488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
-      488,  488,  488,  500,  500,  533,  533,  500,  501,  533,
-      501,  501,  533,  533,  501,  514,  514,  533,  533,  514,
-      515,  533,  515,  533,  533,  533,  515,  526,  533,  533,
-      533,  526,   13,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533
+       14,   15,   16,   17,   18,   19,   20,   21,   22,   14,
+       23,   24,   14,   14,   25,   26,   27,   28,   26,   26,
+       26,   26,   26,   29,   30,   31,   14,   32,   32,   32,
+       32,   33,   34,   34,   35,   34,   36,   34,   37,   34,
+       34,   34,   34,   34,   38,   14,   39,   39,   39,   39,
+       39,   39,   14,   14,   14,   14,   14,   14,   14,   40,
+       14,   14,   41,   48,   48,   81,   42,   49,   49,   74,
+       15,   53,   54,   74,   55,   85,   50,   50,  134,  108,
+       56,   69,   16,   70,   71,   15,   53,   54,  180,   55,
+       43,   44,   56,   55,   45,   56,   86,  553,   46,   74,
+
+       74,   47,   69,   16,   70,   71,  138,   56,   55,  145,
+       90,  141,  108,   57,   90,   90,  109,  127,   86,  177,
+       74,   51,   51,  139,   72,  171,  137,  144,   57,   15,
+       16,   17,   90,   58,   96,   96,   96,   96,   96,   96,
+       96,   96,   74,  137,   81,   72,  146,  147,  182,  142,
+      143,   91,   97,   97,   97,   97,   97,   98,   73,   74,
+       95,   95,   95,   95,   95,   95,   95,   95,  110,  347,
+      143,  178,   59,   60,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+       15,   16,   17,  161,   58,  470,  111,  112,   74,   74,
+
+      113,   74,  163,  184,  114,  123,  220,  115,   83,   83,
+       83,   83,   83,   83,   83,   83,   83,   83,   83,   83,
+       83,   83,   83,   83,   83,   83,   83,   83,   83,   83,
+       83,   83,   73,   59,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+       60,   15,   16,   17,   62,   58,   74,  134,  108,  125,
+       63,   64,   65,  125,  125,  130,  108,  131,  181,  132,
+      179,  166,  144,  131,   66,  132,  167,   74,  168,   90,
+       74,  125,  161,   90,   90,  134,  108,  132,  132,  146,
+      147,  200,  220,  213,   67,   15,   16,   17,   62,   58,
+
+      126,   90,   74,  145,   63,   64,   65,   73,  132,   73,
+       74,   73,  222,   73,   73,  143,  220,   73,   66,   81,
+       91,  159,  159,  159,  159,  159,  159,  159,  159,   73,
+       73,   73,  159,  159,  159,  159,  159,  159,   67,   78,
+       74,   78,   73,   78,  143,   78,   78,  546,   84,   78,
+       84,   74,   84,  223,   84,   84,  110,  161,   84,  546,
+       94,   78,   78,   78,  125,  219,  200,  220,  125,  125,
+      298,   84,   84,  159,  159,  159,  159,  159,  159,  159,
+      159,   74,   79,   81,  111,  112,  125,   74,  113,   81,
+      134,  108,  114,   82,  247,  115,   83,   83,   83,   83,
+
+       83,   83,   83,   83,   92,  126,   93,   93,   93,   93,
+       93,   93,   93,   93,   94,  187,  248,   74,   95,   95,
+       95,   95,   95,  254,   74,  155,  156,  157,  155,  155,
+      155,  155,  155,   74,  299,   74,  262,   95,   95,   95,
+       95,   95,   95,   73,   74,  259,   74,   73,  297,   73,
+      399,  399,   73,   73,   74,   73,   73,   73,  101,  101,
+      101,  101,  101,  101,  101,  101,   94,   74,  354,   73,
+      101,  101,  101,  101,  101,  102,  102,  102,  102,  102,
+      102,  102,  102,  102,  102,  102,  102,   74,  102,   95,
+       95,   95,   95,   95,   95,   73,   73,   73,   73,   73,
+
+       73,   73,   73,   73,   73,  102,  102,  102,  102,  102,
+      102,  102,  102,  553,  231,  231,  231,  102,  102,  102,
+      102,  102,   83,   83,   83,   83,   83,   83,   83,   83,
+       74,   74,  488,  134,  108,  294,   73,   73,   73,   73,
+       73,   73,  107,  108,   73,   81,   73,  345,   73,   73,
+       74,   87,   73,   87,  161,   87,  261,   87,   87,  235,
+      161,   87,  553,  200,   73,   73,   73,   81,  136,  237,
+      354,  136,  136,   87,   87,   87,  137,   82,  136,   94,
+       83,   83,   83,   83,   83,   83,   83,   83,   89,  488,
+       73,  136,   89,   81,   73,   73,  452,  258,   89,  124,
+
+       74,   73,  247,  124,   90,   73,   73,  511,   90,  124,
+       89,   89,   73,   74,   90,  553,  161,  260,  116,   81,
+       74,  124,  124,   73,  248,  237,   90,   90,  389,  133,
+      344,  504,  553,  553,  553,  553,  553,  553,  553,  553,
+       78,  387,   78,  148,   78,  332,   78,   78,  161,  336,
+       78,  553,  553,  553,  553,  553,  553,  553,  553,  161,
+       74,  161,   78,   78,   78,  300,  161,  333,  200,   74,
+      152,  337,  152,  338,  152,  237,  152,  152,  340,   74,
+      152,  433,   81,   79,  158,  158,  158,  158,  158,  158,
+      158,  158,  152,  152,  152,  339,  158,  158,  158,  158,
+
+      158,  224,  225,  226,  224,  224,  224,  224,  224,  240,
+      240,  240,  240,  240,  241,  158,  158,  158,  158,  158,
+      158,  164,  164,  164,  164,  164,  164,  164,  164,  343,
+       74,  431,   81,  164,  164,  164,  164,  164,  187,  452,
+      188,  188,  188,  188,  188,  188,  282,  282,  282,  282,
+      282,  283,  158,  158,  158,  158,  158,  158,  187,   74,
+      188,  188,  188,  188,  188,  188,  188,  188,  346,   74,
+      205,  205,  205,  205,  205,  205,  205,  205,  125,  432,
+      402,  354,  125,  449,  449,  235,  161,  475,  125,   74,
+      187,  356,  189,  189,  189,  189,  189,  189,  189,  189,
+
+      125,  125,  229,  229,  230,  231,  231,  231,  231,  231,
+      197,  239,  239,  239,  239,  239,  239,  239,  239,  553,
+      161,   74,  187,  553,  190,  190,  190,  190,  190,  191,
+      188,  188,  553,  356,  238,  238,  238,  238,  238,  238,
+      238,  238,  268,  268,  268,  268,  268,  268,  268,  268,
+      197,   74,  473,   74,   73,  161,  192,  192,  192,  192,
+      192,  192,  192,  192,  237,  466,  466,  384,  192,  192,
+      192,  192,  192,  273,  274,  275,  273,  273,  273,  273,
+      273,  325,  325,  325,  325,  325,  326,  192,  192,  192,
+      192,  192,  192,  194,  195,  196,  196,  196,  196,  196,
+
+      196,  197,  485,  485,   81,  198,  198,  198,  198,  198,
+      246,  246,  246,  246,  246,  246,  246,  246,  359,  359,
+      359,  359,  359,  360,  198,  198,  198,  198,  198,  198,
+      161,  201,  202,  203,  201,  201,  201,  201,  201,  204,
+      235,  161,   74,  205,  205,  205,  205,  205,  235,  161,
+      277,  277,  277,  277,  277,  277,  332,  336,  237,  504,
+      505,   74,  205,  205,  205,  205,  205,  205,  206,  206,
+      206,  206,  206,  206,  206,  206,  338,  390,  333,  337,
+      206,  206,  206,  206,  206,  281,  281,  281,  281,  281,
+      281,  281,  281,  502,  425,  161,  235,  161,  339,  192,
+
+      192,  192,  192,  192,  192,  187,  237,  188,  188,  188,
+      188,  188,  188,  188,  188,  553,  426,  280,  280,  280,
+      280,  280,  280,  280,  280,  301,  302,  303,  301,  301,
+      301,  301,  301,  517,  517,   74,   74,  187,  161,  188,
+      188,  188,  188,  188,  188,  188,  188,  279,  235,  161,
+      471,  436,  524,   81,   74,  553,  161,  262,  279,  263,
+      263,  263,  263,  263,  263,  279,  532,  532,   74,  235,
+      161,  236,  236,  236,  236,  236,  236,  236,  236,  237,
+      235,  161,   74,  238,  238,  238,  238,  238,   74,  313,
+      279,  314,  314,  314,  314,  314,  314,  314,  314,  402,
+
+      356,  443,  238,  238,  238,  238,  238,  238,  161,  242,
+      243,  244,  242,  242,  242,  242,  242,  245,   74,  475,
+      473,  246,  246,  246,  246,  246,  313,  388,  315,  315,
+      315,  315,  315,  315,  315,  315,  468,  235,  161,  412,
+      246,  246,  246,  246,  246,  246,  262,  322,  263,  263,
+      263,  263,  263,  263,  263,  263,  313,  427,  316,  316,
+      316,  316,  316,  317,  314,  314,  288,  288,  288,  288,
+      288,  288,  288,  288,  425,  356,  307,   74,  262,  428,
+      264,  264,  264,  264,  264,  264,  264,  264,  235,  161,
+      320,  320,  320,  320,  320,  320,  426,  354,  279,  324,
+
+      324,  324,  324,  324,  324,  324,  324,  356,  506,   74,
+      262,  354,  265,  265,  265,  265,  265,  266,  263,  263,
+      553,  402,  323,  323,  323,  323,  323,  323,  323,  323,
+      312,  312,  312,  312,  312,  312,  312,  312,   74,   74,
+      430,   74,  235,  161,  277,  277,  277,  277,  277,  277,
+      277,  277,  237,  235,  161,  278,  278,  278,  278,  278,
+      278,  278,  278,  279,  429,   74,  307,  280,  280,  280,
+      280,  280,  358,  358,  358,  358,  358,  358,  358,  358,
+      376,  376,  376,  376,  376,  377,  280,  280,  280,  280,
+      280,  280,  161,  284,  285,  286,  284,  284,  284,  284,
+
+      284,  287,  161,  233,  386,  288,  288,  288,  288,  288,
+      553,  279,  357,  357,  357,  357,  357,  357,  357,  357,
+      385,  553,  161,  383,  288,  288,  288,  288,  288,  288,
+      262,  322,  263,  263,  263,  263,  263,  263,  263,  263,
+      366,  367,  368,  366,  366,  366,  366,  366,  313,  161,
+      314,  314,  314,  314,  314,  314,  314,  314,  322,  382,
+      313,   74,  262,  553,  263,  263,  263,  263,  263,  263,
+      263,  263,  313,  402,  314,  314,  314,  314,  314,  314,
+      314,  314,  313,  161,  314,  314,  314,  314,  314,  314,
+      431,   81,  322,   74,  308,  309,  310,  308,  308,  308,
+
+      308,  308,  311,  469,  307,  233,  312,  312,  312,  312,
+      312,  331,  331,  331,  331,  331,  331,  331,  331,  405,
+      405,  405,  405,  405,  406,  312,  312,  312,  312,  312,
+      312,  235,  161,  320,  320,  320,  320,  320,  320,  320,
+      320,  279,  235,  161,  321,  321,  321,  321,  321,  321,
+      321,  321,  322,  197,  342,  341,  323,  323,  323,  323,
+      323,  235,  161,  371,  371,  371,  371,  371,  371,  427,
+      335,  322,  334,  307,  233,  323,  323,  323,  323,  323,
+      323,  161,  327,  328,  329,  327,  327,  327,  327,  327,
+      330,  428,  197,  197,  331,  331,  331,  331,  331,  375,
+
+      375,  375,  375,  375,  375,  375,  375,  423,  423,  423,
+      423,  423,  424,  331,  331,  331,  331,  331,  331,  347,
+      348,  348,  348,  348,  348,  348,  348,  348,  553,  255,
+      374,  374,  374,  374,  374,  374,  374,  374,  391,  392,
+      393,  394,  391,  391,  391,  391,  524,   81,  535,   74,
+      347,  349,  349,  349,  349,  349,  349,  349,  349,  534,
+      347,  348,  348,  348,  348,  348,  348,   74,  396,  397,
+      398,  396,  396,  396,  396,  396,  296,  295,  293,   74,
+       74,  347,  350,  350,  350,  350,  350,  351,  348,  348,
+       74,  365,  365,  365,  365,  365,  365,  365,  365,  404,
+
+      404,  404,  404,  404,  404,  404,  404,  292,  291,  290,
+      289,   74,  354,  271,  355,  355,  355,  355,  355,  355,
+      355,  355,  356,  161,  233,  197,  357,  357,  357,  357,
+      357,  553,  373,  403,  403,  403,  403,  403,  403,  403,
+      403,  267,  197,  100,  255,  357,  357,  357,  357,  357,
+      357,  361,  362,  363,  361,  361,  361,  361,  361,  364,
+      257,  255,  256,  365,  365,  365,  365,  365,  412,  354,
+      413,  413,  413,  413,  413,  413,  413,  413,  255,  402,
+      253,  252,  365,  365,  365,  365,  365,  365,  235,  161,
+      371,  371,  371,  371,  371,  371,  371,  371,  322,  235,
+
+      161,  372,  372,  372,  372,  372,  372,  372,  372,  373,
+      251,  250,  249,  374,  374,  374,  374,  374,  412,  354,
+      414,  414,  414,  414,  414,  414,  414,  414,   94,  452,
+      197,  233,  374,  374,  374,  374,  374,  374,  161,  378,
+      379,  380,  378,  378,  378,  378,  378,  235,  161,  197,
+      100,  381,  381,  381,  381,  381,  412,  322,  415,  415,
+      415,  415,  415,  416,  413,  413,   81,  185,  221,  218,
+      381,  381,  381,  381,  381,  381,  347,  348,  348,  348,
+      348,  348,  348,  348,  348,  235,  161,  381,  381,  381,
+      381,  381,  381,  381,  381,  373,  422,  422,  422,  422,
+
+      422,  422,  422,  422,  217,  216,   74,  347,  348,  348,
+      348,  348,  348,  348,  348,  348,  553,  161,  235,  161,
+      419,  419,  419,  419,  419,  419,  373,  553,  373,  421,
+      421,  421,  421,  421,  421,  421,  421,   74,  354,  215,
+      400,  400,  400,  400,  400,  400,  400,  400,  356,  354,
+      553,  401,  401,  401,  401,  401,  401,  401,  401,  402,
+      452,  214,  212,  403,  403,  403,  403,  403,  443,  161,
+      444,  444,  444,  444,  444,  444,  444,  444,  373,  211,
+      210,  209,  403,  403,  403,  403,  403,  403,  407,  408,
+      409,  407,  407,  407,  407,  407,  410,  208,  207,  100,
+
+      411,  411,  411,  411,  411,  443,  354,  445,  445,  445,
+      445,  445,  445,  445,  445,   92,  452,  153,   81,  411,
+      411,  411,  411,  411,  411,  235,  161,  419,  419,  419,
+      419,  419,  419,  419,  419,  373,  235,  161,  420,  420,
+      420,  420,  420,  420,  420,  420,   81,  235,  161,   74,
+      421,  421,  421,  421,  421,  434,  443,  373,  446,  446,
+      446,  446,  446,  447,  444,  444,  480,  480,  480,  421,
+      421,  421,  421,  421,  421,  434,  185,  434,  435,  411,
+      411,  411,  411,  411,  411,  411,  411,  454,  454,  454,
+      454,  454,  454,  454,  454,   74,   74,  436,  142,  437,
+
+      437,  437,  437,  437,  437,  437,  437,  455,  455,  455,
+      455,  455,  456,  553,  354,  453,  453,  453,  453,  453,
+      453,  453,  453,  143,  488,  137,  137,  129,   74,  436,
+      183,  438,  438,  438,  438,  438,  438,  438,  438,  462,
+      463,  464,  462,  462,  462,  462,  462,  412,  553,  413,
+      413,  413,  413,  413,  413,  413,  413,  122,  488,  176,
+       74,  436,  354,  439,  439,  439,  439,  439,  440,  441,
+      441,  412,  488,  413,  413,  413,  413,  413,  413,  413,
+      413,  412,  175,  413,  413,  413,  413,  413,  413,  434,
+      174,  173,   74,  436,  172,  442,  442,  442,  437,  437,
+
+      437,  437,  437,  491,  491,  491,  491,  491,  492,  434,
+      170,  434,  434,  169,  165,  100,  436,   73,  480,  480,
+      480,  100,  154,   88,   74,  354,  153,  450,  450,  450,
+      450,  450,  450,  450,  450,  402,  354,   81,  451,  451,
+      451,  451,  451,  451,  451,  451,  452,   74,  148,  149,
+      453,  453,  453,  453,  453,  476,  477,  478,  476,  476,
+      476,  476,  476,  522,  522,  522,  522,  522,  523,  453,
+      453,  453,  453,  453,  453,  457,  458,  459,  457,  457,
+      457,  457,  457,  460,   74,   76,   75,  461,  461,  461,
+      461,  461,  481,  482,  483,  481,  481,  481,  481,  481,
+
+      540,  540,  540,  540,  540,  540,  461,  461,  461,  461,
+      461,  461,  235,  161,  467,  467,  467,  467,  467,  467,
+      467,  467,  436,   74,  441,  441,  441,  441,  441,  441,
+      441,  441,  443,  143,  444,  444,  444,  444,  444,  444,
+      444,  444,  443,  137,  444,  444,  444,  444,  444,  444,
+      444,  444,  129,   74,  436,  122,  441,  441,  441,  441,
+      441,  441,  441,  441,  443,  121,  444,  444,  444,  444,
+      444,  444,  461,  461,  461,  461,  461,  461,  461,  461,
+      120,  119,  118,  117,  106,   74,  436,  105,  441,  441,
+      441,  441,  441,  441,  479,  479,  490,  490,  490,  490,
+
+      490,  490,  490,  490,  553,  104,  489,  489,  489,  489,
+      489,  489,  489,  489,  103,  100,   88,   74,  436,   76,
+      479,  479,  479,  479,  479,  479,  479,  479,  161,  497,
+      497,  497,  497,  497,  497,  497,  497,  161,  498,  498,
+      498,  498,  498,  498,  498,  498,   75,   74,  553,   74,
+      354,  553,  486,  486,  486,  486,  486,  486,  486,  486,
+      452,  354,  553,  487,  487,  487,  487,  487,  487,  487,
+      487,  488,  553,  553,  553,  489,  489,  489,  489,  489,
+      161,  499,  499,  499,  499,  499,  500,  497,  497,  553,
+      553,  553,  553,  553,  489,  489,  489,  489,  489,  489,
+
+      493,  494,  495,  493,  493,  493,  493,  493,  553,  553,
+      553,  553,  496,  496,  496,  496,  496,  472,  553,  472,
+      553,  472,  553,  472,  472,  553,  553,  472,  553,  553,
+      553,  496,  496,  496,  496,  496,  496,  553,  553,  472,
+      472,  472,  474,  553,  474,  553,  474,  553,  474,  474,
+      553,  553,  474,  479,  479,  479,  479,  479,  479,  479,
+      479,  553,  553,  553,  474,  474,  474,  506,  553,  507,
+      507,  507,  507,  507,  507,  507,  507,  553,  553,  553,
+      553,  511,   74,  512,  512,  512,  512,  512,  512,  512,
+      512,  161,  497,  497,  497,  497,  497,  497,   74,  506,
+
+      553,  508,  508,  508,  508,  508,  508,  508,  508,  511,
+      553,  513,  513,  513,  513,  513,  513,  513,  513,  511,
+      553,  514,  514,  514,  514,  514,  515,  512,  512,  553,
+       74,  506,  553,  509,  509,  509,  509,  509,  510,  507,
+      507,  496,  496,  496,  496,  496,  496,  496,  496,  521,
+      521,  521,  521,  521,  521,  521,  521,  553,  553,  553,
+      553,  553,   74,  354,  553,  518,  518,  518,  518,  518,
+      518,  518,  518,  488,  354,  553,  519,  519,  519,  519,
+      519,  519,  519,  519,  553,  553,  553,  553,  520,  520,
+      520,  520,  520,  553,  553,  520,  520,  520,  520,  520,
+
+      520,  520,  520,  553,  553,  553,  553,  520,  520,  520,
+      520,  520,  520,  161,  497,  497,  497,  497,  497,  497,
+      497,  497,  161,  497,  497,  497,  497,  497,  497,  497,
+      497,  525,  526,  527,  525,  525,  525,  525,  525,  553,
+      506,  553,  507,  507,  507,  507,  507,  507,  528,  529,
+      530,  528,  528,  528,  528,  528,  553,  553,  553,  553,
+       74,  506,  553,  507,  507,  507,  507,  507,  507,  507,
+      507,   74,  511,  553,  512,  512,  512,  512,  512,  512,
+      512,  512,  511,  553,  512,  512,  512,  512,  512,  512,
+      512,  512,   74,  506,  553,  507,  507,  507,  507,  507,
+
+      507,  507,  507,  511,  553,  512,  512,  512,  512,  512,
+      512,  354,  553,  533,  533,  533,  533,  533,  533,  533,
+      533,  553,  553,  553,   74,  535,  553,  536,  536,  536,
+      536,  536,  536,  536,  536,  540,  540,  540,  540,  540,
+      540,  540,  540,  541,  541,  541,  541,  541,  541,  541,
+      541,  553,  553,  553,  553,  553,   74,  535,  553,  537,
+      537,  537,  537,  537,  537,  537,  537,  542,  542,  542,
+      542,  542,  543,  540,  540,  547,  548,  549,  547,  547,
+      547,  547,  547,  553,  553,  553,  553,  553,   74,  535,
+      553,  538,  538,  538,  538,  538,  539,  536,  536,  553,
+
+      553,  553,  553,  535,   74,  536,  536,  536,  536,  536,
+      536,  540,  540,  540,  540,  540,  540,  540,  540,  553,
+       74,  535,  553,  536,  536,  536,  536,  536,  536,  536,
+      536,  553,  553,  553,   74,  540,  540,  540,  540,  540,
+      540,  540,  540,  550,  550,  550,  550,  550,  550,  550,
+      550,  553,   74,  535,  553,  536,  536,  536,  536,  536,
+      536,  536,  536,  547,  547,  547,  547,  547,  547,  547,
+      547,  553,   74,  551,  551,  551,  551,  551,  552,  550,
+      550,  553,  553,  553,   74,  550,  550,  550,  550,  550,
+      550,  553,   74,  550,  550,  550,  550,  550,  550,  550,
+
+      550,  553,   74,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,   74,  553,  553,  553,  553,  553,
+      553,  553,   74,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   61,
+       61,   61,   61,   61,   61,   61,   61,   61,   61,   61,
+       61,   61,   68,   68,   68,   68,   68,   68,   68,   68,
+       68,   68,   68,   68,   68,   73,  553,  553,  553,   73,
+      553,   73,   73,   73,  553,   73,   73,   73,   77,   77,
+      553,   77,   77,   77,   77,   77,   77,   77,   77,   77,
+
+       77,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80,   80,   80,   80,   84,  553,  553,  553,   84,  553,
+       84,   84,   84,   84,   84,   84,   84,   87,  553,  553,
+      553,   87,  553,   87,   87,   87,  553,   87,   87,   87,
+       89,  553,  553,   89,   89,  553,   89,   89,   89,  553,
+       89,   89,   89,   99,   99,  553,  553,   99,  124,  553,
+      553,  124,  124,  553,  124,  124,  124,  553,  124,  124,
+      124,  128,  553,  553,  128,  128,  128,  128,  128,  128,
+      553,  553,  128,  128,  135,  135,  136,  553,  553,  136,
+      553,  553,  136,  136,  136,  136,  136,  136,  136,  140,
+
+      140,  140,  140,  140,  140,  140,  140,  140,  140,  140,
+      140,  140,  142,  142,  553,  142,  553,  142,  142,  142,
+      142,  142,  142,  142,  142,   78,   78,  553,   78,   78,
+       78,   78,   78,   78,   78,   78,   78,   78,  150,  150,
+      150,  150,  150,  150,  150,  150,  150,  150,  150,  150,
+      150,  151,  151,  553,  151,  151,  151,  151,  151,  151,
+      151,  151,  151,  151,  152,  553,  553,  553,  152,  553,
+      152,  152,  152,  553,  152,  152,  152,   90,  553,  553,
+       90,   90,  553,   90,   90,   90,  553,   90,   90,   90,
+      160,  160,  553,  553,  160,  162,  162,  162,  553,  553,
+
+      162,  125,  553,  553,  125,  125,  553,  125,  125,  125,
+      553,  125,  125,  125,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  193,  193,  553,
+      553,  193,  199,  199,  199,  553,  553,  199,  227,  227,
+      553,  553,  227,  228,  228,  553,  553,  228,  232,  232,
+      553,  553,  232,  234,  234,  234,  553,  553,  234,  267,
+      267,  553,  553,  267,  269,  269,  553,  553,  269,  270,
+      270,  553,  553,  270,  272,  272,  272,  553,  553,  272,
+      276,  276,  276,  276,  553,  553,  276,  304,  304,  553,
+      553,  304,  305,  305,  553,  553,  305,  306,  306,  553,
+
+      553,  306,  318,  318,  318,  553,  553,  318,  319,  319,
+      319,  319,  553,  553,  319,  352,  352,  553,  553,  352,
+      353,  353,  553,  553,  353,  369,  369,  369,  553,  553,
+      369,  370,  370,  370,  370,  553,  553,  370,  395,  395,
+      553,  553,  395,  399,  553,  399,  399,  553,  553,  399,
+      417,  417,  417,  553,  553,  417,  418,  418,  418,  418,
+      553,  553,  418,  448,  448,  553,  553,  448,  449,  553,
+      449,  449,  553,  553,  449,  465,  465,  465,  553,  553,
+      465,  466,  466,  466,  553,  553,  553,  466,  472,  553,
+      553,  553,  472,  553,  472,  472,  472,  553,  472,  472,
+
+      472,  474,  553,  553,  553,  474,  553,  474,  474,  474,
+      553,  474,  474,  474,  484,  484,  553,  553,  484,  485,
+      553,  485,  485,  553,  553,  485,  501,  501,  553,  553,
+      553,  501,  503,  503,  503,  503,  503,  503,  503,  503,
+      503,  503,  503,  503,  503,  516,  516,  553,  553,  516,
+      517,  553,  517,  517,  553,  553,  517,  531,  531,  553,
+      553,  531,  532,  553,  532,  553,  553,  553,  532,  544,
+      553,  553,  553,  544,  545,  545,  545,  545,  545,  545,
+      545,  545,  545,  545,  545,  545,  545,   13,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553
     } ;
 
-static yyconst short int yy_chk[3416] =
+static yyconst short int yy_chk[3551] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -924,376 +944,390 @@ static yyconst short int yy_chk[3416] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    2,    3,    4,  247,    2,    3,    4,   95,
-        5,    5,    5,  114,    5,  247,    3,    4,   95,   39,
-        5,   11,   11,   11,   11,    6,    6,    6,  114,    6,
-        2,    2,    5,    5,    2,    6,   39,   62,    2,   50,
-
-       64,    2,   12,   12,   12,   12,   68,    6,    6,   69,
-       24,   58,   58,    5,   24,   24,   50,   62,   66,   66,
-       64,    3,    4,  169,   11,  169,  102,  102,    6,    7,
-        7,    7,   24,    7,   26,   26,   26,   26,   26,   26,
-       26,   26,  104,   71,   71,   12,   71,  104,  111,   68,
-       69,   24,   27,   27,   27,   27,   27,   27,   38,  112,
-       38,   38,   38,   38,   38,   38,   38,   38,   40,  102,
-      530,  112,    7,    7,    7,    7,    7,    7,    7,    7,
+        1,    1,    2,    3,    4,  116,    2,    3,    4,  550,
+        5,    5,    5,  119,    5,   20,    3,    4,   59,   59,
+        5,   11,   11,   11,   11,    6,    6,    6,  119,    6,
+        2,    2,    5,    5,    2,    6,   20,   84,    2,   40,
+
+       51,    2,   12,   12,   12,   12,   63,    6,    6,   70,
+       25,   67,   67,    5,   25,   25,   40,   51,   84,  116,
+      109,    3,    4,   65,   11,  109,   63,   69,    6,    7,
+        7,    7,   25,    7,   27,   27,   27,   27,   27,   27,
+       27,   27,  121,   65,  432,   12,   72,   72,  121,   72,
+       70,   25,   28,   28,   28,   28,   28,   28,   39,  117,
+       39,   39,   39,   39,   39,   39,   39,   39,   41,  348,
+       69,  117,    7,    7,    7,    7,    7,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        8,    8,    8,  116,    8,  516,   40,   40,  121,  116,
+        8,    8,    8,  100,    8,  432,   41,   41,  127,  348,
 
-       40,  166,  111,  121,   40,   48,  166,   40,   48,   48,
-       48,   48,   48,   48,   48,   48,   78,   78,   78,   78,
-       78,   78,   78,   78,   79,   79,   79,   79,   79,   79,
-       79,   79,  113,    8,    8,    8,    8,    8,    8,    8,
+       41,  178,  100,  127,   41,   49,  178,   41,   49,   49,
+       49,   49,   49,   49,   49,   49,   82,   82,   82,   82,
+       82,   82,   82,   82,   83,   83,   83,   83,   83,   83,
+       83,   83,  118,    8,    8,    8,    8,    8,    8,    8,
         8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    9,    9,    9,    9,    9,  115,  124,  124,   49,
-        9,    9,    9,   49,   49,   56,   56,   56,  115,   56,
-      113,   99,  137,   56,    9,   56,   99,  209,   99,   84,
-      159,   49,  150,   84,   84,  127,  127,   56,   56,  139,
-      139,  150,  209,  159,    9,   10,   10,   10,   10,   10,
-
-       49,   84,  165,  168,   10,   10,   10,   73,   56,   73,
-      138,   73,  514,   73,   73,  137,  504,   73,   10,  168,
-       84,   87,   87,   87,   87,   87,   87,   87,   87,   73,
-       73,   73,   93,   93,   93,   93,   93,   93,   10,   18,
-       91,   91,   91,   91,   91,   91,   91,   91,  165,   18,
-       87,  138,   18,   18,   18,   18,   18,   18,   18,   18,
-       25,  175,   25,   25,   25,   25,   25,   25,   25,   25,
-       25,  206,  503,  170,   25,   25,   25,   25,   25,   92,
-       92,   92,   92,   92,   92,   92,   92,  170,  172,  179,
-      246,   25,  175,   25,   25,   25,   25,   25,   25,   31,
-
-      200,  172,  194,   31,  501,   31,  200,  246,   31,   31,
-      179,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   31,  206,  194,   31,   31,   31,   31,   31,
-       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   33,   33,   33,   33,   33,   33,   33,   33,   33,
-      183,  183,  183,   33,   33,   33,   33,   33,  186,  207,
-      207,  221,  259,  500,  118,  134,  134,  186,  118,  118,
-      221,  259,   33,   33,   33,   33,   33,   33,   37,   37,
-
-       37,  496,   37,  286,   37,   37,  118,   81,   37,   81,
-      210,   81,  234,   81,   81,  488,  210,   81,  250,  286,
-       37,   37,   37,   41,  105,  118,  208,  241,  134,   81,
-       81,   81,  241,   41,  234,  486,   41,   41,   41,   41,
-       41,   41,   41,   41,   83,  245,   83,  208,   83,  250,
-       83,   83,  105,  105,   83,   86,  105,   86,  482,   86,
-      105,   86,   86,  105,  208,   86,   83,   83,   83,  470,
-      223,  223,  225,  225,   41,   57,  248,   86,   86,   86,
-      223,  248,  225,  276,  279,   57,  347,  347,   57,   57,
-       57,   57,   57,   57,   57,   57,   88,   88,   88,   88,
-
-       88,   88,   88,   88,  245,  276,  279,  330,   88,   88,
-       88,   88,   88,  174,  174,  174,  174,  174,  174,  174,
-      174,  190,  190,  190,  190,  190,  190,   88,   88,   88,
-       88,   88,   88,   96,   96,   96,   96,   96,   96,   96,
-       96,  280,  174,  284,  263,   96,   96,   96,   96,   96,
-      120,  469,  120,  263,  120,  330,  120,  120,  374,  374,
-      120,  264,  264,  280,   96,   96,   96,   96,   96,   96,
-      459,  264,  120,  120,  120,  130,  285,  142,  130,  130,
-      281,  142,  287,  265,  265,  130,  285,  142,  305,  281,
-      284,  287,  171,  265,  457,  319,  171,  305,  130,  142,
-
-      142,  143,  171,  143,  143,  143,  143,  143,  143,  143,
-      143,  375,  456,  375,  171,  171,  178,  319,  178,  178,
-      178,  178,  178,  178,  187,  187,  187,  187,  187,  187,
-      187,  187,  143,  144,  306,  144,  144,  144,  144,  144,
-      144,  144,  144,  306,  323,  393,  393,  178,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  231,  231,  231,
-      231,  231,  231,  455,  144,  145,  323,  145,  145,  145,
-      145,  145,  145,  145,  145,  189,  189,  189,  189,  189,
-      189,  189,  189,  192,  342,  192,  192,  192,  192,  192,
-      192,  192,  192,  327,  342,  332,  145,  146,  335,  146,
-
-      146,  146,  146,  146,  146,  146,  146,  325,  454,  327,
-      332,  146,  146,  146,  146,  146,  216,  216,  216,  216,
-      216,  216,  216,  216,  216,  369,  407,  407,  335,  325,
-      146,  146,  146,  146,  146,  146,  149,  149,  149,  149,
-      149,  149,  149,  149,  149,  408,  408,  369,  149,  149,
-      149,  149,  149,  222,  222,  222,  222,  222,  222,  222,
-      222,  273,  273,  273,  273,  273,  273,  149,  149,  149,
-      149,  149,  149,  151,  151,  151,  151,  151,  151,  151,
-      151,  151,  151,  411,  411,  452,  151,  151,  151,  151,
-      151,  224,  224,  224,  224,  224,  224,  224,  224,  297,
-
-      297,  297,  297,  297,  297,  151,  151,  151,  151,  151,
-      151,  152,  152,  152,  152,  152,  152,  152,  152,  370,
-      333,  435,  419,  152,  152,  152,  152,  152,  228,  228,
-      228,  228,  228,  228,  228,  228,  333,  419,  228,  267,
-      267,  370,  152,  152,  152,  152,  152,  152,  176,  267,
-      176,  176,  176,  176,  176,  176,  176,  176,  230,  230,
-      230,  230,  230,  230,  230,  230,  233,  331,  233,  233,
-      233,  233,  233,  233,  233,  233,  331,  418,  418,  176,
-      177,  344,  177,  177,  177,  177,  177,  177,  177,  177,
-      418,  344,  434,  387,  249,  249,  249,  249,  249,  249,
-
-      249,  249,  253,  387,  253,  253,  253,  253,  253,  253,
-      430,  177,  188,  188,  188,  188,  188,  188,  188,  188,
-      188,  188,  188,  249,  442,  442,  188,  188,  188,  188,
-      188,  423,  260,  253,  260,  260,  260,  260,  260,  260,
-      260,  260,  453,  453,  421,  188,  188,  188,  188,  188,
-      188,  191,  191,  191,  191,  191,  191,  191,  191,  191,
-      191,  356,  423,  420,  191,  191,  191,  191,  191,  261,
-      356,  261,  261,  261,  261,  261,  261,  261,  261,  416,
-      307,  307,  400,  191,  191,  191,  191,  191,  191,  211,
-      307,  211,  211,  211,  211,  211,  211,  211,  211,  262,
-
-      412,  262,  262,  262,  262,  262,  262,  262,  262,  266,
-      266,  266,  266,  266,  266,  266,  266,  414,  477,  477,
-      211,  212,  412,  212,  212,  212,  212,  212,  212,  212,
-      212,  270,  270,  270,  270,  270,  270,  270,  270,  414,
-      388,  270,  272,  272,  272,  272,  272,  272,  272,  272,
-      388,  491,  212,  213,  390,  213,  213,  213,  213,  213,
-      213,  213,  213,  275,  390,  275,  275,  275,  275,  275,
-      275,  275,  275,  294,  294,  294,  294,  294,  294,  294,
-      294,  386,  491,  382,  213,  226,  226,  226,  226,  226,
-      226,  226,  226,  226,  226,  226,  229,  229,  229,  229,
-
-      229,  229,  229,  229,  229,  229,  229,  507,  507,  377,
-      229,  229,  229,  229,  229,  296,  296,  296,  296,  296,
-      296,  296,  296,  316,  316,  316,  316,  316,  316,  229,
-      229,  229,  229,  229,  229,  232,  232,  232,  232,  232,
-      232,  232,  232,  232,  232,  357,  373,  372,  232,  232,
-      232,  232,  232,  299,  357,  299,  299,  299,  299,  299,
-      299,  299,  299,  371,  308,  308,  340,  232,  232,  232,
-      232,  232,  232,  251,  308,  251,  251,  251,  251,  251,
-      251,  251,  251,  300,  300,  300,  300,  300,  300,  300,
-      300,  302,  404,  302,  302,  302,  302,  302,  302,  302,
-
-      302,  404,  518,  339,  251,  252,  436,  252,  252,  252,
-      252,  252,  252,  252,  252,  303,  436,  303,  303,  303,
-      303,  303,  303,  303,  303,  304,  405,  304,  304,  304,
-      304,  304,  304,  518,  329,  405,  252,  258,  258,  258,
-      258,  258,  258,  258,  258,  258,  328,  322,  321,  258,
-      258,  258,  258,  258,  309,  309,  309,  309,  309,  309,
-      309,  309,  350,  350,  350,  350,  350,  350,  258,  258,
-      258,  258,  258,  258,  268,  268,  268,  268,  268,  268,
-      268,  268,  268,  268,  268,  271,  271,  271,  271,  271,
-      271,  271,  271,  271,  271,  271,  310,  310,  301,  271,
-
-      271,  271,  271,  271,  293,  437,  310,  313,  313,  313,
-      313,  313,  313,  313,  313,  437,  292,  313,  271,  271,
-      271,  271,  271,  271,  274,  274,  274,  274,  274,  274,
-      274,  274,  274,  274,  291,  283,  282,  274,  274,  274,
-      274,  274,  315,  315,  315,  315,  315,  315,  315,  315,
-      367,  367,  367,  367,  367,  367,  274,  274,  274,  274,
-      274,  274,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  318,  278,  318,  318,  318,  318,  318,  318,  318,
-      318,  334,  334,  334,  334,  334,  334,  334,  334,  277,
-      257,  256,  288,  289,  289,  289,  289,  289,  289,  289,
-
-      289,  289,  255,  338,  338,  338,  338,  338,  338,  338,
-      334,  341,  341,  341,  341,  341,  341,  341,  341,  254,
-      244,  243,  242,  289,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  338,  343,  343,  343,  343,  343,  343,
-      343,  343,  349,  349,  349,  349,  349,  349,  349,  349,
-      240,  239,  238,  237,  290,  295,  439,  295,  295,  295,
-      295,  295,  295,  295,  295,  295,  439,  236,  220,  295,
-      295,  295,  295,  295,  352,  451,  352,  352,  352,  352,
-      352,  352,  352,  352,  451,  219,  218,  217,  295,  295,
-      295,  295,  295,  295,  298,  298,  298,  298,  298,  298,
-
-      298,  298,  298,  215,  214,  205,  298,  298,  298,  298,
-      298,  353,  471,  353,  353,  353,  353,  353,  353,  353,
-      353,  204,  471,  203,  202,  298,  298,  298,  298,  298,
-      298,  311,  311,  311,  311,  311,  311,  311,  311,  311,
-      311,  311,  314,  314,  314,  314,  314,  314,  314,  314,
-      314,  314,  314,  201,  199,  198,  314,  314,  314,  314,
-      314,  354,  472,  354,  354,  354,  354,  354,  354,  354,
-      354,  197,  472,  196,  195,  314,  314,  314,  314,  314,
-      314,  317,  317,  317,  317,  317,  317,  317,  317,  317,
-      358,  358,  193,  185,  317,  317,  317,  317,  317,  355,
-
-      358,  355,  355,  355,  355,  355,  355,  355,  355,  184,
-      181,  180,  173,  317,  317,  317,  317,  317,  317,  336,
-      336,  336,  336,  336,  336,  336,  336,  336,  359,  359,
-      360,  360,  360,  360,  360,  360,  360,  360,  359,  366,
-      366,  366,  366,  366,  366,  366,  366,  167,  164,  336,
-      337,  337,  337,  337,  337,  337,  337,  337,  337,  361,
-      361,  364,  364,  364,  364,  364,  364,  364,  364,  361,
-      368,  364,  368,  368,  368,  368,  368,  368,  368,  368,
-      337,  345,  163,  345,  345,  345,  345,  345,  345,  345,
-      345,  345,  348,  474,  348,  348,  348,  348,  348,  348,
-
-      348,  348,  348,  474,  162,  161,  348,  348,  348,  348,
-      348,  383,  502,  383,  383,  383,  383,  383,  383,  383,
-      383,  160,  502,  158,  157,  348,  348,  348,  348,  348,
-      348,  351,  351,  351,  351,  351,  351,  351,  351,  351,
-      156,  155,  154,  351,  351,  351,  351,  351,  384,  153,
-      384,  384,  384,  384,  384,  384,  384,  384,  148,  147,
-      141,  140,  351,  351,  351,  351,  351,  351,  362,  362,
-      362,  362,  362,  362,  362,  362,  362,  362,  362,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  136,
-      406,  406,  135,  365,  365,  365,  365,  365,  376,  385,
-
-      406,  385,  385,  385,  385,  385,  385,  385,  385,  465,
-      465,  465,  365,  365,  365,  365,  365,  365,  376,  133,
-      376,  376,  389,  389,  389,  389,  389,  389,  389,  389,
-      395,  395,  395,  395,  395,  395,  395,  395,  465,  376,
-      378,  129,  378,  378,  378,  378,  378,  378,  378,  378,
-      396,  396,  396,  396,  396,  396,  398,  123,  398,  398,
-      398,  398,  398,  398,  398,  398,  119,  117,  110,  109,
-      108,  378,  379,  107,  379,  379,  379,  379,  379,  379,
-      379,  379,  399,  399,  399,  399,  399,  399,  399,  399,
-      401,  106,  401,  401,  401,  401,  401,  401,  401,  401,
-
-      101,  100,   98,  379,  380,   94,  380,  380,  380,  380,
-      380,  380,  380,  380,  402,   90,  402,  402,  402,  402,
-      402,  402,  402,  402,  403,   89,  403,  403,  403,  403,
-      403,  403,  417,   85,   82,  380,  381,   80,  381,  381,
-      381,  381,  381,  381,  381,  381,  445,  445,  445,  445,
-      445,  445,  417,   76,  417,  417,   75,   74,   72,  428,
-       67,  428,  428,  428,   60,   53,   47,  381,  391,   46,
-      391,  391,  391,  391,  391,  391,  391,  391,  391,  394,
-       45,  394,  394,  394,  394,  394,  394,  394,  394,  394,
-      428,   44,   43,  394,  394,  394,  394,  394,  422,  422,
-
-      422,  422,  422,  422,  422,  422,  480,  480,  480,  480,
-      480,  480,  394,  394,  394,  394,  394,  394,  397,  397,
-      397,  397,  397,  397,  397,  397,  397,  422,   42,   36,
-      397,  397,  397,  397,  397,  429,  429,  429,  429,  429,
-      429,  429,  429,  525,  525,  525,  525,  525,  525,  397,
-      397,  397,  397,  397,  397,  409,  409,  409,  409,  409,
-      409,  409,  409,  409,  409,  424,   35,  424,  424,  424,
-      424,  424,  424,  424,  424,  431,   34,  431,  431,  431,
-      431,  431,  431,  431,  431,  432,   32,  432,  432,  432,
-      432,  432,  432,  432,  432,   28,  424,  425,   22,  425,
-
-      425,  425,  425,  425,  425,  425,  425,  433,   19,  433,
-      433,  433,  433,  433,  433,  438,  438,  438,  438,  438,
-      438,  438,  438,   17,   15,   14,   13,    0,  425,  426,
-        0,  426,  426,  426,  426,  426,  426,  426,  426,  444,
-      444,  444,  444,  444,  444,  444,  444,  447,    0,  447,
-      447,  447,  447,  447,  447,  447,  447,    0,    0,    0,
-      426,  427,    0,  427,  427,  427,  427,  427,  427,  427,
-      427,  448,  448,  448,  448,  448,  448,  448,  448,  448,
-      449,  449,  449,  449,  449,  449,  449,  449,  449,    0,
-        0,    0,  427,  440,    0,  440,  440,  440,  440,  440,
-
-      440,  440,  440,  440,  443,    0,  443,  443,  443,  443,
-      443,  443,  443,  443,  443,    0,    0,    0,  443,  443,
-      443,  443,  443,  450,  450,  450,  450,  450,  450,  450,
-      450,  450,    0,    0,    0,    0,    0,  443,  443,  443,
-      443,  443,  443,  446,  446,  446,  446,  446,  446,  446,
-      446,    0,    0,    0,    0,  446,  446,  446,  446,  446,
-      458,    0,  458,    0,  458,    0,  458,  458,    0,    0,
-      458,    0,    0,    0,  446,  446,  446,  446,  446,  446,
-        0,    0,  458,  458,  458,  460,    0,  460,    0,  460,
-        0,  460,  460,    0,    0,  460,  464,  464,  464,  464,
-
-      464,  464,  464,  464,    0,    0,    0,  460,  460,  460,
-      461,    0,  461,  461,  461,  461,  461,  461,  461,  461,
-        0,    0,    0,    0,  466,  464,  466,  466,  466,  466,
-      466,  466,  466,  466,  485,  485,  485,  485,  485,  485,
-      485,  461,  462,    0,  462,  462,  462,  462,  462,  462,
-      462,  462,  467,    0,  467,  467,  467,  467,  467,  467,
-      467,  467,  468,    0,  468,  468,  468,  468,  468,  468,
-      468,  468,    0,  462,  463,    0,  463,  463,  463,  463,
-      463,  463,  463,  463,  473,  473,  473,  473,  473,  473,
-      473,  473,  479,  479,  479,  479,  479,  479,  479,  479,
-
-        0,    0,    0,    0,    0,  463,  475,    0,  475,  475,
-      475,  475,  475,  475,  475,  475,  475,  478,    0,  478,
-      478,  478,  478,  478,  478,  478,  478,    0,    0,    0,
-        0,  478,  478,  478,  478,  478,  481,    0,  481,  481,
-      481,  481,  481,  481,  481,  481,    0,    0,    0,    0,
-      478,  478,  478,  478,  478,  478,  483,  483,  483,  483,
-      483,  483,  483,  483,  483,  484,  484,  484,  484,  484,
-      484,  484,  484,  484,  490,  490,  490,  490,  490,  490,
-      490,  490,    0,  494,    0,  494,  494,  494,  494,  494,
-      494,  495,  495,  495,  495,  495,  495,  495,  495,    0,
-
-        0,    0,    0,  490,  492,    0,  492,  492,  492,  492,
-      492,  492,  492,  492,  494,  497,    0,  497,  497,  497,
-      497,  497,  497,  497,  497,  498,    0,  498,  498,  498,
-      498,  498,  498,  498,  498,  492,  493,    0,  493,  493,
-      493,  493,  493,  493,  493,  493,  499,    0,  499,  499,
-      499,  499,  499,  499,  505,    0,  505,  505,  505,  505,
-      505,  505,  505,  505,    0,    0,    0,  493,  508,    0,
-      508,  508,  508,  508,  508,  508,  508,  508,  511,  511,
-      511,  511,  511,  511,  511,  511,  512,  512,  512,  512,
-      512,  512,  512,  512,    0,    0,    0,    0,    0,  508,
-
-      509,    0,  509,  509,  509,  509,  509,  509,  509,  509,
-      513,  513,  513,  513,  513,  513,  513,  513,  517,  517,
-      517,  517,  517,  517,  517,  517,    0,    0,    0,    0,
-        0,  509,  510,    0,  510,  510,  510,  510,  510,  510,
-      510,  510,    0,    0,    0,    0,  521,  517,  521,  521,
-      521,  521,  521,  521,  523,  523,  523,  523,  523,  523,
-      523,  523,    0,  510,  519,    0,  519,  519,  519,  519,
-      519,  519,  519,  519,    0,    0,    0,  521,  524,  524,
-      524,  524,  524,  524,  524,  524,  527,  527,  527,  527,
-      527,  527,  527,  527,    0,  519,  520,    0,  520,  520,
-
-      520,  520,  520,  520,  520,  520,  528,  528,  528,  528,
-      528,  528,  528,  528,    0,  527,  529,  529,  529,  529,
-      529,  529,  529,  529,    0,    0,    0,  520,  532,  532,
-      532,  532,  532,  532,    0,  528,  531,  531,  531,  531,
-      531,  531,  531,  531,    0,  529,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,  532,    0,    0,
-        0,    0,    0,    0,    0,  531,  534,  534,  534,  534,
-      534,  534,  534,  534,  534,  534,  534,  534,  534,  535,
-      535,  535,  535,  535,  535,  535,  535,  535,  535,  535,
-      535,  535,  536,  536,  536,  536,  536,  536,  536,  536,
-
-      536,  536,  536,  536,  536,  537,  537,  537,  537,  537,
-      537,  537,  537,  537,  537,  537,  537,  537,  538,    0,
-        0,    0,  538,    0,  538,  538,  538,    0,  538,  538,
-      538,  539,  539,  539,  539,  539,  539,  539,  539,  539,
-      539,  539,  539,  539,  540,    0,    0,    0,  540,    0,
-      540,  540,  540,    0,  540,  540,  540,  541,    0,    0,
-        0,  541,    0,  541,  541,  541,    0,  541,  541,  541,
-      542,    0,    0,  542,  542,    0,  542,  542,  542,    0,
-      542,  542,  542,  543,  543,    0,    0,  543,  544,    0,
-        0,  544,  544,    0,  544,  544,  544,    0,  544,  544,
-
-      544,  545,    0,    0,  545,  545,  545,  545,  545,  545,
-        0,    0,  545,  545,  546,  546,  547,    0,    0,  547,
-        0,    0,  547,  547,  547,  547,  547,  547,  547,  548,
-      548,  548,  548,  548,  548,  548,  548,  548,  548,  548,
-      548,  548,  549,  549,    0,  549,    0,  549,  549,  549,
-      549,  549,  549,  549,  549,  550,  550,  550,  550,  550,
-      550,  550,  550,  550,  550,  550,  550,  550,  551,    0,
-        0,  551,  551,    0,  551,  551,  551,    0,  551,  551,
-      551,  552,  552,    0,    0,  552,  553,  553,  553,    0,
-        0,  553,  554,    0,    0,  554,  554,    0,  554,  554,
-
-      554,    0,  554,  554,  554,  555,  555,    0,    0,  555,
-      556,  556,  556,    0,    0,  556,  557,  557,    0,    0,
-      557,  558,  558,    0,    0,  558,  559,  559,    0,    0,
-      559,  560,  560,  560,    0,    0,  560,  561,  561,    0,
-        0,  561,  562,  562,    0,    0,  562,  563,  563,    0,
-        0,  563,  564,  564,  564,    0,    0,  564,  565,  565,
-      565,  565,    0,    0,  565,  566,  566,    0,    0,  566,
-      567,  567,    0,    0,  567,  568,  568,    0,    0,  568,
-      569,  569,  569,    0,    0,  569,  570,  570,  570,  570,
-        0,    0,  570,  571,  571,    0,    0,  571,  572,  572,
-
-        0,    0,  572,  573,  573,  573,    0,    0,  573,  574,
-      574,  574,  574,    0,    0,  574,  575,  575,    0,    0,
-      575,  576,    0,  576,  576,    0,    0,  576,  577,  577,
-      577,    0,    0,  577,  578,  578,  578,  578,    0,    0,
-      578,  579,  579,    0,    0,  579,  580,    0,  580,  580,
-        0,    0,  580,  581,  581,  581,    0,    0,  581,  582,
-      582,  582,    0,    0,    0,  582,  583,    0,    0,    0,
-      583,    0,  583,  583,  583,    0,  583,  583,  583,  584,
-        0,    0,    0,  584,    0,  584,  584,  584,    0,  584,
-      584,  584,  585,  585,    0,    0,  585,  586,    0,  586,
-
-      586,    0,    0,  586,  587,  587,    0,    0,    0,  587,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  589,  589,    0,    0,  589,  590,    0,
-      590,  590,    0,    0,  590,  591,  591,    0,    0,  591,
-      592,    0,  592,    0,    0,    0,  592,  593,    0,    0,
-        0,  593,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533
+        8,    9,    9,    9,    9,    9,  120,  130,  130,   50,
+        9,    9,    9,   50,   50,   57,   57,   57,  120,   57,
+      118,  104,  144,   57,    9,   57,  104,  222,  104,   89,
+      171,   50,  162,   89,   89,  134,  134,   57,   57,  146,
+      146,  162,  222,  171,    9,   10,   10,   10,   10,   10,
+
+       50,   89,  182,  145,   10,   10,   10,   74,   57,   74,
+      181,   74,  181,   74,   74,  144,  182,   74,   10,  177,
+       89,   96,   96,   96,   96,   96,   96,   96,   96,   74,
+       74,   74,   98,   98,   98,   98,   98,   98,   10,   18,
+      184,   18,   18,   18,  145,   18,   18,  545,   86,   18,
+       86,  180,   86,  184,   86,   86,  110,  199,   86,  534,
+      192,   18,   18,   18,  124,  177,  199,  180,  124,  124,
+      259,   86,   86,   97,   97,   97,   97,   97,   97,   97,
+       97,  192,   18,   19,  110,  110,  124,  259,  110,  258,
+      107,  107,  110,   19,  207,  110,   19,   19,   19,   19,
+
+       19,   19,   19,   19,   26,  124,   26,   26,   26,   26,
+       26,   26,   26,   26,   26,  188,  207,  213,   26,   26,
+       26,   26,   26,  213,  260,   92,   92,   92,   92,   92,
+       92,   92,   92,  107,  260,   26,  263,   26,   26,   26,
+       26,   26,   26,   32,  220,  220,  188,   32,  258,   32,
+      360,  360,   32,   32,   92,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,  263,  533,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+
+       32,   32,   32,   32,   32,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,  196,  196,  196,   34,   34,   34,
+       34,   34,  123,  123,  123,  123,  123,  123,  123,  123,
+      254,  299,  531,  141,  141,  254,   34,   34,   34,   34,
+       34,   34,   38,   38,   38,  219,   38,  299,   38,   38,
+      223,   88,   38,   88,  234,   88,  223,   88,   88,  236,
+      236,   88,  520,  234,   38,   38,   38,   42,  137,  236,
+      519,  137,  137,   88,   88,   88,  141,   42,  137,  221,
+       42,   42,   42,   42,   42,   42,   42,   42,   91,  517,
+       91,  137,   91,  343,   91,   91,  516,  219,   91,  126,
+
+      221,  126,  247,  126,  154,  126,  126,  512,  154,  126,
+       91,   91,   91,  345,  154,  238,  238,  221,   42,   58,
+      298,  126,  126,  126,  247,  238,  154,  154,  345,   58,
+      298,  503,   58,   58,   58,   58,   58,   58,   58,   58,
+       77,  343,   77,   77,   77,  289,   77,   77,  501,  292,
+       77,  133,  133,  133,  133,  133,  133,  133,  133,  272,
+      261,  497,   77,   77,   77,  261,  276,  289,  272,  294,
+      153,  292,  153,  293,  153,  276,  153,  153,  294,  388,
+      153,  388,  297,   77,   93,   93,   93,   93,   93,   93,
+       93,   93,  153,  153,  153,  293,   93,   93,   93,   93,
+
+       93,  187,  187,  187,  187,  187,  187,  187,  187,  203,
+      203,  203,  203,  203,  203,   93,   93,   93,   93,   93,
+       93,  101,  101,  101,  101,  101,  101,  101,  101,  297,
+      187,  387,  387,  101,  101,  101,  101,  101,  191,  485,
+      191,  191,  191,  191,  191,  191,  244,  244,  244,  244,
+      244,  244,  101,  101,  101,  101,  101,  101,  155,  300,
+      155,  155,  155,  155,  155,  155,  155,  155,  300,  191,
+      200,  200,  200,  200,  200,  200,  200,  200,  183,  387,
+      484,  355,  183,  406,  406,  420,  420,  474,  183,  155,
+      156,  355,  156,  156,  156,  156,  156,  156,  156,  156,
+
+      183,  183,  195,  195,  195,  195,  195,  195,  195,  195,
+      195,  202,  202,  202,  202,  202,  202,  202,  202,  421,
+      421,  156,  157,  357,  157,  157,  157,  157,  157,  157,
+      157,  157,  205,  357,  205,  205,  205,  205,  205,  205,
+      205,  205,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  340,  472,  157,  158,  318,  158,  158,  158,  158,
+      158,  158,  158,  158,  318,  424,  424,  340,  158,  158,
+      158,  158,  158,  235,  235,  235,  235,  235,  235,  235,
+      235,  286,  286,  286,  286,  286,  286,  158,  158,  158,
+      158,  158,  158,  161,  161,  161,  161,  161,  161,  161,
+
+      161,  161,  456,  456,  470,  161,  161,  161,  161,  161,
+      237,  237,  237,  237,  237,  237,  237,  237,  310,  310,
+      310,  310,  310,  310,  161,  161,  161,  161,  161,  161,
+      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+      467,  467,  471,  163,  163,  163,  163,  163,  241,  241,
+      241,  241,  241,  241,  241,  241,  332,  336,  241,  469,
+      470,  346,  163,  163,  163,  163,  163,  163,  164,  164,
+      164,  164,  164,  164,  164,  164,  338,  346,  332,  336,
+      164,  164,  164,  164,  164,  243,  243,  243,  243,  243,
+      243,  243,  243,  468,  382,  466,  277,  277,  338,  164,
+
+      164,  164,  164,  164,  164,  189,  277,  189,  189,  189,
+      189,  189,  189,  189,  189,  246,  382,  246,  246,  246,
+      246,  246,  246,  246,  246,  262,  262,  262,  262,  262,
+      262,  262,  262,  492,  492,  433,  189,  190,  319,  190,
+      190,  190,  190,  190,  190,  190,  190,  319,  278,  278,
+      433,  437,  505,  505,  262,  280,  280,  266,  278,  266,
+      266,  266,  266,  266,  266,  280,  523,  523,  190,  201,
+      201,  201,  201,  201,  201,  201,  201,  201,  201,  201,
+      320,  320,  437,  201,  201,  201,  201,  201,  266,  273,
+      320,  273,  273,  273,  273,  273,  273,  273,  273,  449,
+
+      448,  444,  201,  201,  201,  201,  201,  201,  204,  204,
+      204,  204,  204,  204,  204,  204,  204,  204,  344,  435,
+      434,  204,  204,  204,  204,  204,  274,  344,  274,  274,
+      274,  274,  274,  274,  274,  274,  429,  321,  321,  413,
+      204,  204,  204,  204,  204,  204,  224,  321,  224,  224,
+      224,  224,  224,  224,  224,  224,  275,  383,  275,  275,
+      275,  275,  275,  275,  275,  275,  279,  279,  279,  279,
+      279,  279,  279,  279,  425,  399,  395,  224,  225,  383,
+      225,  225,  225,  225,  225,  225,  225,  225,  283,  283,
+      283,  283,  283,  283,  283,  283,  425,  400,  283,  285,
+
+      285,  285,  285,  285,  285,  285,  285,  400,  507,  225,
+      226,  401,  226,  226,  226,  226,  226,  226,  226,  226,
+      288,  401,  288,  288,  288,  288,  288,  288,  288,  288,
+      307,  307,  307,  307,  307,  307,  307,  307,  390,  507,
+      386,  226,  239,  239,  239,  239,  239,  239,  239,  239,
+      239,  239,  239,  242,  242,  242,  242,  242,  242,  242,
+      242,  242,  242,  242,  385,  384,  353,  242,  242,  242,
+      242,  242,  309,  309,  309,  309,  309,  309,  309,  309,
+      329,  329,  329,  329,  329,  329,  242,  242,  242,  242,
+      242,  242,  245,  245,  245,  245,  245,  245,  245,  245,
+
+      245,  245,  369,  352,  342,  245,  245,  245,  245,  245,
+      312,  369,  312,  312,  312,  312,  312,  312,  312,  312,
+      341,  323,  323,  335,  245,  245,  245,  245,  245,  245,
+      264,  323,  264,  264,  264,  264,  264,  264,  264,  264,
+      313,  313,  313,  313,  313,  313,  313,  313,  315,  370,
+      315,  315,  315,  315,  315,  315,  315,  315,  370,  334,
+      314,  264,  265,  403,  265,  265,  265,  265,  265,  265,
+      265,  265,  316,  403,  316,  316,  316,  316,  316,  316,
+      316,  316,  317,  417,  317,  317,  317,  317,  317,  317,
+      431,  431,  417,  265,  271,  271,  271,  271,  271,  271,
+
+      271,  271,  271,  431,  306,  305,  271,  271,  271,  271,
+      271,  322,  322,  322,  322,  322,  322,  322,  322,  363,
+      363,  363,  363,  363,  363,  271,  271,  271,  271,  271,
+      271,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  304,  296,  295,  284,  284,  284,  284,
+      284,  326,  326,  326,  326,  326,  326,  326,  326,  427,
+      291,  326,  290,  270,  269,  284,  284,  284,  284,  284,
+      284,  287,  287,  287,  287,  287,  287,  287,  287,  287,
+      287,  427,  268,  267,  287,  287,  287,  287,  287,  328,
+
+      328,  328,  328,  328,  328,  328,  328,  380,  380,  380,
+      380,  380,  380,  287,  287,  287,  287,  287,  287,  301,
+      301,  301,  301,  301,  301,  301,  301,  301,  331,  257,
+      331,  331,  331,  331,  331,  331,  331,  331,  347,  347,
+      347,  347,  347,  347,  347,  347,  524,  524,  536,  301,
+      302,  302,  302,  302,  302,  302,  302,  302,  302,  524,
+      351,  351,  351,  351,  351,  351,  351,  347,  354,  354,
+      354,  354,  354,  354,  354,  354,  256,  255,  253,  536,
+      302,  303,  303,  303,  303,  303,  303,  303,  303,  303,
+      351,  356,  356,  356,  356,  356,  356,  356,  356,  362,
+
+      362,  362,  362,  362,  362,  362,  362,  252,  251,  250,
+      249,  303,  308,  233,  308,  308,  308,  308,  308,  308,
+      308,  308,  308,  418,  232,  231,  308,  308,  308,  308,
+      308,  365,  418,  365,  365,  365,  365,  365,  365,  365,
+      365,  230,  228,  227,  218,  308,  308,  308,  308,  308,
+      308,  311,  311,  311,  311,  311,  311,  311,  311,  311,
+      217,  216,  215,  311,  311,  311,  311,  311,  366,  450,
+      366,  366,  366,  366,  366,  366,  366,  366,  214,  450,
+      212,  211,  311,  311,  311,  311,  311,  311,  324,  324,
+      324,  324,  324,  324,  324,  324,  324,  324,  324,  327,
+
+      327,  327,  327,  327,  327,  327,  327,  327,  327,  327,
+      210,  209,  208,  327,  327,  327,  327,  327,  367,  451,
+      367,  367,  367,  367,  367,  367,  367,  367,  206,  451,
+      198,  197,  327,  327,  327,  327,  327,  327,  330,  330,
+      330,  330,  330,  330,  330,  330,  330,  371,  371,  194,
+      193,  330,  330,  330,  330,  330,  368,  371,  368,  368,
+      368,  368,  368,  368,  368,  368,  186,  185,  179,  176,
+      330,  330,  330,  330,  330,  330,  349,  349,  349,  349,
+      349,  349,  349,  349,  349,  372,  372,  373,  373,  373,
+      373,  373,  373,  373,  373,  372,  379,  379,  379,  379,
+
+      379,  379,  379,  379,  175,  174,  349,  350,  350,  350,
+      350,  350,  350,  350,  350,  350,  374,  374,  377,  377,
+      377,  377,  377,  377,  377,  377,  374,  381,  377,  381,
+      381,  381,  381,  381,  381,  381,  381,  350,  358,  173,
+      358,  358,  358,  358,  358,  358,  358,  358,  358,  361,
+      453,  361,  361,  361,  361,  361,  361,  361,  361,  361,
+      453,  172,  170,  361,  361,  361,  361,  361,  396,  465,
+      396,  396,  396,  396,  396,  396,  396,  396,  465,  169,
+      168,  167,  361,  361,  361,  361,  361,  361,  364,  364,
+      364,  364,  364,  364,  364,  364,  364,  166,  165,  160,
+
+      364,  364,  364,  364,  364,  397,  486,  397,  397,  397,
+      397,  397,  397,  397,  397,  159,  486,  152,  151,  364,
+      364,  364,  364,  364,  364,  375,  375,  375,  375,  375,
+      375,  375,  375,  375,  375,  375,  378,  378,  378,  378,
+      378,  378,  378,  378,  378,  378,  150,  419,  419,  148,
+      378,  378,  378,  378,  378,  389,  398,  419,  398,  398,
+      398,  398,  398,  398,  398,  398,  480,  480,  480,  378,
+      378,  378,  378,  378,  378,  389,  147,  389,  389,  402,
+      402,  402,  402,  402,  402,  402,  402,  408,  408,  408,
+      408,  408,  408,  408,  408,  480,  389,  391,  143,  391,
+
+      391,  391,  391,  391,  391,  391,  391,  409,  409,  409,
+      409,  409,  409,  411,  487,  411,  411,  411,  411,  411,
+      411,  411,  411,  142,  487,  140,  136,  129,  391,  392,
+      125,  392,  392,  392,  392,  392,  392,  392,  392,  412,
+      412,  412,  412,  412,  412,  412,  412,  414,  489,  414,
+      414,  414,  414,  414,  414,  414,  414,  122,  489,  115,
+      392,  393,  518,  393,  393,  393,  393,  393,  393,  393,
+      393,  415,  518,  415,  415,  415,  415,  415,  415,  415,
+      415,  416,  114,  416,  416,  416,  416,  416,  416,  430,
+      113,  112,  393,  394,  111,  394,  394,  394,  394,  394,
+
+      394,  394,  394,  459,  459,  459,  459,  459,  459,  430,
+      106,  430,  430,  105,  103,   99,  442,   95,  442,  442,
+      442,   94,   90,   87,  394,  404,   85,  404,  404,  404,
+      404,  404,  404,  404,  404,  404,  407,   80,  407,  407,
+      407,  407,  407,  407,  407,  407,  407,  442,   79,   78,
+      407,  407,  407,  407,  407,  436,  436,  436,  436,  436,
+      436,  436,  436,  495,  495,  495,  495,  495,  495,  407,
+      407,  407,  407,  407,  407,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  436,   76,   75,  410,  410,  410,
+      410,  410,  443,  443,  443,  443,  443,  443,  443,  443,
+
+      543,  543,  543,  543,  543,  543,  410,  410,  410,  410,
+      410,  410,  422,  422,  422,  422,  422,  422,  422,  422,
+      422,  422,  438,   73,  438,  438,  438,  438,  438,  438,
+      438,  438,  445,   68,  445,  445,  445,  445,  445,  445,
+      445,  445,  446,   61,  446,  446,  446,  446,  446,  446,
+      446,  446,   54,  438,  439,   48,  439,  439,  439,  439,
+      439,  439,  439,  439,  447,   47,  447,  447,  447,  447,
+      447,  447,  452,  452,  452,  452,  452,  452,  452,  452,
+       46,   45,   44,   43,   37,  439,  440,   36,  440,  440,
+      440,  440,  440,  440,  440,  440,  458,  458,  458,  458,
+
+      458,  458,  458,  458,  461,   35,  461,  461,  461,  461,
+      461,  461,  461,  461,   33,   29,   23,  440,  441,   17,
+      441,  441,  441,  441,  441,  441,  441,  441,  462,  462,
+      462,  462,  462,  462,  462,  462,  462,  463,  463,  463,
+      463,  463,  463,  463,  463,  463,   15,   14,   13,  441,
+      454,    0,  454,  454,  454,  454,  454,  454,  454,  454,
+      454,  457,    0,  457,  457,  457,  457,  457,  457,  457,
+      457,  457,    0,    0,    0,  457,  457,  457,  457,  457,
+      464,  464,  464,  464,  464,  464,  464,  464,  464,    0,
+        0,    0,    0,    0,  457,  457,  457,  457,  457,  457,
+
+      460,  460,  460,  460,  460,  460,  460,  460,    0,    0,
+        0,    0,  460,  460,  460,  460,  460,  473,    0,  473,
+        0,  473,    0,  473,  473,    0,    0,  473,    0,    0,
+        0,  460,  460,  460,  460,  460,  460,    0,    0,  473,
+      473,  473,  475,    0,  475,    0,  475,    0,  475,  475,
+        0,    0,  475,  479,  479,  479,  479,  479,  479,  479,
+      479,    0,    0,    0,  475,  475,  475,  476,    0,  476,
+      476,  476,  476,  476,  476,  476,  476,    0,    0,    0,
+        0,  481,  479,  481,  481,  481,  481,  481,  481,  481,
+      481,  500,  500,  500,  500,  500,  500,  500,  476,  477,
+
+        0,  477,  477,  477,  477,  477,  477,  477,  477,  482,
+        0,  482,  482,  482,  482,  482,  482,  482,  482,  483,
+        0,  483,  483,  483,  483,  483,  483,  483,  483,    0,
+      477,  478,    0,  478,  478,  478,  478,  478,  478,  478,
+      478,  488,  488,  488,  488,  488,  488,  488,  488,  494,
+      494,  494,  494,  494,  494,  494,  494,    0,    0,    0,
+        0,    0,  478,  490,    0,  490,  490,  490,  490,  490,
+      490,  490,  490,  490,  493,    0,  493,  493,  493,  493,
+      493,  493,  493,  493,    0,    0,    0,    0,  493,  493,
+      493,  493,  493,  496,    0,  496,  496,  496,  496,  496,
+
+      496,  496,  496,    0,    0,    0,    0,  493,  493,  493,
+      493,  493,  493,  498,  498,  498,  498,  498,  498,  498,
+      498,  498,  499,  499,  499,  499,  499,  499,  499,  499,
+      499,  506,  506,  506,  506,  506,  506,  506,  506,    0,
+      510,    0,  510,  510,  510,  510,  510,  510,  511,  511,
+      511,  511,  511,  511,  511,  511,    0,    0,    0,    0,
+      506,  508,    0,  508,  508,  508,  508,  508,  508,  508,
+      508,  510,  513,    0,  513,  513,  513,  513,  513,  513,
+      513,  513,  514,    0,  514,  514,  514,  514,  514,  514,
+      514,  514,  508,  509,    0,  509,  509,  509,  509,  509,
+
+      509,  509,  509,  515,    0,  515,  515,  515,  515,  515,
+      515,  521,    0,  521,  521,  521,  521,  521,  521,  521,
+      521,    0,    0,    0,  509,  525,    0,  525,  525,  525,
+      525,  525,  525,  525,  525,  528,  528,  528,  528,  528,
+      528,  528,  528,  529,  529,  529,  529,  529,  529,  529,
+      529,    0,    0,    0,    0,    0,  525,  526,    0,  526,
+      526,  526,  526,  526,  526,  526,  526,  530,  530,  530,
+      530,  530,  530,  530,  530,  535,  535,  535,  535,  535,
+      535,  535,  535,    0,    0,    0,    0,    0,  526,  527,
+        0,  527,  527,  527,  527,  527,  527,  527,  527,    0,
+
+        0,    0,    0,  539,  535,  539,  539,  539,  539,  539,
+      539,  541,  541,  541,  541,  541,  541,  541,  541,    0,
+      527,  537,    0,  537,  537,  537,  537,  537,  537,  537,
+      537,    0,    0,    0,  539,  542,  542,  542,  542,  542,
+      542,  542,  542,  547,  547,  547,  547,  547,  547,  547,
+      547,    0,  537,  538,    0,  538,  538,  538,  538,  538,
+      538,  538,  538,  548,  548,  548,  548,  548,  548,  548,
+      548,    0,  547,  549,  549,  549,  549,  549,  549,  549,
+      549,    0,    0,    0,  538,  552,  552,  552,  552,  552,
+      552,    0,  548,  551,  551,  551,  551,  551,  551,  551,
+
+      551,    0,  549,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  552,    0,    0,    0,    0,    0,
+        0,    0,  551,  554,  554,  554,  554,  554,  554,  554,
+      554,  554,  554,  554,  554,  554,  555,  555,  555,  555,
+      555,  555,  555,  555,  555,  555,  555,  555,  555,  556,
+      556,  556,  556,  556,  556,  556,  556,  556,  556,  556,
+      556,  556,  557,  557,  557,  557,  557,  557,  557,  557,
+      557,  557,  557,  557,  557,  558,    0,    0,    0,  558,
+        0,  558,  558,  558,    0,  558,  558,  558,  559,  559,
+        0,  559,  559,  559,  559,  559,  559,  559,  559,  559,
+
+      559,  560,  560,  560,  560,  560,  560,  560,  560,  560,
+      560,  560,  560,  560,  561,    0,    0,    0,  561,    0,
+      561,  561,  561,  561,  561,  561,  561,  562,    0,    0,
+        0,  562,    0,  562,  562,  562,    0,  562,  562,  562,
+      563,    0,    0,  563,  563,    0,  563,  563,  563,    0,
+      563,  563,  563,  564,  564,    0,    0,  564,  565,    0,
+        0,  565,  565,    0,  565,  565,  565,    0,  565,  565,
+      565,  566,    0,    0,  566,  566,  566,  566,  566,  566,
+        0,    0,  566,  566,  567,  567,  568,    0,    0,  568,
+        0,    0,  568,  568,  568,  568,  568,  568,  568,  569,
+
+      569,  569,  569,  569,  569,  569,  569,  569,  569,  569,
+      569,  569,  570,  570,    0,  570,    0,  570,  570,  570,
+      570,  570,  570,  570,  570,  571,  571,    0,  571,  571,
+      571,  571,  571,  571,  571,  571,  571,  571,  572,  572,
+      572,  572,  572,  572,  572,  572,  572,  572,  572,  572,
+      572,  573,  573,    0,  573,  573,  573,  573,  573,  573,
+      573,  573,  573,  573,  574,    0,    0,    0,  574,    0,
+      574,  574,  574,    0,  574,  574,  574,  575,    0,    0,
+      575,  575,    0,  575,  575,  575,    0,  575,  575,  575,
+      576,  576,    0,    0,  576,  577,  577,  577,    0,    0,
+
+      577,  578,    0,    0,  578,  578,    0,  578,  578,  578,
+        0,  578,  578,  578,  579,  579,  579,  579,  579,  579,
+      579,  579,  579,  579,  579,  579,  579,  580,  580,    0,
+        0,  580,  581,  581,  581,    0,    0,  581,  582,  582,
+        0,    0,  582,  583,  583,    0,    0,  583,  584,  584,
+        0,    0,  584,  585,  585,  585,    0,    0,  585,  586,
+      586,    0,    0,  586,  587,  587,    0,    0,  587,  588,
+      588,    0,    0,  588,  589,  589,  589,    0,    0,  589,
+      590,  590,  590,  590,    0,    0,  590,  591,  591,    0,
+        0,  591,  592,  592,    0,    0,  592,  593,  593,    0,
+
+        0,  593,  594,  594,  594,    0,    0,  594,  595,  595,
+      595,  595,    0,    0,  595,  596,  596,    0,    0,  596,
+      597,  597,    0,    0,  597,  598,  598,  598,    0,    0,
+      598,  599,  599,  599,  599,    0,    0,  599,  600,  600,
+        0,    0,  600,  601,    0,  601,  601,    0,    0,  601,
+      602,  602,  602,    0,    0,  602,  603,  603,  603,  603,
+        0,    0,  603,  604,  604,    0,    0,  604,  605,    0,
+      605,  605,    0,    0,  605,  606,  606,  606,    0,    0,
+      606,  607,  607,  607,    0,    0,    0,  607,  608,    0,
+        0,    0,  608,    0,  608,  608,  608,    0,  608,  608,
+
+      608,  609,    0,    0,    0,  609,    0,  609,  609,  609,
+        0,  609,  609,  609,  610,  610,    0,    0,  610,  611,
+        0,  611,  611,    0,    0,  611,  612,  612,    0,    0,
+        0,  612,  613,  613,  613,  613,  613,  613,  613,  613,
+      613,  613,  613,  613,  613,  614,  614,    0,    0,  614,
+      615,    0,  615,  615,    0,    0,  615,  616,  616,    0,
+        0,  616,  617,    0,  617,    0,    0,    0,  617,  618,
+        0,    0,    0,  618,  619,  619,  619,  619,  619,  619,
+      619,  619,  619,  619,  619,  619,  619,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553,
+      553,  553,  553,  553,  553,  553,  553,  553,  553,  553
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -1311,7 +1345,7 @@ char *yytext;
 #define INITIAL 0
 #line 2 "toke.l"
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -1338,6 +1372,7 @@ char *yytext;
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #ifdef STDC_HEADERS
 # include <stdlib.h>
@@ -1360,13 +1395,29 @@ char *yytext;
 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
 # include <malloc.h>
 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
 #include <ctype.h>
 #include "sudo.h"
 #include "parse.h"
 #include <gram.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: toke.c,v 1.27 2008/11/24 00:42:20 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: toke.c,v 1.36 2009/05/27 00:47:17 millert Exp $";
 #endif /* lint */
 
 extern YYSTYPE yylval;
@@ -1380,15 +1431,16 @@ static int append               __P((char *, int));
 static int _fill               __P((char *, int, int));
 static int fill_cmnd           __P((char *, int));
 static int fill_args           __P((char *, int, int));
-static int switch_buffer       __P((char *));
+static int _push_include       __P((char *, int));
+static int pop_include         __P((void));
 static int ipv6_valid          __P((const char *s));
 static char *parse_include     __P((char *));
 extern void yyerror            __P((const char *));
 
 #define fill(a, b)             _fill(a, b, 0)
 
-#define        push_include(_p)        (switch_buffer((_p)))
-#define        pop_include()           (switch_buffer(NULL))
+#define        push_include(_p)        (_push_include((_p), FALSE))
+#define        push_includedir(_p)     (_push_include((_p), TRUE))
 
 /* realloc() to size + COMMANDARGINC to make room for command args */
 #define COMMANDARGINC  64
@@ -1409,7 +1461,7 @@ extern void yyerror               __P((const char *));
 
 #define INSTR 5
 
-#line 1413 "lex.yy.c"
+#line 1465 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1563,9 +1615,9 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
-#line 113 "toke.l"
+#line 131 "toke.l"
 
-#line 1569 "lex.yy.c"
+#line 1621 "lex.yy.c"
 
        if ( yy_init )
                {
@@ -1617,13 +1669,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 534 )
+                               if ( yy_current_state >= 554 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 3353 );
+               while ( yy_base[yy_current_state] != 3488 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -1651,12 +1703,12 @@ do_action:      /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 114 "toke.l"
+#line 132 "toke.l"
 BEGIN STARTDEFS;
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 116 "toke.l"
+#line 134 "toke.l"
 {
                            BEGIN INDEFS;
                            LEXTRACE("DEFVAR ");
@@ -1668,7 +1720,7 @@ YY_RULE_SETUP
 
 case 3:
 YY_RULE_SETUP
-#line 125 "toke.l"
+#line 143 "toke.l"
 {
                            BEGIN STARTDEFS;
                            LEXTRACE(", ");
@@ -1677,7 +1729,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 131 "toke.l"
+#line 149 "toke.l"
 {
                            LEXTRACE("= ");
                            return('=');
@@ -1685,7 +1737,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 136 "toke.l"
+#line 154 "toke.l"
 {
                            LEXTRACE("+= ");
                            return('+');
@@ -1693,7 +1745,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 141 "toke.l"
+#line 159 "toke.l"
 {
                            LEXTRACE("-= ");
                            return('-');
@@ -1701,7 +1753,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 146 "toke.l"
+#line 164 "toke.l"
 {
                            LEXTRACE("BEGINSTR ");
                            yylval.string = NULL;
@@ -1710,7 +1762,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 152 "toke.l"
+#line 170 "toke.l"
 {
                            LEXTRACE("WORD(2) ");
                            if (!fill(yytext, yyleng))
@@ -1722,7 +1774,7 @@ YY_RULE_SETUP
 
 case 9:
 YY_RULE_SETUP
-#line 161 "toke.l"
+#line 179 "toke.l"
 {
                            /* Line continuation char followed by newline. */
                            ++sudolineno;
@@ -1731,7 +1783,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 167 "toke.l"
+#line 185 "toke.l"
 {
                            LEXTRACE("ENDSTR ");
                            BEGIN INDEFS;
@@ -1740,7 +1792,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 173 "toke.l"
+#line 191 "toke.l"
 {
                            LEXTRACE("BACKSLASH ");
                            if (!append(yytext, yyleng))
@@ -1749,7 +1801,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 179 "toke.l"
+#line 197 "toke.l"
 {
                            LEXTRACE("STRBODY ");
                            if (!append(yytext, yyleng))
@@ -1760,7 +1812,7 @@ YY_RULE_SETUP
 
 case 13:
 YY_RULE_SETUP
-#line 187 "toke.l"
+#line 205 "toke.l"
 {
                            /* quoted fnmatch glob char, pass verbatim */
                            LEXTRACE("QUOTEDCHAR ");
@@ -1771,7 +1823,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 195 "toke.l"
+#line 213 "toke.l"
 {
                            /* quoted sudoers special char, strip backslash */
                            LEXTRACE("QUOTEDCHAR ");
@@ -1782,7 +1834,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 203 "toke.l"
+#line 221 "toke.l"
 {
                            BEGIN INITIAL;
                            yyless(0);
@@ -1791,7 +1843,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 209 "toke.l"
+#line 227 "toke.l"
 {
                            LEXTRACE("ARG ");
                            if (!fill_args(yytext, yyleng, sawspace))
@@ -1802,7 +1854,7 @@ YY_RULE_SETUP
 
 case 17:
 YY_RULE_SETUP
-#line 217 "toke.l"
+#line 235 "toke.l"
 {
                            char *path;
 
@@ -1818,7 +1870,23 @@ YY_RULE_SETUP
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 230 "toke.l"
+#line 248 "toke.l"
+{
+                           char *path;
+
+                           if ((path = parse_include(yytext)) == NULL)
+                               yyterminate();
+
+                           LEXTRACE("INCLUDEDIR\n");
+
+                           /* Push current buffer and switch to include file */
+                           if (!push_includedir(path))
+                               yyterminate();
+                       }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 261 "toke.l"
 {
                            int n;
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -1848,9 +1916,9 @@ YY_RULE_SETUP
                            }
                        }
        YY_BREAK
-case 19:
+case 20:
 YY_RULE_SETUP
-#line 259 "toke.l"
+#line 290 "toke.l"
 {
                            int n;
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -1871,59 +1939,59 @@ YY_RULE_SETUP
                            }
                        }
        YY_BREAK
-case 20:
+case 21:
 YY_RULE_SETUP
-#line 279 "toke.l"
+#line 310 "toke.l"
 {
                                /* cmnd does not require passwd for this user */
                                LEXTRACE("NOPASSWD ");
                                return(NOPASSWD);
                        }
        YY_BREAK
-case 21:
+case 22:
 YY_RULE_SETUP
-#line 285 "toke.l"
+#line 316 "toke.l"
 {
                                /* cmnd requires passwd for this user */
                                LEXTRACE("PASSWD ");
                                return(PASSWD);
                        }
        YY_BREAK
-case 22:
+case 23:
 YY_RULE_SETUP
-#line 291 "toke.l"
+#line 322 "toke.l"
 {
                                LEXTRACE("NOEXEC ");
                                return(NOEXEC);
                        }
        YY_BREAK
-case 23:
+case 24:
 YY_RULE_SETUP
-#line 296 "toke.l"
+#line 327 "toke.l"
 {
                                LEXTRACE("EXEC ");
                                return(EXEC);
                        }
        YY_BREAK
-case 24:
+case 25:
 YY_RULE_SETUP
-#line 301 "toke.l"
+#line 332 "toke.l"
 {
                                LEXTRACE("SETENV ");
                                return(SETENV);
                        }
        YY_BREAK
-case 25:
+case 26:
 YY_RULE_SETUP
-#line 306 "toke.l"
+#line 337 "toke.l"
 {
                                LEXTRACE("NOSETENV ");
                                return(NOSETENV);
                        }
        YY_BREAK
-case 26:
+case 27:
 YY_RULE_SETUP
-#line 311 "toke.l"
+#line 342 "toke.l"
 {
                            /* netgroup */
                            if (!fill(yytext, yyleng))
@@ -1932,9 +2000,9 @@ YY_RULE_SETUP
                            return(NETGROUP);
                        }
        YY_BREAK
-case 27:
+case 28:
 YY_RULE_SETUP
-#line 319 "toke.l"
+#line 350 "toke.l"
 {
                            /* UN*X group */
                            if (!fill(yytext, yyleng))
@@ -1943,9 +2011,9 @@ YY_RULE_SETUP
                            return(USERGROUP);
                        }
        YY_BREAK
-case 28:
+case 29:
 YY_RULE_SETUP
-#line 327 "toke.l"
+#line 358 "toke.l"
 {
                            if (!fill(yytext, yyleng))
                                yyterminate();
@@ -1953,9 +2021,9 @@ YY_RULE_SETUP
                            return(NTWKADDR);
                        }
        YY_BREAK
-case 29:
+case 30:
 YY_RULE_SETUP
-#line 334 "toke.l"
+#line 365 "toke.l"
 {
                            if (!fill(yytext, yyleng))
                                yyterminate();
@@ -1963,9 +2031,9 @@ YY_RULE_SETUP
                            return(NTWKADDR);
                        }
        YY_BREAK
-case 30:
+case 31:
 YY_RULE_SETUP
-#line 341 "toke.l"
+#line 372 "toke.l"
 {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
@@ -1977,9 +2045,9 @@ YY_RULE_SETUP
                            return(NTWKADDR);
                        }
        YY_BREAK
-case 31:
+case 32:
 YY_RULE_SETUP
-#line 352 "toke.l"
+#line 383 "toke.l"
 {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
@@ -1991,9 +2059,9 @@ YY_RULE_SETUP
                            return(NTWKADDR);
                        }
        YY_BREAK
-case 32:
+case 33:
 YY_RULE_SETUP
-#line 363 "toke.l"
+#line 394 "toke.l"
 {
                            if (strcmp(yytext, "ALL") == 0) {
                                LEXTRACE("ALL ");
@@ -2016,9 +2084,9 @@ YY_RULE_SETUP
                            return(ALIAS);
                        }
        YY_BREAK
-case 33:
+case 34:
 YY_RULE_SETUP
-#line 385 "toke.l"
+#line 416 "toke.l"
 {
                            /* no command args allowed for Defaults!/path */
                            if (!fill_cmnd(yytext, yyleng))
@@ -2027,9 +2095,9 @@ YY_RULE_SETUP
                            return(COMMAND);
                        }
        YY_BREAK
-case 34:
+case 35:
 YY_RULE_SETUP
-#line 393 "toke.l"
+#line 424 "toke.l"
 {
                            BEGIN GOTCMND;
                            LEXTRACE("COMMAND ");
@@ -2037,9 +2105,9 @@ YY_RULE_SETUP
                                yyterminate();
                        }                       /* sudo -e */
        YY_BREAK
-case 35:
+case 36:
 YY_RULE_SETUP
-#line 400 "toke.l"
+#line 431 "toke.l"
 {
                            /* directories can't have args... */
                            if (yytext[yyleng - 1] == '/') {
@@ -2055,68 +2123,88 @@ YY_RULE_SETUP
                            }
                        }                       /* a pathname */
        YY_BREAK
-case 36:
+case 37:
+YY_RULE_SETUP
+#line 446 "toke.l"
+{
+                           /* a quoted user/group name */
+                           if (!fill(yytext + 1, yyleng - 2))
+                               yyterminate();
+                           switch (yytext[1]) {
+                           case '%':
+                               LEXTRACE("USERGROUP ");
+                               return(USERGROUP);
+                           case '+':
+                               LEXTRACE("NETGROUP ");
+                               return(NETGROUP);
+                           default:
+                               LEXTRACE("WORD(4) ");
+                               return(WORD);
+                           }
+                       }
+       YY_BREAK
+case 38:
 YY_RULE_SETUP
-#line 415 "toke.l"
+#line 463 "toke.l"
 {
                            /* a word */
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           LEXTRACE("WORD(4) ");
+                           LEXTRACE("WORD(5) ");
                            return(WORD);
                        }
        YY_BREAK
-case 37:
+case 39:
 YY_RULE_SETUP
-#line 423 "toke.l"
+#line 471 "toke.l"
 {
                            LEXTRACE("( ");
                            return ('(');
                        }
        YY_BREAK
-case 38:
+case 40:
 YY_RULE_SETUP
-#line 428 "toke.l"
+#line 476 "toke.l"
 {
                            LEXTRACE(") ");
                            return(')');
                        }
        YY_BREAK
-case 39:
+case 41:
 YY_RULE_SETUP
-#line 433 "toke.l"
+#line 481 "toke.l"
 {
                            LEXTRACE(", ");
                            return(',');
                        }                       /* return ',' */
        YY_BREAK
-case 40:
+case 42:
 YY_RULE_SETUP
-#line 438 "toke.l"
+#line 486 "toke.l"
 {
                            LEXTRACE("= ");
                            return('=');
                        }                       /* return '=' */
        YY_BREAK
-case 41:
+case 43:
 YY_RULE_SETUP
-#line 443 "toke.l"
+#line 491 "toke.l"
 {
                            LEXTRACE(": ");
                            return(':');
                        }                       /* return ':' */
        YY_BREAK
-case 42:
+case 44:
 YY_RULE_SETUP
-#line 448 "toke.l"
+#line 496 "toke.l"
 {
                            if (yyleng % 2 == 1)
                                return('!');    /* return '!' */
                        }
        YY_BREAK
-case 43:
+case 45:
 YY_RULE_SETUP
-#line 453 "toke.l"
+#line 501 "toke.l"
 {
                            BEGIN INITIAL;
                            ++sudolineno;
@@ -2124,35 +2212,35 @@ YY_RULE_SETUP
                            return(COMMENT);
                        }                       /* return newline */
        YY_BREAK
-case 44:
+case 46:
 YY_RULE_SETUP
-#line 460 "toke.l"
+#line 508 "toke.l"
 {                      /* throw away space/tabs */
                            sawspace = TRUE;    /* but remember for fill_args */
                        }
        YY_BREAK
-case 45:
+case 47:
 YY_RULE_SETUP
-#line 464 "toke.l"
+#line 512 "toke.l"
 {
                            sawspace = TRUE;    /* remember for fill_args */
                            ++sudolineno;
                            LEXTRACE("\n\t");
                        }                       /* throw away EOL after \ */
        YY_BREAK
-case 46:
+case 48:
 YY_RULE_SETUP
-#line 470 "toke.l"
+#line 518 "toke.l"
 {
                            BEGIN INITIAL;
                            ++sudolineno;
                            LEXTRACE("\n");
                            return(COMMENT);
-                       }                       /* return comments */
+                       }                       /* comment, not uid/gid */
        YY_BREAK
-case 47:
+case 49:
 YY_RULE_SETUP
-#line 477 "toke.l"
+#line 525 "toke.l"
 {
                            LEXTRACE("ERROR ");
                            return(ERROR);
@@ -2164,7 +2252,7 @@ case YY_STATE_EOF(GOTCMND):
 case YY_STATE_EOF(STARTDEFS):
 case YY_STATE_EOF(INDEFS):
 case YY_STATE_EOF(INSTR):
-#line 482 "toke.l"
+#line 530 "toke.l"
 {
                            if (YY_START != INITIAL) {
                                BEGIN INITIAL;
@@ -2175,12 +2263,12 @@ case YY_STATE_EOF(INSTR):
                                yyterminate();
                        }
        YY_BREAK
-case 48:
+case 50:
 YY_RULE_SETUP
-#line 492 "toke.l"
+#line 540 "toke.l"
 ECHO;
        YY_BREAK
-#line 2184 "lex.yy.c"
+#line 2272 "lex.yy.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -2471,7 +2559,7 @@ static yy_state_type yy_get_previous_state()
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 534 )
+                       if ( yy_current_state >= 554 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2506,11 +2594,11 @@ yy_state_type yy_current_state;
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 534 )
+               if ( yy_current_state >= 554 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 533);
+       yy_is_jam = (yy_current_state == 553);
 
        return yy_is_jam ? 0 : yy_current_state;
        }
@@ -3069,14 +3157,59 @@ int main()
        return 0;
        }
 #endif
-#line 492 "toke.l"
+#line 540 "toke.l"
+
+static unsigned char
+hexchar(s)
+    const char *s;
+{
+    int i;
+    int result = 0;
+
+    s += 2; /* skip \\x */
+    for (i = 0; i < 2; i++) {
+       switch (*s) {
+       case 'A':
+       case 'a':
+           result += 10;
+           break;
+       case 'B':
+       case 'b':
+           result += 11;
+           break;
+       case 'C':
+       case 'c':
+           result += 12;
+           break;
+       case 'D':
+       case 'd':
+           result += 13;
+           break;
+       case 'E':
+       case 'e':
+           result += 14;
+           break;
+       case 'F':
+       case 'f':
+           result += 15;
+           break;
+       default:
+           result += *s - '0';
+           break;
+       }
+       if (i == 0) {
+           result *= 16;
+           s++;
+       }
+    }
+    return((unsigned char)result);
+}
 
 static int
 _fill(src, len, olen)
     char *src;
     int len, olen;
 {
-    int i, j;
     char *dst;
 
     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
@@ -3088,13 +3221,24 @@ _fill(src, len, olen)
 
     /* Copy the string and collapse any escaped characters. */
     dst += olen;
-    for (i = 0, j = 0; i < len; i++, j++) {
-       if (src[i] == '\\' && i != len - 1)
-           dst[j] = src[++i];
-       else
-           dst[j] = src[i];
+    while (len--) {
+       if (*src == '\\' && len) {
+           if (src[1] == 'x' && len >= 3 && 
+               isxdigit((unsigned char) src[2]) &&
+               isxdigit((unsigned char) src[3])) {
+               *dst++ = hexchar(src);
+               src += 4;
+               len -= 3;
+           } else {
+               src++;
+               len--;
+               *dst++ = *src++;
+           }
+       } else {
+           *dst++ = *src++;
+       }
     }
-    dst[j] = '\0';
+    *dst = '\0';
     return(TRUE);
 }
 
@@ -3186,63 +3330,228 @@ fill_args(s, len, addspace)
     return(TRUE);
 }
 
-struct sudoers_state {
+struct path_list {
+    char *path;
+    struct path_list *next;
+};
+
+struct include_stack {
     YY_BUFFER_STATE bs;
     char *path;
+    struct path_list *more; /* more files in case of includedir */
     int lineno;
+    int keepopen;
 };
 
+static int
+pl_compare(v1, v2)
+    const void *v1;
+    const void *v2;
+{
+    const struct path_list * const *p1 = v1;
+    const struct path_list * const *p2 = v2;
+
+    return(strcmp((*p1)->path, (*p2)->path));
+}
+
+static char *
+switch_dir(stack, dirpath)
+    struct include_stack *stack;
+    char *dirpath;
+{
+    DIR *dir;
+    int i, count = 0;
+    char *path = NULL;
+    struct dirent *dent;
+    struct stat sb;
+    struct path_list *pl, *first = NULL;
+    struct path_list **sorted = NULL;
+
+    if (!(dir = opendir(dirpath))) {
+       yyerror(dirpath);
+       return(FALSE);
+    }
+    while ((dent = readdir(dir))) {
+       /* Ignore files that end in '~' or have a '.' in them. */
+       if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
+           || strchr(dent->d_name, '.') != NULL) {
+           continue;
+       }
+       if (asprintf(&path, "%s/%s", dirpath, dent->d_name) == -1) {
+           closedir(dir);
+           goto bad;
+       }
+       if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
+           efree(path);
+           continue;
+       }
+       pl = malloc(sizeof(*pl));
+       if (pl == NULL)
+           goto bad;
+       pl->path = path;
+       pl->next = first;
+       first = pl;
+       count++;
+    }
+    closedir(dir);
+
+    if (count == 0)
+       goto done;
+
+    /* Sort the list as an array. */
+    sorted = malloc(sizeof(*sorted) * count);
+    if (sorted == NULL)
+       goto bad;
+    pl = first;
+    for (i = 0; i < count; i++) {
+       sorted[i] = pl;
+       pl = pl->next;
+    }
+    qsort(sorted, count, sizeof(*sorted), pl_compare);
+
+    /* Apply sorting to the list. */
+    first = sorted[0];
+    sorted[count - 1]->next = NULL;
+    for (i = 1; i < count; i++)
+       sorted[i - 1]->next = sorted[i];
+    efree(sorted);
+
+    /* Pull out the first element for parsing, leave the rest for later. */
+    if (count) {
+       path = first->path;
+       pl = first->next;
+       efree(first);
+       stack->more = pl;
+    } else {
+       path = NULL;
+    }
+done:
+    efree(dirpath);
+    return(path);
+bad:
+    while (first != NULL) {
+       pl = first;
+       first = pl->next;
+       free(pl->path);
+       free(pl);
+    }
+    efree(sorted);
+    efree(dirpath);
+    efree(path);
+    return(NULL);
+}
+
 #define MAX_SUDOERS_DEPTH      128
 #define SUDOERS_STACK_INCREMENT        16
 
+static size_t istacksize, idepth;
+static struct include_stack *istack;
+static int keepopen;
+
+void
+init_lexer()
+{
+    struct path_list *pl;
+
+    while (idepth) {
+       idepth--;
+       while ((pl = istack[idepth].more) != NULL) {
+           istack[idepth].more = pl->next;
+           efree(pl->path);
+           efree(pl);
+       }
+       efree(istack[idepth].path);
+       if (!istack[idepth].keepopen)
+           fclose(istack[idepth].bs->yy_input_file);
+       yy_delete_buffer(istack[idepth].bs);
+    }
+    efree(istack);
+    istack = NULL;
+    istacksize = idepth = 0;
+    keepopen = FALSE;
+}
+
 static int
-switch_buffer(path)
+_push_include(path, isdir)
     char *path;
+    int isdir;
 {
-    static size_t stacksize, depth;
-    static struct sudoers_state *state;
-    static int keepopen;
     FILE *fp;
 
-    if (path != NULL) {
-       /* push current state */
-       if (depth >= stacksize) {
-           if (depth > MAX_SUDOERS_DEPTH) {
-               yyerror("too many levels of includes");
-               return(FALSE);
-           }
-           stacksize += SUDOERS_STACK_INCREMENT;
-           state = (struct sudoers_state *) realloc(state,
-               sizeof(state) * stacksize);
-           if (state == NULL) {
-               yyerror("unable to allocate memory");
-               return(FALSE);
-           }
+    /* push current state onto stack */
+    if (idepth >= istacksize) {
+       if (idepth > MAX_SUDOERS_DEPTH) {
+           yyerror("too many levels of includes");
+           return(FALSE);
+       }
+       istacksize += SUDOERS_STACK_INCREMENT;
+       istack = (struct include_stack *) realloc(istack,
+           sizeof(istack) * istacksize);
+       if (istack == NULL) {
+           yyerror("unable to allocate memory");
+           return(FALSE);
+       }
+    }
+    if (isdir) {
+       if (!(path = switch_dir(&istack[idepth], path))) {
+           yyerror(path);
+           return(FALSE);
+       }
+       if ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {
+           yyerror(path);
+           return(FALSE); /* XXX - just to go next one? */
        }
-       if ((fp = open_sudoers(path, &keepopen)) == NULL) {
+    } else {
+       if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {
            yyerror(path);
            return(FALSE);
        }
-       state[depth].bs = YY_CURRENT_BUFFER;
-       state[depth].path = sudoers;
-       state[depth].lineno = sudolineno;
-       depth++;
+       istack[idepth].more = NULL;
+    }
+    /* Push the old (current) file and open the new one. */
+    istack[idepth].path = sudoers; /* push old path */
+    istack[idepth].bs = YY_CURRENT_BUFFER;
+    istack[idepth].lineno = sudolineno;
+    istack[idepth].keepopen = keepopen;
+    idepth++;
+    sudolineno = 1;
+    sudoers = path;
+    yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+
+    return(TRUE);
+}
+
+static int
+pop_include()
+{
+    struct path_list *pl;
+    FILE *fp;
+
+    if (idepth == 0)
+       return(FALSE);
+
+    if (!keepopen)
+       fclose(YY_CURRENT_BUFFER->yy_input_file);
+    yy_delete_buffer(YY_CURRENT_BUFFER);
+    keepopen = FALSE;
+    if ((pl = istack[idepth - 1].more) != NULL) {
+       /* Move to next file in the dir. */
+       istack[idepth - 1].more = pl->next;
+       if ((fp = open_sudoers(pl->path, FALSE, &keepopen)) == NULL) {
+           yyerror(pl->path);
+           return(FALSE); /* XXX - just to go next one? */
+       }
+       efree(sudoers);
+       sudoers = pl->path;
        sudolineno = 1;
-       sudoers = path;
        yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+       efree(pl);
     } else {
-       /* pop */
-       if (depth == 0)
-           return(FALSE);
-       depth--;
-       if (!keepopen)
-           fclose(YY_CURRENT_BUFFER->yy_input_file);
-       yy_delete_buffer(YY_CURRENT_BUFFER);
-       yy_switch_to_buffer(state[depth].bs);
+       idepth--;
+       yy_switch_to_buffer(istack[idepth].bs);
        efree(sudoers);
-       sudoers = state[depth].path;
-       sudolineno = state[depth].lineno;
-       keepopen = FALSE;
+       sudoers = istack[idepth].path;
+       sudolineno = istack[idepth].lineno;
     }
     return(TRUE);
 }
@@ -3252,22 +3561,45 @@ parse_include(base)
     char *base;
 {
     char *cp, *ep, *path;
-    int len;
+    int len = 0, subst = 0;
+    size_t shost_len = 0;
 
     /* Pull out path from #include line. */
     cp = base + sizeof("#include");
+    if (*cp == 'i')
+       cp += 3; /* includedir */
     while (isblank((unsigned char) *cp))
        cp++;
     ep = cp;
-    while (*ep != '\0' && !isspace((unsigned char) *ep))
+    while (*ep != '\0' && !isspace((unsigned char) *ep)) {
+       if (ep[0] == '%' && ep[1] == 'h') {
+           shost_len = strlen(user_shost);
+           len += shost_len - 2;
+           subst = 1;
+       }
        ep++;
+    }
 
     /* Make a copy of path and return it. */
-    len = (int)(ep - cp);
+    len += (int)(ep - cp);
     if ((path = malloc(len + 1)) == NULL)
        yyerror("unable to allocate memory");
-    memcpy(path, cp, len);
-    path[len] = '\0';
+    if (subst) {
+       /* substitute for %h */
+       char *pp = path;
+       while (cp < ep) {
+           if (cp[0] == '%' && cp[1] == 'h') {
+               memcpy(pp, user_shost, shost_len);
+               pp += shost_len;
+               cp += 2;
+           }
+           *pp++ = *cp++;
+       }
+       *pp = '\0';
+    } else {
+       memcpy(path, cp, len);
+       path[len] = '\0';
+    }
 
     /* Push any excess characters (e.g. comment, newline) back to the lexer */
     if (*ep != '\0')
diff --git a/toke.l b/toke.l
index a38da3a6067b1c624171c7c8a668e645362b3647..9b93563558f3f4e7260a59268e0584b363aa6c00 100644 (file)
--- a/toke.l
+++ b/toke.l
@@ -1,6 +1,6 @@
 %{
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -27,6 +27,7 @@
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #ifdef STDC_HEADERS
 # include <stdlib.h>
 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
 # include <malloc.h>
 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
 #include <ctype.h>
 #include "sudo.h"
 #include "parse.h"
 #include <gram.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: toke.l,v 1.27 2008/11/24 00:41:36 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: toke.l,v 1.37 2009/05/27 00:46:51 millert Exp $";
 #endif /* lint */
 
 extern YYSTYPE yylval;
@@ -69,15 +86,16 @@ static int append           __P((char *, int));
 static int _fill               __P((char *, int, int));
 static int fill_cmnd           __P((char *, int));
 static int fill_args           __P((char *, int, int));
-static int switch_buffer       __P((char *));
+static int _push_include       __P((char *, int));
+static int pop_include         __P((void));
 static int ipv6_valid          __P((const char *s));
 static char *parse_include     __P((char *));
 extern void yyerror            __P((const char *));
 
 #define fill(a, b)             _fill(a, b, 0)
 
-#define        push_include(_p)        (switch_buffer((_p)))
-#define        pop_include()           (switch_buffer(NULL))
+#define        push_include(_p)        (_push_include((_p), FALSE))
+#define        push_includedir(_p)     (_push_include((_p), TRUE))
 
 /* realloc() to size + COMMANDARGINC to make room for command args */
 #define COMMANDARGINC  64
@@ -227,6 +245,19 @@ DEFVAR                     [a-z_]+
                                yyterminate();
                        }
 
+<INITIAL>^#includedir[[:blank:]]+\/.*\n {
+                           char *path;
+
+                           if ((path = parse_include(yytext)) == NULL)
+                               yyterminate();
+
+                           LEXTRACE("INCLUDEDIR\n");
+
+                           /* Push current buffer and switch to include file */
+                           if (!push_includedir(path))
+                               yyterminate();
+                       }
+
 <INITIAL>^[[:blank:]]*Defaults([:@>\!]{WORD})? {
                            int n;
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -316,7 +347,7 @@ NOSETENV[[:blank:]]*:       {
                            return(NETGROUP);
                        }
 
-\%{WORD}               {
+\%:?{WORD}             {
                            /* UN*X group */
                            if (!fill(yytext, yyleng))
                                yyterminate();
@@ -412,11 +443,28 @@ sudoedit          {
                            }
                        }                       /* a pathname */
 
+<INITIAL,GOTDEFS>\"[^"\n]+\" {
+                           /* a quoted user/group name */
+                           if (!fill(yytext + 1, yyleng - 2))
+                               yyterminate();
+                           switch (yytext[1]) {
+                           case '%':
+                               LEXTRACE("USERGROUP ");
+                               return(USERGROUP);
+                           case '+':
+                               LEXTRACE("NETGROUP ");
+                               return(NETGROUP);
+                           default:
+                               LEXTRACE("WORD(4) ");
+                               return(WORD);
+                           }
+                       }
+
 <INITIAL,GOTDEFS>({ID}|{WORD}) {
                            /* a word */
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           LEXTRACE("WORD(4) ");
+                           LEXTRACE("WORD(5) ");
                            return(WORD);
                        }
 
@@ -467,12 +515,12 @@ sudoedit          {
                            LEXTRACE("\n\t");
                        }                       /* throw away EOL after \ */
 
-<INITIAL,STARTDEFS,INDEFS>#([^\n0-9-].*)?\n    {
+<INITIAL,STARTDEFS,INDEFS>#(-[^\n0-9].*|[^\n0-9-].*)?\n        {
                            BEGIN INITIAL;
                            ++sudolineno;
                            LEXTRACE("\n");
                            return(COMMENT);
-                       }                       /* return comments */
+                       }                       /* comment, not uid/gid */
 
 <*>.                   {
                            LEXTRACE("ERROR ");
@@ -490,12 +538,57 @@ sudoedit          {
                        }
 
 %%
+static unsigned char
+hexchar(s)
+    const char *s;
+{
+    int i;
+    int result = 0;
+
+    s += 2; /* skip \\x */
+    for (i = 0; i < 2; i++) {
+       switch (*s) {
+       case 'A':
+       case 'a':
+           result += 10;
+           break;
+       case 'B':
+       case 'b':
+           result += 11;
+           break;
+       case 'C':
+       case 'c':
+           result += 12;
+           break;
+       case 'D':
+       case 'd':
+           result += 13;
+           break;
+       case 'E':
+       case 'e':
+           result += 14;
+           break;
+       case 'F':
+       case 'f':
+           result += 15;
+           break;
+       default:
+           result += *s - '0';
+           break;
+       }
+       if (i == 0) {
+           result *= 16;
+           s++;
+       }
+    }
+    return((unsigned char)result);
+}
+
 static int
 _fill(src, len, olen)
     char *src;
     int len, olen;
 {
-    int i, j;
     char *dst;
 
     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
@@ -507,13 +600,24 @@ _fill(src, len, olen)
 
     /* Copy the string and collapse any escaped characters. */
     dst += olen;
-    for (i = 0, j = 0; i < len; i++, j++) {
-       if (src[i] == '\\' && i != len - 1)
-           dst[j] = src[++i];
-       else
-           dst[j] = src[i];
+    while (len--) {
+       if (*src == '\\' && len) {
+           if (src[1] == 'x' && len >= 3 && 
+               isxdigit((unsigned char) src[2]) &&
+               isxdigit((unsigned char) src[3])) {
+               *dst++ = hexchar(src);
+               src += 4;
+               len -= 3;
+           } else {
+               src++;
+               len--;
+               *dst++ = *src++;
+           }
+       } else {
+           *dst++ = *src++;
+       }
     }
-    dst[j] = '\0';
+    *dst = '\0';
     return(TRUE);
 }
 
@@ -605,63 +709,228 @@ fill_args(s, len, addspace)
     return(TRUE);
 }
 
-struct sudoers_state {
+struct path_list {
+    char *path;
+    struct path_list *next;
+};
+
+struct include_stack {
     YY_BUFFER_STATE bs;
     char *path;
+    struct path_list *more; /* more files in case of includedir */
     int lineno;
+    int keepopen;
 };
 
+static int
+pl_compare(v1, v2)
+    const void *v1;
+    const void *v2;
+{
+    const struct path_list * const *p1 = v1;
+    const struct path_list * const *p2 = v2;
+
+    return(strcmp((*p1)->path, (*p2)->path));
+}
+
+static char *
+switch_dir(stack, dirpath)
+    struct include_stack *stack;
+    char *dirpath;
+{
+    DIR *dir;
+    int i, count = 0;
+    char *path = NULL;
+    struct dirent *dent;
+    struct stat sb;
+    struct path_list *pl, *first = NULL;
+    struct path_list **sorted = NULL;
+
+    if (!(dir = opendir(dirpath))) {
+       yyerror(dirpath);
+       return(FALSE);
+    }
+    while ((dent = readdir(dir))) {
+       /* Ignore files that end in '~' or have a '.' in them. */
+       if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
+           || strchr(dent->d_name, '.') != NULL) {
+           continue;
+       }
+       if (asprintf(&path, "%s/%s", dirpath, dent->d_name) == -1) {
+           closedir(dir);
+           goto bad;
+       }
+       if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
+           efree(path);
+           continue;
+       }
+       pl = malloc(sizeof(*pl));
+       if (pl == NULL)
+           goto bad;
+       pl->path = path;
+       pl->next = first;
+       first = pl;
+       count++;
+    }
+    closedir(dir);
+
+    if (count == 0)
+       goto done;
+
+    /* Sort the list as an array. */
+    sorted = malloc(sizeof(*sorted) * count);
+    if (sorted == NULL)
+       goto bad;
+    pl = first;
+    for (i = 0; i < count; i++) {
+       sorted[i] = pl;
+       pl = pl->next;
+    }
+    qsort(sorted, count, sizeof(*sorted), pl_compare);
+
+    /* Apply sorting to the list. */
+    first = sorted[0];
+    sorted[count - 1]->next = NULL;
+    for (i = 1; i < count; i++)
+       sorted[i - 1]->next = sorted[i];
+    efree(sorted);
+
+    /* Pull out the first element for parsing, leave the rest for later. */
+    if (count) {
+       path = first->path;
+       pl = first->next;
+       efree(first);
+       stack->more = pl;
+    } else {
+       path = NULL;
+    }
+done:
+    efree(dirpath);
+    return(path);
+bad:
+    while (first != NULL) {
+       pl = first;
+       first = pl->next;
+       free(pl->path);
+       free(pl);
+    }
+    efree(sorted);
+    efree(dirpath);
+    efree(path);
+    return(NULL);
+}
+
 #define MAX_SUDOERS_DEPTH      128
 #define SUDOERS_STACK_INCREMENT        16
 
+static size_t istacksize, idepth;
+static struct include_stack *istack;
+static int keepopen;
+
+void
+init_lexer()
+{
+    struct path_list *pl;
+
+    while (idepth) {
+       idepth--;
+       while ((pl = istack[idepth].more) != NULL) {
+           istack[idepth].more = pl->next;
+           efree(pl->path);
+           efree(pl);
+       }
+       efree(istack[idepth].path);
+       if (!istack[idepth].keepopen)
+           fclose(istack[idepth].bs->yy_input_file);
+       yy_delete_buffer(istack[idepth].bs);
+    }
+    efree(istack);
+    istack = NULL;
+    istacksize = idepth = 0;
+    keepopen = FALSE;
+}
+
 static int
-switch_buffer(path)
+_push_include(path, isdir)
     char *path;
+    int isdir;
 {
-    static size_t stacksize, depth;
-    static struct sudoers_state *state;
-    static int keepopen;
     FILE *fp;
 
-    if (path != NULL) {
-       /* push current state */
-       if (depth >= stacksize) {
-           if (depth > MAX_SUDOERS_DEPTH) {
-               yyerror("too many levels of includes");
-               return(FALSE);
-           }
-           stacksize += SUDOERS_STACK_INCREMENT;
-           state = (struct sudoers_state *) realloc(state,
-               sizeof(state) * stacksize);
-           if (state == NULL) {
-               yyerror("unable to allocate memory");
-               return(FALSE);
-           }
+    /* push current state onto stack */
+    if (idepth >= istacksize) {
+       if (idepth > MAX_SUDOERS_DEPTH) {
+           yyerror("too many levels of includes");
+           return(FALSE);
+       }
+       istacksize += SUDOERS_STACK_INCREMENT;
+       istack = (struct include_stack *) realloc(istack,
+           sizeof(istack) * istacksize);
+       if (istack == NULL) {
+           yyerror("unable to allocate memory");
+           return(FALSE);
        }
-       if ((fp = open_sudoers(path, &keepopen)) == NULL) {
+    }
+    if (isdir) {
+       if (!(path = switch_dir(&istack[idepth], path))) {
            yyerror(path);
            return(FALSE);
        }
-       state[depth].bs = YY_CURRENT_BUFFER;
-       state[depth].path = sudoers;
-       state[depth].lineno = sudolineno;
-       depth++;
+       if ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {
+           yyerror(path);
+           return(FALSE); /* XXX - just to go next one? */
+       }
+    } else {
+       if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {
+           yyerror(path);
+           return(FALSE);
+       }
+       istack[idepth].more = NULL;
+    }
+    /* Push the old (current) file and open the new one. */
+    istack[idepth].path = sudoers; /* push old path */
+    istack[idepth].bs = YY_CURRENT_BUFFER;
+    istack[idepth].lineno = sudolineno;
+    istack[idepth].keepopen = keepopen;
+    idepth++;
+    sudolineno = 1;
+    sudoers = path;
+    yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+
+    return(TRUE);
+}
+
+static int
+pop_include()
+{
+    struct path_list *pl;
+    FILE *fp;
+
+    if (idepth == 0)
+       return(FALSE);
+
+    if (!keepopen)
+       fclose(YY_CURRENT_BUFFER->yy_input_file);
+    yy_delete_buffer(YY_CURRENT_BUFFER);
+    keepopen = FALSE;
+    if ((pl = istack[idepth - 1].more) != NULL) {
+       /* Move to next file in the dir. */
+       istack[idepth - 1].more = pl->next;
+       if ((fp = open_sudoers(pl->path, FALSE, &keepopen)) == NULL) {
+           yyerror(pl->path);
+           return(FALSE); /* XXX - just to go next one? */
+       }
+       efree(sudoers);
+       sudoers = pl->path;
        sudolineno = 1;
-       sudoers = path;
        yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+       efree(pl);
     } else {
-       /* pop */
-       if (depth == 0)
-           return(FALSE);
-       depth--;
-       if (!keepopen)
-           fclose(YY_CURRENT_BUFFER->yy_input_file);
-       yy_delete_buffer(YY_CURRENT_BUFFER);
-       yy_switch_to_buffer(state[depth].bs);
+       idepth--;
+       yy_switch_to_buffer(istack[idepth].bs);
        efree(sudoers);
-       sudoers = state[depth].path;
-       sudolineno = state[depth].lineno;
-       keepopen = FALSE;
+       sudoers = istack[idepth].path;
+       sudolineno = istack[idepth].lineno;
     }
     return(TRUE);
 }
@@ -671,22 +940,45 @@ parse_include(base)
     char *base;
 {
     char *cp, *ep, *path;
-    int len;
+    int len = 0, subst = 0;
+    size_t shost_len = 0;
 
     /* Pull out path from #include line. */
     cp = base + sizeof("#include");
+    if (*cp == 'i')
+       cp += 3; /* includedir */
     while (isblank((unsigned char) *cp))
        cp++;
     ep = cp;
-    while (*ep != '\0' && !isspace((unsigned char) *ep))
+    while (*ep != '\0' && !isspace((unsigned char) *ep)) {
+       if (ep[0] == '%' && ep[1] == 'h') {
+           shost_len = strlen(user_shost);
+           len += shost_len - 2;
+           subst = 1;
+       }
        ep++;
+    }
 
     /* Make a copy of path and return it. */
-    len = (int)(ep - cp);
+    len += (int)(ep - cp);
     if ((path = malloc(len + 1)) == NULL)
        yyerror("unable to allocate memory");
-    memcpy(path, cp, len);
-    path[len] = '\0';
+    if (subst) {
+       /* substitute for %h */
+       char *pp = path;
+       while (cp < ep) {
+           if (cp[0] == '%' && cp[1] == 'h') {
+               memcpy(pp, user_shost, shost_len);
+               pp += shost_len;
+               cp += 2;
+           }
+           *pp++ = *cp++;
+       }
+       *pp = '\0';
+    } else {
+       memcpy(path, cp, len);
+       path[len] = '\0';
+    }
 
     /* Push any excess characters (e.g. comment, newline) back to the lexer */
     if (*ep != '\0')
diff --git a/vasgroups.c b/vasgroups.c
new file mode 100644 (file)
index 0000000..33a333d
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * (c) 2006 Quest Software, Inc.  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 Quest Software, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include <vas.h>
+
+#include "compat.h"
+#include "logging.h"
+#include "nonunix.h"
+#include "parse.h"
+#include "sudo.h"
+
+
+/* Pseudo-boolean types */
+#undef TRUE
+#undef FALSE
+#define FALSE 0
+#define TRUE  1
+
+
+static vas_ctx_t *sudo_vas_ctx;
+static vas_id_t  *sudo_vas_id;
+/* Don't use VAS_NAME_FLAG_NO_CACHE or lookups just won't work.
+ * -tedp, 2006-08-29 */
+static const int update_flags = 0;
+static int sudo_vas_available = 0;
+static char *err_msg = NULL;
+static void *libvas_handle = NULL;
+
+/* libvas functions */
+static vas_err_t       (*v_ctx_alloc) (vas_ctx_t **ctx);
+static void            (*v_ctx_free) (vas_ctx_t *ctx);
+static vas_err_t       (*v_id_alloc) (vas_ctx_t *ctx, const char *name, vas_id_t **id);
+static void            (*v_id_free) (vas_ctx_t *ctx, vas_id_t *id);
+static vas_err_t       (*v_id_establish_cred_keytab) (vas_ctx_t *ctx, vas_id_t *id, int credflags, const char *keytab);
+static vas_err_t       (*v_user_init) (vas_ctx_t *ctx, vas_id_t *id, const char *name, int flags, vas_user_t **user);
+static void            (*v_user_free) (vas_ctx_t *ctx, vas_user_t *user);
+static vas_err_t       (*v_group_init) (vas_ctx_t *ctx, vas_id_t *id, const char *name, int flags, vas_group_t **group);
+static void            (*v_group_free) (vas_ctx_t *ctx, vas_group_t *group);
+static vas_err_t       (*v_user_is_member) (vas_ctx_t *ctx, vas_id_t *id, vas_user_t *user, vas_group_t *group);
+static const char*     (*v_err_get_string) (vas_ctx_t *ctx, int with_cause);
+
+
+static int     resolve_vas_funcs(void);
+
+
+/**
+ * Whether nonunix group lookups are available.
+ * @return 1 if available, 0 if not.
+ */
+int
+sudo_nonunix_groupcheck_available(void)
+{
+    return sudo_vas_available;
+}
+
+
+/**
+ * Check if the user is in the group
+ * @param group group name which can be in DOMAIN\sam format or just the group
+ *              name
+ * @param user user name
+ * @param pwd (unused)
+ * @return 1 if user is a member of the group, 0 if not (or error occurred)
+ */
+int
+sudo_nonunix_groupcheck( const char* group, const char* user, const struct passwd* pwd )
+{
+    static int          error_cause_shown = FALSE;
+    int                 rval = FALSE;
+    vas_err_t           vaserr;
+    vas_user_t*         vas_user = NULL;
+    vas_group_t*        vas_group = NULL;
+
+    if (!sudo_vas_available) {
+       if (error_cause_shown == FALSE) {
+           /* Produce the saved error reason */
+           log_error(NO_MAIL|NO_EXIT, "Non-unix group checking unavailable: %s",
+                   err_msg ? err_msg
+                   : "(unknown cause)");
+           error_cause_shown = TRUE;
+       }
+       return 0;
+    }
+
+    /* resolve the user and group. The user will be a real Unix account name,
+     * while the group may be a unix name, or any group name accepted by
+     * vas_name_to_dn, which means any of:
+     * - Group Name
+     * - Group Name@FULLY.QUALIFIED.DOMAIN
+     * - CN=sudoers,CN=Users,DC=rcdev,DC=vintela,DC=com
+     * - S-1-2-34-5678901234-5678901234-5678901234-567
+     *
+     * XXX - we may get non-VAS user accounts here. You can add local users to an
+     * Active Directory group through override files. Should we handle that case?
+     * */
+    if( (vaserr = v_user_init( sudo_vas_ctx, sudo_vas_id, user, update_flags, &vas_user )) != VAS_ERR_SUCCESS ) {
+       if (vaserr == VAS_ERR_NOT_FOUND) {
+            /* No such user in AD. Probably a local user. */
+           vaserr = VAS_ERR_SUCCESS;
+       }
+        goto FINISHED;
+    }
+        
+    if( (vaserr = v_group_init( sudo_vas_ctx, sudo_vas_id, group, update_flags, &vas_group )) != VAS_ERR_SUCCESS ) {
+        goto FINISHED;
+    }
+
+    /* do the membership check */
+    if( (vaserr = v_user_is_member( sudo_vas_ctx, sudo_vas_id, vas_user, vas_group )) == VAS_ERR_SUCCESS ) {
+        rval = TRUE;
+    }
+    else if (vaserr == VAS_ERR_NOT_FOUND) {
+       /* fake the vaserr code so no error is triggered */
+       vaserr = VAS_ERR_SUCCESS;
+    }
+
+
+FINISHED: /* cleanups */
+    if (vaserr != VAS_ERR_SUCCESS) {
+       int error_flags = NO_MAIL | MSG_ONLY | (uses_inversion ? 0 : NO_EXIT);
+
+       log_error(error_flags, "Error while checking group membership "
+               "for user \"%s\", group \"%s\", error: %s%s.", user, group,
+               v_err_get_string(sudo_vas_ctx, 1),
+               /* A helpful hint if there seems to be a non-FQDN as the domain */
+               (strchr(group, '@') && !strchr(group, '.'))
+                ? "\nMake sure the fully qualified domain name is specified"
+                : "");
+    }
+    if( vas_group )              v_group_free( sudo_vas_ctx, vas_group );
+    if( vas_user )              v_user_free( sudo_vas_ctx, vas_user );
+
+    return(rval);
+}
+
+
+static void
+set_err_msg(const char *msg, ...) {
+    va_list ap;
+
+    if (!msg) /* assert */
+       return;
+
+    if (err_msg)
+       free(err_msg);
+
+    va_start(ap, msg);
+
+    if (vasprintf(&err_msg, msg, ap) == -1)
+       err_msg = NULL;
+       
+    va_end(ap);
+}
+
+
+/**
+ * Initialise nonunix_groupcheck state.
+ */
+void
+sudo_nonunix_groupcheck_init(void)
+{
+    vas_err_t vaserr;
+    void *libvas;
+
+    if (err_msg) {
+       free(err_msg);
+       err_msg = NULL;
+    }
+
+    libvas = dlopen(LIBVAS_SO, RTLD_LAZY);
+    if (!libvas) {
+       set_err_msg("dlopen() failed: %s", dlerror());
+       return;
+    }
+
+    libvas_handle = libvas;
+
+    if (resolve_vas_funcs() != 0)
+       return;
+
+    if (VAS_ERR_SUCCESS == (vaserr = v_ctx_alloc(&sudo_vas_ctx))) {
+
+       if (VAS_ERR_SUCCESS == (vaserr = v_id_alloc(sudo_vas_ctx, "host/", &sudo_vas_id))) {
+       
+           if (update_flags & VAS_NAME_FLAG_NO_LDAP) {
+               sudo_vas_available = 1;
+               return; /* OK */
+           } else { /* Get a keytab */
+               if ((vaserr = v_id_establish_cred_keytab( sudo_vas_ctx,
+                                                   sudo_vas_id,
+                                                     VAS_ID_FLAG_USE_MEMORY_CCACHE
+                                                   | VAS_ID_FLAG_KEEP_COPY_OF_CRED
+                                                   | VAS_ID_FLAG_NO_INITIAL_TGT,
+                                                   NULL )) == VAS_ERR_SUCCESS) {
+                   sudo_vas_available = 1;
+                   return; /* OK */
+               }
+
+               if (!err_msg)
+                   set_err_msg("unable to establish creds: %s",
+                           v_err_get_string(sudo_vas_ctx, 1));
+           }
+
+           v_id_free(sudo_vas_ctx, sudo_vas_id);
+           sudo_vas_id = NULL;
+       }
+
+       /* This is the last opportunity to get an error message from libvas */
+       if (!err_msg)
+           set_err_msg("Error initializing non-unix group checking: %s",
+                   v_err_get_string(sudo_vas_ctx, 1));
+
+       v_ctx_free(sudo_vas_ctx);
+       sudo_vas_ctx = NULL;
+    }
+
+    if (!err_msg)
+       set_err_msg("Failed to get a libvas handle for non-unix group checking (unknown cause)");
+
+    sudo_vas_available = 0;
+}
+
+
+/**
+ * Clean up nonunix_groupcheck state.
+ */
+void
+sudo_nonunix_groupcheck_cleanup()
+{
+    if (err_msg) {
+       free(err_msg);
+       err_msg = NULL;
+    }
+
+    if (sudo_vas_available) {
+       v_id_free(sudo_vas_ctx, sudo_vas_id);
+       sudo_vas_id = NULL;
+
+       v_ctx_free(sudo_vas_ctx);
+       sudo_vas_ctx = NULL;
+
+       sudo_vas_available = FALSE;
+    }
+
+    if (libvas_handle) {
+       if (dlclose(libvas_handle) != 0)
+           log_error(NO_MAIL|NO_EXIT, "dlclose() failed: %s", dlerror());
+       libvas_handle = NULL;
+    }
+}
+
+#define RESOLVE_OR_ERR(fptr, sym) \
+    do { \
+       void *_fptr = dlsym(libvas_handle, (sym)); \
+       if (!_fptr) { \
+           set_err_msg("dlsym() failed: %s", dlerror()); \
+           return -1; \
+       } \
+       fptr = _fptr; \
+    } while (0)
+
+
+/**
+ * Resolve all the libvas functions.
+ * Returns -1 and sets err_msg if something went wrong, or 0 on success.
+ */
+int
+resolve_vas_funcs(void)
+{
+    if (!libvas_handle) /* assert */
+       return -1;
+
+    RESOLVE_OR_ERR(v_ctx_alloc,        "vas_ctx_alloc");
+    RESOLVE_OR_ERR(v_ctx_free, "vas_ctx_free");
+    RESOLVE_OR_ERR(v_id_alloc, "vas_id_alloc");
+    RESOLVE_OR_ERR(v_id_free,  "vas_id_free");
+    RESOLVE_OR_ERR(v_id_establish_cred_keytab, "vas_id_establish_cred_keytab");
+    RESOLVE_OR_ERR(v_user_init,        "vas_user_init");
+    RESOLVE_OR_ERR(v_user_free,        "vas_user_free");
+    RESOLVE_OR_ERR(v_group_init,       "vas_group_init");
+    RESOLVE_OR_ERR(v_group_free,       "vas_group_free");
+    RESOLVE_OR_ERR(v_user_is_member,   "vas_user_is_member");
+    RESOLVE_OR_ERR(v_err_get_string,   "vas_err_get_string");
+
+    return 0;
+}
diff --git a/version.h b/version.h
deleted file mode 100644 (file)
index fa354e0..0000000
--- a/version.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 1996, 1998-2005, 2008
- *     Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- *
- * $Sudo: version.h,v 1.71 2008/11/09 14:13:12 millert Exp $
- */
-
-#ifndef _SUDO_VERSION_H
-#define _SUDO_VERSION_H
-
-static const char version[] = "1.7.0";
-
-#endif /* _SUDO_VERSION_H */
index 81b57185395c428ef107f351504466969ff1ac2f..b48fc24745f9beabb6d90150be393d6917c3d189 100644 (file)
--- a/visudo.c
+++ b/visudo.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2008
+ * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 #include "sudo.h"
 #include "interfaces.h"
 #include "parse.h"
+#include "redblack.h"
 #include <gram.h>
-#include "version.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: visudo.c,v 1.223 2008/11/22 15:12:26 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: visudo.c,v 1.234 2009/05/25 12:02:42 millert Exp $";
 #endif /* lint */
 
 struct sudoersfile {
     char *path;
-    int fd;
     char *tpath;
+    int fd;
     int tfd;
     int modified;
+    int doedit;
     struct sudoersfile *next;
 };
 
@@ -105,14 +106,16 @@ struct sudoersfile {
 static RETSIGTYPE quit         __P((int));
 static char *get_args          __P((char *));
 static char *get_editor                __P((char **));
+static void get_hostname       __P((void));
 static char whatnow            __P((void));
-static int check_aliases       __P((int));
+static int check_aliases       __P((int, int));
 static int check_syntax                __P((char *, int, int));
 static int edit_sudoers                __P((struct sudoersfile *, char *, char *, int));
 static int install_sudoers     __P((struct sudoersfile *, int));
 static int print_unused                __P((void *, void *));
 static int reparse_sudoers     __P((char *, char *, int, int));
 static int run_command         __P((char *, char **));
+static void print_undefined    __P((char *name, int, int, int));
 static void setup_signals      __P((void));
 static void usage              __P((void)) __attribute__((__noreturn__));
 
@@ -122,6 +125,7 @@ extern void yyrestart               __P((FILE *));
 /*
  * External globals exported by the parser
  */
+extern struct rbtree *aliases;
 extern FILE *yyin;
 extern char *sudoers, *errorfile;
 extern int errorlineno, parse_error;
@@ -141,6 +145,7 @@ struct passwd *list_pw;
 static struct sudoerslist {
     struct sudoersfile *first, *last;
 } sudoerslist;
+static struct rbtree *alias_freelist;
 
 int
 main(argc, argv)
@@ -167,7 +172,7 @@ main(argc, argv)
     while ((ch = getopt(argc, argv, "Vcf:sq")) != -1) {
        switch (ch) {
            case 'V':
-               (void) printf("%s version %s\n", getprogname(), version);
+               (void) printf("%s version %s\n", getprogname(), PACKAGE_VERSION);
                exit(0);
            case 'c':
                checkonly++;            /* check mode */
@@ -195,9 +200,10 @@ main(argc, argv)
     sudo_setgrent();
 
     /* Mock up a fake sudo_user struct. */
-    user_host = user_shost = user_cmnd = "";
+    user_cmnd = "";
     if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL)
        errorx(1, "you don't exist in the passwd database");
+    get_hostname();
 
     /* Setup defaults data structures. */
     init_defaults();
@@ -209,8 +215,9 @@ main(argc, argv)
      * Parse the existing sudoers file(s) in quiet mode to highlight any
      * existing errors and to pull in editor and env_editor conf values.
      */
-    if ((yyin = open_sudoers(sudoers_path, NULL)) == NULL)
+    if ((yyin = open_sudoers(sudoers_path, TRUE, NULL)) == NULL) {
        error(1, "%s", sudoers_path);
+    }
     init_parser(sudoers_path, 0);
     yyparse();
     (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER);
@@ -222,6 +229,8 @@ main(argc, argv)
 
     /* Edit the sudoers file(s) */
     tq_foreach_fwd(&sudoerslist, sp) {
+       if (!sp->doedit)
+           continue;
        if (sp != tq_first(&sudoerslist)) {
            printf("press return to edit %s: ", sp->path);
            while ((ch = getchar()) != EOF && ch != '\n')
@@ -428,7 +437,7 @@ reparse_sudoers(editor, args, strict, quiet)
            parse_error = TRUE;
        }
        fclose(yyin);
-       if (check_aliases(strict) != 0)
+       if (check_aliases(strict, quiet) != 0)
            parse_error = TRUE;
 
        /*
@@ -698,10 +707,14 @@ check_syntax(sudoers_path, quiet, strict)
            warningx("failed to parse %s file, unknown error", sudoers_path);
        parse_error = TRUE;
     }
+    if (!parse_error) {
+       if (check_aliases(strict, quiet) != 0)
+           parse_error = TRUE;
+    }
     error = parse_error;
     if (!quiet) {
        if (parse_error)
-           (void) printf("parse error in %s near line %d\n", sudoers_path,
+           (void) printf("parse error in %s near line %d\n", errorfile,
                errorlineno);
        else
            (void) printf("%s: parsed OK\n", sudoers_path);
@@ -737,8 +750,9 @@ check_syntax(sudoers_path, quiet, strict)
  * any subsequent files #included via a callback from the parser.
  */
 FILE *
-open_sudoers(path, keepopen)
+open_sudoers(path, doedit, keepopen)
     const char *path;
+    int doedit;
     int *keepopen;
 {
     struct sudoersfile *entry;
@@ -756,6 +770,8 @@ open_sudoers(path, keepopen)
        entry->next = NULL;
        entry->fd = open(entry->path, O_RDWR | O_CREAT, SUDOERS_MODE);
        entry->tpath = NULL;
+       entry->tfd = -1;
+       entry->doedit = doedit;
        if (entry->fd == -1) {
            warning("%s", entry->path);
            efree(entry);
@@ -772,8 +788,6 @@ open_sudoers(path, keepopen)
            sudoerslist.last->next = entry;
            sudoerslist.last = entry;
        }
-       if (keepopen != NULL)
-           *keepopen = TRUE;
     } else {
        /* Already exists, open .tmp version if there is one. */
        if (entry->tpath != NULL) {
@@ -782,8 +796,11 @@ open_sudoers(path, keepopen)
        } else {
            if ((fp = fdopen(entry->fd, "r")) == NULL)
                error(1, "%s", entry->path);
+           rewind(fp);
        }
     }
+    if (keepopen != NULL)
+       *keepopen = TRUE;
     return(fp);
 }
 
@@ -908,13 +925,59 @@ get_args(cmnd)
     return(*args ? args : NULL);
 }
 
+/*
+ * Look up the hostname and set user_host and user_shost.
+ */
+static void
+get_hostname()
+{
+    char *p, thost[MAXHOSTNAMELEN + 1];
+
+    if (gethostname(thost, sizeof(thost)) != 0) {
+       user_host = user_shost = "localhost";
+       return;
+    }
+    thost[sizeof(thost) - 1] = '\0';
+    user_host = estrdup(thost);
+
+    if ((p = strchr(user_host, '.'))) {
+       *p = '\0';
+       user_shost = estrdup(user_host);
+       *p = '.';
+    } else {
+       user_shost = user_host;
+    }
+}
+
+static void
+alias_remove_recursive(name, type)
+    char *name;
+    int type;
+{
+    struct member *m;
+    struct alias *a;
+
+    if ((a = alias_find(name, type)) != NULL) {
+       tq_foreach_fwd(&a->members, m) {
+           if (m->type == ALIAS) {
+               alias_remove_recursive(m->name, type);
+           }
+       }
+    }
+    alias_seqno++;
+    a = alias_remove(name, type);
+    if (a)
+       rbinsert(alias_freelist, a);
+}
+
 /*
  * Iterate through the sudoers datastructures looking for undefined
  * aliases or unused aliases.
  */
 static int
-check_aliases(strict)
+check_aliases(strict, quiet)
     int strict;
+    int quiet;
 {
     struct cmndspec *cs;
     struct member *m, *binding;
@@ -923,14 +986,15 @@ check_aliases(strict)
     struct defaults *d;
     int atype, error = 0;
 
+    alias_freelist = rbcreate(alias_compare);
+
     /* Forward check. */
     tq_foreach_fwd(&userspecs, us) {
        tq_foreach_fwd(&us->users, m) {
            if (m->type == ALIAS) {
                alias_seqno++;
-               if (find_alias(m->name, USERALIAS) == NULL) {
-                   warningx("%s: User_Alias `%s' referenced but not defined",
-                       strict ? "Error" : "Warning", m->name);
+               if (alias_find(m->name, USERALIAS) == NULL) {
+                   print_undefined(m->name, USERALIAS, strict, quiet);
                    error++;
                }
            }
@@ -939,9 +1003,8 @@ check_aliases(strict)
            tq_foreach_fwd(&priv->hostlist, m) {
                if (m->type == ALIAS) {
                    alias_seqno++;
-                   if (find_alias(m->name, HOSTALIAS) == NULL) {
-                       warningx("%s: Host_Alias `%s' referenced but not defined",
-                           strict ? "Error" : "Warning", m->name);
+                   if (alias_find(m->name, HOSTALIAS) == NULL) {
+                       print_undefined(m->name, HOSTALIAS, strict, quiet);
                        error++;
                    }
                }
@@ -950,18 +1013,16 @@ check_aliases(strict)
                tq_foreach_fwd(&cs->runasuserlist, m) {
                    if (m->type == ALIAS) {
                        alias_seqno++;
-                       if (find_alias(m->name, RUNASALIAS) == NULL) {
-                           warningx("%s: Runas_Alias `%s' referenced but not defined",
-                               strict ? "Error" : "Warning", m->name);
+                       if (alias_find(m->name, RUNASALIAS) == NULL) {
+                           print_undefined(m->name, RUNASALIAS, strict, quiet);
                            error++;
                        }
                    }
                }
                if ((m = cs->cmnd)->type == ALIAS) {
                    alias_seqno++;
-                   if (find_alias(m->name, CMNDALIAS) == NULL) {
-                       warningx("%s: Cmnd_Alias `%s' referenced but not defined",
-                           strict ? "Error" : "Warning", m->name);
+                   if (alias_find(m->name, CMNDALIAS) == NULL) {
+                       print_undefined(m->name, CMNDALIAS, strict, quiet);
                        error++;
                    }
                }
@@ -972,21 +1033,22 @@ check_aliases(strict)
     /* Reverse check (destructive) */
     tq_foreach_fwd(&userspecs, us) {
        tq_foreach_fwd(&us->users, m) {
-           if (m->type == ALIAS)
-               (void) alias_remove(m->name, USERALIAS);
+           if (m->type == ALIAS) {
+               (void) alias_remove_recursive(m->name, USERALIAS);
+           }
        }
        tq_foreach_fwd(&us->privileges, priv) {
            tq_foreach_fwd(&priv->hostlist, m) {
                if (m->type == ALIAS)
-                   (void) alias_remove(m->name, HOSTALIAS);
+                   (void) alias_remove_recursive(m->name, HOSTALIAS);
            }
            tq_foreach_fwd(&priv->cmndlist, cs) {
                tq_foreach_fwd(&cs->runasuserlist, m) {
                    if (m->type == ALIAS)
-                       (void) alias_remove(m->name, RUNASALIAS);
+                       (void) alias_remove_recursive(m->name, RUNASALIAS);
                }
                if ((m = cs->cmnd)->type == ALIAS)
-                   (void) alias_remove(m->name, CMNDALIAS);
+                   (void) alias_remove_recursive(m->name, CMNDALIAS);
            }
        }
     }
@@ -1010,18 +1072,37 @@ check_aliases(strict)
        tq_foreach_fwd(&d->binding, binding) {
            for (m = binding; m != NULL; m = m->next) {
                if (m->type == ALIAS)
-                   (void) alias_remove(m->name, atype);
+                   (void) alias_remove_recursive(m->name, atype);
            }
        }
     }
+    rbdestroy(alias_freelist, alias_free);
 
     /* If all aliases were referenced we will have an empty tree. */
     if (no_aliases())
        return(0);
-    alias_apply(print_unused, strict ? "Error" : "Warning");
+    if (!quiet) {
+       alias_apply(print_unused, strict ? "Error" : "Warning");
+    }
     return (strict ? 1 : 0);
 }
 
+static void
+print_undefined(name, type, strict, quiet)
+    char *name;
+    int type;
+    int strict;
+    int quiet;
+{
+    if (!quiet) {
+       warningx("%s: %s_Alias `%s' referenced but not defined",
+           strict ? "Error" : "Warning",
+           type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" :
+           type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" :
+           "Unknown", name);
+    }
+}
+
 static int
 print_unused(v1, v2)
     void *v1;
index 74be714137619a02b331fa7eddbfc8b1df8d813f..51c822e7ae88af5f9cceccb971043920cedadedc 100644 (file)
@@ -53,15 +53,15 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
        -f _\bs_\bu_\bd_\bo_\be_\br_\bs  Specify and alternate _\bs_\bu_\bd_\bo_\be_\br_\bs file location.  With this
                    option v\bvi\bis\bsu\bud\bdo\bo will edit (or check) the _\bs_\bu_\bd_\bo_\be_\br_\bs file of your
-                   choice, instead of the default, _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  The
-                   lock file used is the specified _\bs_\bu_\bd_\bo_\be_\br_\bs file with ".tmp"
+                   choice, instead of the default, _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  The lock
+                   file used is the specified _\bs_\bu_\bd_\bo_\be_\br_\bs file with ".tmp"
                    appended to it.
 
        -q          Enable q\bqu\bui\bie\bet\bt mode.  In this mode details about syntax
 
 
 
-1.7.0                   November 15, 2008                       1
+1.7.2                     June 11, 2009                         1
 
 
 
@@ -92,10 +92,9 @@ E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
        EDITOR          Used by visudo if VISUAL is not set
 
 F\bFI\bIL\bLE\bES\bS
-       _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs    List of who can run what
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs            List of who can run what
 
-       _\b@_\bs_\by_\bs_\bc_\bo_\bn_\bf_\bd_\bi_\br_\b@_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bt_\bm_\bp
-                               Lock file for visudo
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bt_\bm_\bp        Lock file for visudo
 
 D\bDI\bIA\bAG\bGN\bNO\bOS\bST\bTI\bIC\bCS\bS
        sudoers file busy, try again later.
@@ -123,11 +122,12 @@ D\bDI\bIA\bAG\bGN\bNO\bOS\bST\bTI\bIC\bCS\bS
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        _\bv_\bi(1), _\bs_\bu_\bd_\bo_\be_\br_\bs(4), _\bs_\bu_\bd_\bo(1m), _\bv_\bi_\bp_\bw(8)
 
+A\bAU\bUT\bTH\bHO\bOR\bR
+       Many people have worked on _\bs_\bu_\bd_\bo over the years; this version of v\bvi\bis\bsu\bud\bdo\bo
 
 
 
-
-1.7.0                   November 15, 2008                       2
+1.7.2                     June 11, 2009                         2
 
 
 
@@ -136,8 +136,6 @@ S\bSE\bEE\bE A\bAL\bLS\bSO\bO
 VISUDO(1m)             MAINTENANCE COMMANDS            VISUDO(1m)
 
 
-A\bAU\bUT\bTH\bHO\bOR\bR
-       Many people have worked on _\bs_\bu_\bd_\bo over the years; this version of v\bvi\bis\bsu\bud\bdo\bo
        was written by:
 
         Todd Miller
@@ -193,6 +191,8 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.7.0                   November 15, 2008                       3
+
+
+1.7.2                     June 11, 2009                         3
 
 
index 7aa576b4ceaae7bdf2ac6dfe8e3f91302dbf2439..dc33f549ec1ad95d92e3c683c8cfdb812191bfc1 100644 (file)
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: visudo.man.in,v 1.32 2008/11/15 18:34:26 millert Exp $
+.\" $Sudo: visudo.man.in,v 1.34 2009/06/11 20:29:12 millert Exp $
 .\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "VISUDO @mansectsu@"
-.TH VISUDO @mansectsu@ "November 15, 2008" "1.7.0" "MAINTENANCE COMMANDS"
+.TH VISUDO @mansectsu@ "June 11, 2009" "1.7.2" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -211,7 +211,7 @@ exit with a value of 0.  If a syntax error is encountered,
 .IX Item "-f sudoers"
 Specify and alternate \fIsudoers\fR file location.  With this option
 \&\fBvisudo\fR will edit (or check) the \fIsudoers\fR file of your choice,
-instead of the default, \fI\f(CI@sysconfdir\fI@/sudoers\fR.  The lock file used
+instead of the default, \fI@sysconfdir@/sudoers\fR.  The lock file used
 is the specified \fIsudoers\fR file with \*(L".tmp\*(R" appended to it.
 .IP "\-q" 12
 .IX Item "-q"
@@ -243,12 +243,12 @@ Invoked by visudo as the editor to use
 Used by visudo if \s-1VISUAL\s0 is not set
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI\fI@sysconfdir\fI@/sudoers\fR" 24
-.el .IP "\fI\f(CI@sysconfdir\fI@/sudoers\fR" 24
+.ie n .IP "\fI@sysconfdir@/sudoers\fR" 24
+.el .IP "\fI@sysconfdir@/sudoers\fR" 24
 .IX Item "@sysconfdir@/sudoers"
 List of who can run what
-.ie n .IP "\fI\fI@sysconfdir\fI@/sudoers.tmp\fR" 24
-.el .IP "\fI\f(CI@sysconfdir\fI@/sudoers.tmp\fR" 24
+.ie n .IP "\fI@sysconfdir@/sudoers.tmp\fR" 24
+.el .IP "\fI@sysconfdir@/sudoers.tmp\fR" 24
 .IX Item "@sysconfdir@/sudoers.tmp"
 Lock file for visudo
 .SH "DIAGNOSTICS"